从头开始编写操作系统(3) 第2章:基本理论

来源:互联网 发布:linux find查找文件 编辑:程序博客网 时间:2024/05/29 05:58

译自:http://www.brokenthorn.com/Resources/OSDev2.html

2章:基本理论
by Mike, 2009

本系列文章旨在向您展示并说明如何从头开发一个操作系统。

介绍

欢迎来到有趣又疯狂的操作系统是世界!

在前面的章节中,我们定义了操作系统是什么。操作系统是用户和计算机系统之间的基本接口(界面)。它提供了系统的基本外观和感觉。

我们也看到了一些对我们有帮助的工具。汇编器、编译器、连接器、PartCopy MagicISOBochs

对于那些正在阅读本文却又没有编程经验的人来说(我知道有一些)抱歉,请返回到第1章“读者需要了解的知识”一节。为什么你还在看呢?来吧,继续!

在这篇文章中,我们将会从不同的视角来看操作系统。我们首先要Back in Time(tm) 看看操作系统的历史。你会发现这些操作系统有很多相似之处。这些相似之处后来变成了操作系统所具有的基本的东西,并且也将成为你的操作系统的一部分。

Blast from the Past(想起过去)

现在大多数的操作系统都是图像化的。这些图像用户界面(graphical user interfaces (GUI))是对操作系统真正在做的事情的一种抽象。

大多数的操作系统概念要追溯到程序还在磁带上的时候,这些概念现在依然活跃。

史前——对操作系统的需求

追溯到20世纪50年代,所以的程序都在卡片上。这些卡片代表着一些指令,这些指令控制着计算机硬件的每一个开关。每一段软件都完整控制着整个系统。多数情况下,每一个软件都各不相同,即使是同一个软件的不同版本。

问题是每一个程序都完全不同。它们必须简化,因为它们必须从头重写。没有对软件的通用支持,所以软件必须直接与硬件交互。这样也使兼容变得不可能。

在大型机中,创建代码库更为科可行。虽然这解决了部分问题,同一个软件的不同版本完全不同,每一个软件完全控制硬件。

如果更换了新的硬件,软件就变得不再可用。如果软件崩溃,就得使用控制面板上的小开关来调试。

这种在软硬件之间设置接口的想法来源于大型机领域。通过一个硬件之上的抽象层,程序不再完全控制硬件,相反的,它们使用一个单独的公用的接口来控制硬件。

这个酷毙了的接口是什么?什么,这个甜美可爱(有时是令人生厌)的东西,我们把它叫做操作系统!

1950s——是的,操作系统来了

根据wiki百科,第一个真正的操作系统是 GM-NAA I/OSHARE操作系统的GM-NAA I/O的后继者。SHARE提供共享程序、缓冲区管理,并且是第一个可以执行由汇编语言编写的出现的操作系统。在20世纪50年代SHAREIBM计算机的标准操作系统。

http://www.brokenthorn.com/Resources/images/SHARE.jpg

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

“缓冲区管理”类似于“内存管理”。“共享程序”类似于不同的程序使用库文件。

从开始(不是真的J)的时候,操作系统的两个重要任务是管理内存和管理程序。

因为我们并不是在描述真正的(计算机)历史,让我们跳到老DOS吧。

1964——DOS/360 OS/360

DOS/360(或简称“DOS”)是一个磁盘操作系统,IBM最初宣称在1964年末推出。因为一些问题,被迫延迟到19666IBM推出了DOS/360 3个版本。

它们是:

  • BOS/360 - 8KB
  • DOS/360 - 16KB 配有磁盘
  • TOS/360 - 16KB 配有磁带

要注意的是DOS/360 没有多任务,也没有内存保护。OS/360大约在同一时间在IBM开发。OS/360 使用“OS/MFT(Multiple Fixed Transactions) 支持多任务。使用固定基地址(Fixed Base Address)和OS/MVT (Multiple VariableTransaction),支持可变程序尺寸。

