Chinaunix首页 | 论坛 | 博客
  • 博客访问: 522550
  • 博文数量: 252
  • 博客积分: 6057
  • 博客等级: 准将
  • 技术积分: 1635
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-21 10:17
文章分类

全部博文(252)

文章存档

2013年(1)

2012年(1)

2011年(32)

2010年(212)

2009年(6)

分类:

2010-09-07 20:08:06

操作系统开发系列——历史与基本理论

Translated By

本系列旨在展示和教授如何从最底层开始开发一个操作系统。

简介

欢迎来到奇妙而又令人疯狂的操作系统世界!

在前一章里,我们已经定义了什么是操作系统。一个操作系统提供了用户与计算机系统之间的基本接口,它为系统提供了基本的外观和感觉。

我们也看了一些将会对我们有帮助的工具,汇编器、编译器、链接器、PartCopy、MagicISO还有Bochs。

我对正在阅读这一章而又没有任何编程经验的人(我知道有一些这样的人)感到羞愧:)请回到第一章并重新阅读“要求”这一节。你为什么非要到这里来呢?赶快回去吧!

在本文中,我们将从另外一种角度来看操作系统。我们首先回到过去去看看操作系统的历史。你将会发现这些操作系统之间有很多相似点。这些相似点将会被归类为操作系统所有共有的基本东西——也是创建我们操作系统的积木(building blocks)。

快速回顾

今天大多数的操作系统是图形化的。然而,这些图形用户接口(GUI),为操作系统上正在运行的程序提供了一个大的抽象层。

许多操作系统的概念需要追溯到磁带程序时代,许多概念在今天仍然有效。

历史背景——对操作系统的需求

二十世纪50年代之前,所有的程序员都在穿孔卡片上工作。这些穿孔卡片代表了一系列指令,这些指令会控制计算机硬件的所有开关,每一片软件都有系统的完全控制权。大多数时间,这些软件都会完全与其他的不同,即使是一个程序的不同版本。

问题就是这些程序完全不同,程序员们不得不非常简单地工作,因为他们不得不始终从零开始重写软件。没有对软件的共同的支持,所以软件必须直接与硬件打交道,这也使得软件不可能有可移植性和兼容性。

在大型计算机的领域,创建代码库变得更为可行(feasable)。它确实解决了一些问题,如一个软件的两个版本完全不同的问题,但是每个软件仍然有硬件的完全控制权。

如果有新的硬件出现,这些软件将无法工作。如果软件崩溃了,需要利用控制面板上的灯的开关来调试。

硬件和程序之间的接口的想法就是来自于大型机时代。通过创建一个硬件的抽象层,程序将不再需要拥有完全控制权,相反,他们都会使用一个单一的共同的硬件接口。

那么这个超级酷(ultra cool)的接口是什么呢?他是一个甜美可爱(有时又令人讨厌)的东西也就是我们所说的操作系统。

20世纪50年代——操作系统的起源

根据wikipedia上的记录,第一个真正的操作系统是GM-NAA I/O。SHARE操作系统(SHARE Operating System)是GM-NAA I/O的一个继任者。SHARE提供了共享程序,管理缓冲区的功能,同时它也是第一允许执行用汇编语言编写的程序的操作系统。SHARE成为了20世纪 50年代后期IBM计算机的标准操作系统。

SHARE

SHARE操作系统(SOS)是第一个能够管理缓冲区,提供程序共享以及允许执行汇编语言程序的操作系统。

“管理缓冲区”涉及到一种“管理内存”的形式。“程序共享”涉及到使用不同程序的库。

在这里有两个重点要指出,从一开始的时候(事实上不是:)),操作系统就负责内存管理和程序执行/管理。

因为这不是我想描述的世界(也不是计算机)的历史,所以我们直接跳到美好的旧DOS时代。

1964——DOS/360和OS/360

DOS/360(或者就叫“DOS”)是一个磁盘操作系统(Disk Operating System)。原本IBM宣布它将在1964年的最后一天发布,但是由于某些原因,IBM不得不推迟DOS/360并推出了3个版本,直到1966年6月才发布DOS/360。

这几个版本是:

  • BOS/360 – 8KB配置
  • DOS/360 – 16KB的磁盘配置
  • TOS/360 – 16KB的磁带配置

