Lesson 1:引导扇区
本课我们将学习引导扇区的内容,然后我们就可以开始写自己的引导程序。
当计算机从软盘启动时,BIOS读取磁盘并将第一个扇区载入内存地址0000:7C00。这第一个扇区称为DOS 引导记录(DBR)。BIOS跳转到地址0x7C00并开始执行那里的指令。这些指令将把操作系统(OS)载入内存并开始OS的引导进程。
我们首先要做的就是看引导记录。DOS的工具DEBUG是一个很有效的工具,它可以用于查看内存和磁盘的内容。我们将使用DEBUG来查看软盘的引导记录。
在DOS(或Windows)的命令行提示符下打入debug。将显示一个连字号为提示符。如果输入字母“d”并回车,将显示RAM(随机存取存贮器)的内容。输入?并回车将显示DEBUG的所有有效命令列表。(使用DEGUG工具时必须非常小心。该工具可以用来覆盖任意磁盘的数据,很容易造成数据丢失。)
将一张完全格式化过的磁盘放入软驱。输入以下命令可以软盘载入引导记录:
-l 0 0 0 1
(第一个字符是字母“l”,不是数字“1”。)该命令将磁盘的扇区载入RAM的部分。字母“l”后面的4个数字依次表示:数据被载入的开始地址,驱动器名(0表示软盘),磁盘上的第一个引导扇区,需要载入多少扇区。输入这个命令将把软盘的第一个扇区从0地址开始载入内存。
既然我们将引导记录载入了内存,我们输入以下命令,就可以看到它的内容:
-d 0
你能看到软盘引导记录的前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...
乍一看去,好象没什么信息。再看看,这好象就是一个没有命名的FAT12文件系统的MS-DOS 5.0盘。最左边的列显示RAM中的内存地址。中间列的十六进制数显示内存部分的所有字节数,右列的十六进制数用ASCII字符表示这些十六进制数。(其中有一部分可能是乱码)。你看到的引导记录部分有一些正是引导程序的部分指令,还有一些保留磁盘信息,如每个扇区的字节数,每个磁道的扇区数,等等。
现在是我们看引导程序代码的时候了,输入以下命令:
-u 0
这执行了一个“非集合操作”。给我们显示了和前面相同的字节(从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文件。这些文件包含了操作系统的代码。如果在磁盘上找不到这些文件,引导程序将显示如下 “著名”的错误消息:
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开始继续并一直延续到地址0x1FD,其后跟随着两字节,0x55和0xAA。在下一课中我们将运用这些知识开始制作我们的引导程序。