现在我们有了几个有钱的词——多任务(Multitasking)、内存保护(Memory Protection)和固定基地址(Fixed Base Address),加上前面的我们有了程序执行(Programexecution)和内存管理(Memory Management

1969——Unix!

Unix操作系统原本用C语言编写。C语言和Unix都是AT&T创造的。UnixC对于政府和教育部门自由分发,这使得它被引入到了多种设备和操作系统之中。

Unix是一个多用户(multiuser)、多任务(Multitasking)的操作系统

Unix包含一个内核(Kernel)、文件系统(File System)和一个命令壳(Comm Shell)。有大量的图形用户接口(Graphical UserInterfaces (GUI)使用命令壳(Comm Shell与操作系统交互,并提供更友好更漂亮的外观。

1982——Commodore DOS

http://www.brokenthorn.com/Resources/images/DOS%5b1%5d.gif

Commodore DOS (CBM DOS)Commodore's8位计算机上使用。不像前面提到的那些在启动时由磁盘引导内存的计算机,CBM DOS在驱动器内部执行——内部有ROM芯片,被一个MOS 6502 CPU执行。

1985——Microsoft Windows 1.0

http://www.brokenthorn.com/Resources/images/Windows1.gif

第一个Windows是一个DOS应用程序。它的“MSDOS Executive”程序可以运行程序“窗口(Windows)”不能覆盖,所以每个“窗口”都显示在一边。它不怎么流行。

1987——Microsoft Windows 2.0

http://www.brokenthorn.com/Resources/images/Windows2.gif

Windows的第二个版本依然是一个DOS 图形壳(Graphical Shell),但是支持窗口覆盖,以及更多的颜色。然而,受限于DOS,它为被广泛使用。

注释:DOS是一个16位操作系统,使用线性地址访问内存,使用LBA(Linear Block Addressing线性块地址)访问磁盘。因为x86平台向后兼容,当PC引导时处在位(实模式)使用LBA,更多内容,后文详述。

受限于16位模式,DOS不能访问超过1 MB 的内存。现在它通过打开键盘控制器上的第20号地址线被解决了,我们在后边详细讨论。

因为1 MB内存的限制Windows 很慢,这也是它无法流行的另一个主要原因。

1987——Microsoft Windows 3.0

http://www.brokenthorn.com/Resources/images/Windows3.gif

Windows 2.0 被完全重写,Windows3.0 还是一个DOS图形壳,但它包含一个“DOS扩展”以允许使用多达16 MB的内存,跨越了DOS1 MB限制。它支持多任务(multitasking)。

正是这个Windows使得Microsoft做大。它支持可调整大小的窗口和窗口移动。

操作系统开发与Windows的关系

我很少见到有操作系统的初级开发者会想要做下一代Windows。虽然这是可能的,但是相当困难,并且对于只有一个人的团队来说这似乎是不可能的。看看前面的图片吧,记住图形壳在命令壳之上,都被内核执行。同样,记住,Windows必须从这里开始。命令壳是DOS,图形壳是“Windows”。

基本概念

看看我们这个短暂的旅程,它给我们带来一些重要的新条目。开始的时候,我们只给出了关于操作系统的简单定义。前一节中的信息使我们能够得到更好更准确的操作系统定义。

为了得到一个更好的定义,让我们把前面加粗的词列在下面:

  • 内存管理Memory Management
  • 程序管理Program Management
  • 多任务Multitasking
  • 内存保护Memory Protection
  • 固定基地址Fixed Base Address
  • 多用户Multiuser
  • 内核Kernel
  • 文件系统File System
  • 命令壳Comm Shell
  • 图像用户界面Graphical User Interface (GUI)
  • 图像壳Graphical Shell
  • 线性块地址Linear Block Addressing (LBA)
  • 引导加载器Bootloader (来自前一章)

有更多需要考虑的,不是吗?——上面的列表也是对自己的抽象。

让我们看得更仔细些。

内存管理Memory Management

内存管理是:

  • 动态的根据抽象的要求分配或收回内存。
  • 实现分页(Paging)或虚拟存储器(Virtual Memory)。
  • 确保操作系统内核不读或写未知的或是非法的内存。
  • 监视并管理内存碎片(Memory Fragmentation)。

程序管理Program Management

与内存管理相似。程序管理的任务是:

  • 确保程序不覆盖另一个程序。
  • 确保程序不损害系统数据。
  • 控制程序请求以完成任务(比如分配和回收内存)。

多任务Multitasking

多任务是:

  • 在多个程序之间切换,并给出时间片以使其执行。
  • 提供一个任务管理器(Task Manager)允许切换任务(就像Windows的任务管理器)。
  • TSS Task State Segment 任务栈段)切换。新条目!
  • 同时执行多个任务。

内存保护Memory Protection

它是:

  • 在保护模式下访问非法描述符(或非法段地址)。
  • 覆盖程序本身。
  • 覆盖在内存中的其他文件的一部分或几部分。

固定基地址Fixed Base Address

“基地址”就是程序加载到内存中位置。在同城的应用程序编程中,你不需要它,但在操作系统开发中,你需要。

“固定”基地址简而言之就是程序每次加载到内存的基地址都是一样的,两个例子是BIOS和引导加载器。

多用户Multiuser

它是:

  • 注册及安全保护。
  • 使多个用户在这台计算机上工作。
  • 在保证数据不丢失,不损坏的前提下,切换用户。

内核Kernel

内核是操作系统的核心。它提供基本功能、内存管理、文件系统、程序执行等等。我们很快会详细了解内核,别着急。

文件系统File System

在操作系统开发中,没有一个叫做“文件”的东西。从一开始(引导加载器)所有的东西都是纯二进制代码。

文件系统简单来说就是对文件信息的描述。多数情况下,这表示簇、段、段地址、根目录等。使得操作系统可以找到文件的确定起始并按顺序加载它。

文件系统也描述文件名。有外部(external)文件名和内部(internal)文件名。比如FAT12定义文件名必须是11个字符,不能多,也不能少,也就是说,比如文件名“KRNL.sys”的内部文件名是:

"KRNL   SYS"

我们会使用FAT12并且在后面详细讨论。

命令壳Comm Shell

命令壳是内核之上的一个独立程序。命令壳通过键入命令来提供一个基本的输入输出功能。命令壳使用内核来帮助其完成底层任务。

图形用户界面(GUI)

图形用户界面(GUI)即是图形壳和用户之间的接口。

图形壳Graphical Shell

图形壳提供视频程序及底层图像功能。一般的它会被命令壳执行(就像Windows 1.02.03.0)。然而现在它们会自动执行。

线性块地址 (LBA)

操作系统能控制内存的每一个字节。线性地址直接访问线性内存,比如

mov ax, [09000h]               ;在操作系统开发中,没有访问违规

这既是好事也坏事,比如:

mov bx, [07bffh]               ; 或者其他比7c00h小的地址

mov cx, 10

   .loop1:

        mov [bx], 0h           ; 清空bx

        inc bx                 ;下一个地址

        loop .loop1            ;循环知道cx=0

上面的代码看似无害,但是,如果这段代码出现在引导加载器中,它会将自己用十个字节覆盖。呀,这是因为引导加载器被固定的加载到地址0x7c00:0处,而上面的代码从 07bffh07c00h前一字节)开始写数据。

引导加载器Bootloader

引导加载器,我们从上一章就见到这个条目,从上一章我们知道,引导加载器被BIOS加载,并且是操作系统中执行的第一个程序。

引导加载器被BIOS加载到绝对地址0x7c00:0处, 加载后,CS:IP被设置为引导加载器的入口点,并且引导加载器获得全部控制权。

一个软盘扇区只有512字节。记住引导加载器必须放到一个扇区中。这意味着什么?引导加载器的大小十分受限,不能超过512字节。

大多数情况下,引导加载器要么加载并执行内核,要么加载并执行第二段引导加载器(Second Stage Bootloader)。

我们会很快会深入了解引导步骤。

总结

我们看了看过去,并且学习了列表中的新条目。在历史课之后,我们提取条目,并展开讨论每一个是如何工作的。我们甚至还见到了一些代码,尽管很少。

之后,我们能够得到一个关于我们要做的事情的更简明的定义。

“一个提供给用户和支持程序的接口环境;提供一个稳健安全的环境;一个系统服务和硬件之间的接口层”

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

下一章,我们将详细描述引导步骤,换言之,我们将创建和汇编真正的引导加载器。

下次见。

原创粉丝点击