两个需要指出的重点是DOS/360并没有提供多任务内存保护。OS/360基本上是IBM在同一时间开发的一款操作系统。OS/360使用了“OS/MFT”(Multiple Fixed Transactions)和固定基址来支持多程序。使用OS/MVT(Multiple Varable Transaction),它就能支持可变程序大小。

现在我们又多了几个有趣的关键字——多任务内存保护固定基址,加上前面的程序执行内存管理

1969——Unix!

Unix操作系统最初是用C编写的,C和Unix都是由AT&T最初创造的。由于Unix和C大量地分布在政府和学术机构,所以导致相对于其他的操作系统,它被移植到各种各样的机器家族上。

Unix是一个多用户多任务操作系统。

Unix由一个内核文件系统和一个命令壳组成。有很多图形用户接口(GUI)使用命令壳与操作系统交互,并且提供了一个更为友好和美观的界面。

1982——Commodore DOS

Commodore DOS

Commodore DOS(CBM DOS)与Comodore的8位计算机一起使用。不像其他的操作系统,在启动时从磁盘引导到系统内存之前或者当时,CBM DOS在一个内部驱动的ROM芯片中内部执行,是被一个MOS 6502 CPU执行的。

1985——Microsoft Windows 1.0

Microsoft Windows 1.0

第一个Windows是一个DOS应用程序。它的“MSDOS Executive”程序只允许一个程序的运行。不允许有“窗口”的重叠,因此“窗口”被显示为在一边或另一边。它并不很受欢迎。

1987——Microsoft Windows 2.0

Microsoft Windows 2.0

Windows的第二个版本仍然是一个DOS的图形壳(Graphical Shell),但是支持重叠窗口和更多的颜色。但是,由于DOS的限制,它并没有被广泛使用。

备注:DOS是一个16位操作系统。在这段时间,DOS不得不通过线性地址来访问内存,通过LBA(线性块地址(Linear Block Addressing))访问磁盘。因为x86平台是向后兼容的,所以PC启动时是在16位模式(实模式),仍然使用LBA。后面会讲到更多关于这个的内容。

由于16位模式的限制,DOS无法访问高于1MB的内存。在今天这个已经被解决了,方法是通过键盘控制器打开A20地址总线。我们后面将讲到这个内容。

因为这个1MB的限制,Windows实在是太慢了,这也是它无法流行的主要原因。

1987——Microsoft Windows 3.0

Microsoft Windows 3.0

Windows 2.0被完全重新设计。Windows 3.0同样是一个DOS图形壳(Graphical Shell),然而,它包含一个“DOS扩展器”允许访问到16MB的内存,超出了DOS的1MB内存限制。它支持多任务的DOS程序。

Windows与操作系统开发者的关系

我看到很有一些入门级的操作系统开发者想开发另外一个Windows。虽然这是可能,但却是极度困难的,一个人更本不可能完成。再看一看上面的图片,你要知道它是一个通过命令壳(Command Shell)被内核执行的图形壳(Graphical Shell)。同样你要知道即使是Windows也是从这里开始的。命令壳就是DOS,图形壳就是“Windows”。

基本概念

回顾我们的前面的旅途,它给我们带来一些重要的术语。到目前为止,我们仅仅给出了“操作系统”的一个小的定义。前面的章节会帮助我们定义一个更好的,更具有描述性的关于什么是操作系统的定义。

为了得到一个更好的定义,让我们把上面的黑体术语列成一个表:

  • 内存管理
  • 程序管理
  • 多任务
  • 内存保护
  • 固定基址
  • 多用户
  • 内核
  • 文件系统
  • 命令壳
  • 图形用户接口(GUI)
  • 图形壳
  • 线性块地址(LBA)
  • 引导程序(前一章)

这可以联想到很多,不是吗?上述列表在技术上本身仍然是一个抽象层。

让我们深入了解一下吧!

内存管理

内存管理涉及到:

  • 动态给需要的程序分配内存或回收内存
  • 实现一种形式的分页,或者甚至虚拟内存
  • 保证操作操作系统内核不会读或者写未知或无效内存
  • 查看和处理内存碎片

程序管理

这个与内存管理关系非常密切,程序管理负责:

  • 保证程序不会覆盖另外一个程序
  • 保证程序不会破坏系统数据
  • 处理程序的请求以完成一个任务(如分配和回收内存)

多任务

