博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Write Your Own Operating System Tutorial(中文版) - Lesson 1: 引导扇区
阅读量:2234 次
发布时间:2019-05-09

本文共 3440 字,大约阅读时间需要 11 分钟。

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。下一课我们将利用我们的这些知识,来写一个我们自己的引导程序。
 

转载地址:http://fcibb.baihongyu.com/

你可能感兴趣的文章
Oracle知识点连载(一)
查看>>
Oracle知识点连载(二)
查看>>
Oracle知识点连载(三)
查看>>
Oracle知识点连载(五)
查看>>
关于三元运算符的类型转换问题
查看>>
笔记本怎么设置WIfi热点
查看>>
如何实现字符串的反转及替换?
查看>>
Java面试题全集(上)
查看>>
Java面试题全集(中)
查看>>
值传递和引用传递
查看>>
什么情况下用+运算符进行字符串连接比调用StringBuilder对象的append方法连接字符串性能更好?
查看>>
怎么根据Comparable方法中的compareTo方法的返回值的正负 判断升序 还是 降序?
查看>>
理解事务的4种隔离级别
查看>>
常用正则匹配符号
查看>>
建议42: 让工具类不可实例化
查看>>
Java 异步机制与同步机制的区别
查看>>
hibernate的对象三种状态说明
查看>>
什么是N+1查询?
查看>>
Spring 接管 Hibernate 配置 延迟加载
查看>>
找出不在预定数组中的自然数
查看>>