Write Your Own Operating System Tutorial(中文版) - Lesson 1: 引导扇区

Lesson 1: 引导扇区


这一课我们将学习引导扇区的知识,这样我们就能写一个我们自己的引导程序了。

当计算机从软盘引导时, BIOS (Basic Input/Output System)将磁盘的第一个扇区读入以0000:7C00开始的内存。这个扇区称为DOS Boot Record (DBR)。然后,BIOS跳转到0x7C00开始执行那里的指令。正是那些指令(即“boot loader”)将把OS加载到内存中,并且开始启动处理。

我们要做的第一件事情是仔细看一看Boot Record。DOS的工具DEBUG非常有用,我们常常用它来查看内存或着是磁盘的内容。同样,我们将用DEBUG来看看软盘的Boot Record。

在DOS (或者Windows)的命令行方式下输入debug。于是提示符变成了连接线。如果你输入命令‘d’加上一个回车,它将显示一块内存的内容。如果你输入一个问号,将显示在DEBUG中可用的命令。(请仔细使用DEBUG。它可以用来覆盖磁盘上的内容,这有可能导致数据的丢失。)

请在软驱中放入一张新格式化的软盘。要载入你软盘上的Boot Record,请输入如下命令。

-l 0 0 0 1

(第一个字符是字母‘l’,而不是数字‘1’。)这个命令将磁盘扇区载入到内存中。‘l’后面的四个数字,依次表示你希望将数据载入到其中的那块内存的首地址,驱动器编号 (软驱的话,是0),以及扇区的编号和扇区的数目。输入这个命令将把磁盘的第一个扇区载入到内存以0开始的地方。

现在我们已经把Boot Record载入到内存里了,接下来我们想看看它的内容,输入下面的指令。

-d 0

你会看到8行数据,它们表示软盘引导记录最初的128(16进制的0x80)个字节。结果(我的软盘)如下:

0AF6:0000  EB 3C 90 4D 53 44 4F 53-35 2E 30 00 02 01 01 00   .<.MSDOS5.0.....

0AF6:0010  02 E0 00 40 0B F0 09 00-12 00 02 00 00 00 00 00   ...@............

0AF6:0020  00 00 00 00 00 00 29 F6-63 30 88 4E 4F 20 4E 41   ......).c0.NO NA

0AF6:0030  4D 45 20 20 20 20 46 41-54 31 32 20 20 20 33 C9   ME    FAT12   3.

0AF6:0040  8E D1 BC F0 7B 8E D9 B8-00 20 8E C0 FC BD 00 7C   ....{.... .....|

0AF6:0050  38 4E 24 7D 24 8B C1 99-E8 3C 01 72 1C 83 EB 3A   8N$}$....<.r...:

0AF6:0060  66 A1 1C 7C 26 66 3B 07-26 8A 57 FC 75 06 80 CA   f..|&f;.&.W.u...

0AF6:0070  02 88 56 02 80 C3 10 73-EB 33 C9 8A 46 10 98 F7   ..V....s.3..F...

 

粗看一眼,仿佛什么都没有。我能够看出来这是张MS-DOS 5.0的软盘,有一个没有名字的FAT12文件系统。最左端的数字显示的是内存地址。中间的16进制码显示的是这段内存的全部字节,最右边显示的是16进制码所对应的ASCII字符(如果某字节不能被转换为一个可见的字符,就用一个句点来表示)。这部分引导记录中的一些字节是boot loader的指令,另一些存储了诸如每个扇区多少字节,每个磁道多少扇区这样的信息。

现在到看一看boot loader代码的时候了。输入下面的指令。

-u 0

这将执行“unassemble”操作。这将同样显示刚才的那些字节,(从地址0开始),只不过这一次DEBUG显示的是这些字节所表示的INTEL的指令。我的软盘结果如下:

0AF6:0000 EB3C          JMP     003E

0AF6:0002 90            NOP

0AF6:0003 4D            DEC     BP

0AF6:0004 53            PUSH    BX

0AF6:0005 44            INC     SP

0AF6:0006 4F            DEC     DI

0AF6:0007 53            PUSH    BX

0AF6:0008 352E30        XOR     AX,302E

0AF6:000B 0002          ADD     [BP+SI],AL

0AF6:000D 0101          ADD     [BX+DI],AX

0AF6:000F 0002          ADD     [BP+SI],AL

0AF6:0011 E000          LOOPNZ  0013

0AF6:0013 40            INC     AX

0AF6:0014 0BF0          OR      SI,AX

0AF6:0016 0900          OR      [BX+SI],AX

0AF6:0018 1200          ADC     AL,[BX+SI]

0AF6:001A 0200          ADD     AL,[BX+SI]

0AF6:001C 0000          ADD     [BX+SI],AL

0AF6:001E 0000          ADD     [BX+SI],AL

 

第一个指令要求跳转到0x3E。这之后的指令是关于刚才我提到的软盘参数的,并没有对应的指令,但是DEBUG还是尽心尽责的为我们翻译了。

第一条指令跳过了这些数据,执行从地址0x3E开始的启动程序的代码。让我们看看那里的指令,输入:

-u 3E

在这里,你能看到负责加载DOS或者是WINDOWS的代码的开始部分。代码(就MS-DOS来说)将在磁盘上寻找IO.SYS和MSDOS.SYS。这些文件包含了操作系统的代码。boot loader的代码将把这些文件载入到内存中,并且开始执行它们。如果在磁盘上没有找到这些文件,boot loader将显示如下这条臭名昭著的错误信息:

Invalid system disk

Disk I/O error

Replace the disk, and then press any key

 

如果你看一下DOS引导记录的最后部分,你将会发现这条信息。你可以看看我磁盘上的:

-d 180

0AFC:0180  18 01 27 0D 0A 49 6E 76-61 6C 69 64 20 73 79 73   ..'..Invalid sys

0AFC:0190  74 65 6D 20 64 69 73 6B-FF 0D 0A 44 69 73 6B 20   tem disk...Disk

0AFC:01A0  49 2F 4F 20 65 72 72 6F-72 FF 0D 0A 52 65 70 6C   I/O error...Repl

0AFC:01B0  61 63 65 20 74 68 65 20-64 69 73 6B 2C 20 61 6E   ace the disk, an

0AFC:01C0  64 20 74 68 65 6E 20 70-72 65 73 73 20 61 6E 79   d then press any

0AFC:01D0  20 6B 65 79 0D 0A 00 00-49 4F 20 20 20 20 20 20    key....IO      

0AFC:01E0  53 59 53 4D 53 44 4F 53-20 20 20 53 59 53 7F 01   SYSMSDOS   SYS..

0AFC:01F0  00 41 BB 00 07 60 66 6A-00 E9 3B FF 00 00 55 AA   .A...`fj..;...U.

 

这是引导记录的末尾。引导记录在磁盘上恰好占一个扇区(512字节)。如果从内存地址0开始加载它,那么最后那个地址应该是0x1FF。如果你看一看引导记录的这最后两个字节(0x1FE和0x1FF),你会发现它们是0x55和0xAA。引导记录的最后两个字节一定得是这个值,否则BIOS将不会加载这个扇区并且执行它。

概括起来说,DOS的引导记录以一个跳转指令开始,这个跳转指令讲跳过紧随其后的数据。这60字节的数据从0x02开始,至0x3D,之后是引导代码,从0x3E到0xFD,再之后是两个字节0x55和0xAA。下一课我们将利用我们的这些知识,来写一个我们自己的引导程序。

 

你可能感兴趣的:(Write Your Own Operating System Tutorial(中文版) - Lesson 1: 引导扇区)