多任务涉及到:

  • 切换程序并给予多个程序一个特定的时间片去执行
  • 提供一个任务管理器以允许任务切换(如Windows任务管理器)
  • TSS(Task State Segment)切换。这是一个新的术语
  • 同时地执行多个程序

内存保护

它涉及到:

  • 在保护模式下访问一个无效的描述符(或者一个无效的段地址)
  • 覆盖了程序它自己
  • 覆盖了内存中另一个程序的一部分或几部分

固定基址

一个“固定基址”是一个程序加载在内存中的地方。在一般的应用程序编程中,你一般不需要使用它。然而,在操作系统开发中,你需要使用它。

一个“固定”的基址仅仅意味着程序每次加载到内存的时候都拥有同一个基址。举两个例子程序,BIOS和Bootloader。

多用户

它涉及到:

  • 登录和安全保护
  • 多个用户工作在同一台计算机上的能力
  • 在没有损失和损坏数据的情况下切换用户

内核

内核是操作系统的心脏。它提供了基本的基础,内存管理,文件系统,程序执行等等。我们将在不久之后更进一步探究它,不用担心:)。

文件系统

在操作系统开发中,没有被称为“文件”的东西。所有的东西都可以是纯二进制代码(从启动扇区中来);从一开始。

一个文件系统仅仅是一个描述关于文件信息的详细说明。在大多数情况下,指的是簇,段,段地址,根目录等等。操作系统要想加载它,就必须找到文件的确切的起始地址。

文件系统也描述文件名。文件名分为外部文件名和内部文件名。例如,FAT12说明描述的一个文件名只能是11个字符。不能多也不能少,非常严格。例如,这意味着文件名”KRNL.SYS”的内部文件名是”KRNL    SYS”。

我们将会使用FAT12文件系统,后面会详细讨论它。

命令壳

命令壳在内核之上作为一个单独的程序。命令壳通过使用输入命令提供基本的输入输出。命令壳使用内核来实现它并完成低级任务。

图形用户接口(GUI

图形用户接口(GUI)仅仅涉及到图形接口以及图形壳和用户之间的交互。

图形壳

图形壳提供了视频例程和低级图形能力。它通常会被命令壳执行(就像Windows 1.0,2.0和3.0)。然而现在这些一般都是自动的。

线性块地址(LBA

操作系统已经控制了内存中的每一个单个字节。线性地址是指直接访问线性内存。例如:

1mov ax, [09000h]        ; There is no such thing as Access Violations in OS Development

这是件好事情但同样也有可能是坏事情。例如:

1mov bx, [07bffh]        ; or some other address less then 7c00h
2    mov cx, 10
3.loop1:
4    mov [bx], 0h        ; clear bx
5    inc bx              ; go to next address
6    loop    .loop1      ; loop until cx=0

上面的代码看起来无害处,然而,如果上面的代码是在引导程序中,则上面的代码会将自己覆盖10字节。天啦!这是因为引导程序被加载在一个固定的地 址,即0x7c00:0(这里应该有问题,应该是0x7c0:0),而上面代码从07bffh开始写:07c00h前面一个字节。

引导程序

引导程序,我们在前面一章看到了这个术语。从前一章我们知道了,引导程序被BIOS加载,并且它是你的操作系统执行的第一个程序。

引导程序被BIOS加载到绝对地址0x7c00:0(同样应该是0x7c0:0)。加载之后,CS:IP被设置到你的引导程序,然后引导程序完全接管控制。

一个软盘扇区的大小仅仅只有512字节。记住引导程序必须装配到一个单个扇区中。这意味着什么?引导程序在大小上被严格限制了,不能超过512字节。

结论

我们回顾了一下过去,学习了一些新的术语,并加入了我们的术语表。在历史课之后,我们学习了术语并建立了一个更宽的视角来看一切是如何工作的。我们甚至看了一些代码,虽然很少。

这之后,我们就可以开发一个关于我们所做的更加简明的定义。

“它是一个交互环境,它提供了一个用户和应用程序的接口,提供了一个稳定的安全的环境,提供了一个系统服务和计算机硬件接口层”

是的,这就是我关于“操作系统”的新的定义,你的呢?

未完待续

在下一章中,我们将详细地看一看启动过程。除此之外,我们将看看如何建造和汇编一个真正的引导程序。




阅读(476) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~