系统引导环节是操作系统启动过程中的最重要环节,也是最容易出问题的环节之一。按照个人计算机的硬件标准,引导环节发生在计算机的硬件系统检测完毕之后。具体的引导工作,是由BIOS完成的。BIOS维持一个可用于引导计算机的硬件设备列表,比如本地硬盘、本地光驱、网络、USB接口设备等,然后做一个排序。BIOS会试图从整个序列的第一个设备开始,检查其状态和引导能力。比如针对光驱,则首先会判断光驱中是否存在光盘,如果不存在,则跳过光驱设备,进入下一个设备的检测过程。如果发现有光盘存在,则试图读取光盘的第一个扇区,并检查这是否是一个可引导扇区(比如通过检查扇区的最后两个字节是不是0x55AA)。如果发现不是一个可引导扇区,则也是跳过光盘,再检查引导序列中的下一个设备,直到发现一个可引导的扇区为止。如果遍历完整个引导设备列表,未找到任何可引导的扇区代码,则引导过程失败,BIOS会提示无法找到可启动设备。如果在这个过程中能够找到一个可引导扇区,则BIOS会把该扇区的内容加载到内存,并跳转到该扇区,执行引导代码。这个跳转指令,就是BIOS程序在计算机启动过程中的最后一条指令,至此,BIOS的工作结束。后续工作,将由引导扇区代码完成。

由此可见,BIOS在计算机引导过程中的角色是非常重要且复杂的。但是由于其独立于操作系统的实现,不是我们重点分析的范畴。在本文中,我们重点分析引导扇区被加载到内存,并开始执行后的过程。这个过程属于操作系统的作用范畴,而且是操作系统生命周期的最开始部分。本文将以硬盘为例,首先分析硬盘的逻辑结构和主引导记录(MBR)的作用,然后再分析不同的文件系统下,操作系统引导扇区的功能差异和实现差异,以及每种实现的功能缺陷。最后给出一种克服了这些缺陷的一种引导程序制作方法-预置引导法,并以Hello China操作系统的引导程序为实例,说明这种方法的应用。

硬盘逻辑结构及引导扇区的功能

可以在逻辑上把硬盘理解为一个线性数组,这个数组的元素就是扇区。每个扇区按照其在硬盘上的位置进行编号,第一个扇区就是大名鼎鼎的MBR(主引导区,Master Boot Record)。

为了管理上的方便,一个硬盘可以划分为若干个逻辑分区,每个分区占据了硬盘上的一部分连续的存储空间。一般情况下,分区在硬盘上的位置和大小,可用其在硬盘上的起始扇区号、扇区数量进行描述。目前的实现是,一个物理硬盘,最大可以分成四个分区,分区的位置、大小、属性等信息,记录在一个只有四个元素的线性表里,这个表就是分区表。

分区表就存放在MBR中,且在MBR中的固定位置处。因为一般情况下,硬盘的每个扇区的容量是512字节,如果分区表在MBR中的位置不固定,就无法明确读出分区表的内容。但分区表却不是MBR的唯一内容,MBR还存放了引导扇区代码。BIOS在发现一个可引导的硬盘之后,会把MBR的代码读入内存,然后跳转到开始处执行。需要说明的是MBR的代码一般是操作系统无关的。这可能会引起一些疑惑,下面稍作解释。

操作系统是安装在硬盘分区上的,至少到目前为止,我还不知道有哪个操作系统,不对硬盘进行分区(或者说把整个硬盘看做一个分区),而直接安装。而操作系统本身特定的引导代码,是放在其所在分区的第一个扇区上的。比如,一个硬盘被划分成了两个分区,一个分区的起始扇区号是2(MBR的扇区号是1),扇区数量是M。另外一个分区的起始扇区号是M+2,扇区数量是N。假设第一个分区上安装的是WINDOWS操作系统,第二个分区上安装的是Linux操作系统。这样,WINDOWS操作系统的引导扇区,是2个物理扇区(第一个分区的第一个扇区),而Linux的引导扇区,则是第M+2个物理扇区。显然,这两个(第2个和第M+2个)引导扇区是与操作系统强相关的。

但BIOS最初读入的是MBR。一旦跳入MBR执行,BIOS就撒手不管了。这时候MBR上的代码,必须能够找到Windows或Linux的引导扇区,并把它们读入内存中,完成相应操作系统的引导。因此MBR功能代码本身,需要完成两个问题的决策:

1、         在硬盘上有多个分区,每个分区都有可能安装操作系统的情况下,如何选择一个分区进行继续引导?

2、         如果确定了一个分区,如何得到这个分区的引导扇区的物理位置(即扇区在整个物理磁盘上的编号)?

显然,在第一个问题确定的情况下,第二个问题很容易解决。因为这时候分区编号已经确定,只要读取分区表,并找到对应的记录,就可读出该分区的第一个扇区的编号,这就是引导扇区。对于第一个问题,是通过在分区表中设置一个活动标志解决的。每个分区表项(对应一个分区)中,都有一个字节,叫做活动标志,且四个分区表项中,必须只有一个分区的活动标志被设置,这个分区就是活动分区。安装在这个分区上的操作系统会被引导。具体是由谁来设置这个标志呢?答案是操作系统。在操作系统安装的时候,会让你选择要安装的分区(比如Windows,会列出硬盘的分区情况,用C:、D:等盘符表示)。一旦选定一个分区,Windows安装程序就会把该分区对应的分区表项的活动标志设置为1,同时清除其它分区表项的活动标志。

按照这种规则,最后安装的操作系统,往往会“压制”以前安装的操作系统,使得先前安装的操作系统无法引导。但只要知道了这个过程,我们就可以通过一些工具,改变这种情况。比如你最后安装的是windows操作系统,在启动到Windows操作系统之后,可以通过运行在Windows操作系统上的工具,把Linux操作系统所在分区修改为活动分区。这样在下一次启动的时候,Linux就会被引导。但是为了安全起见,操作系统都提供了对MBR的保护功能,不能直接写入MBR。这样就很麻烦了,一旦你安装了windows,就意味着原有的Linux(与新安装的windows在不同分区)不能用了。但这也不是绝对的,比如可以通过光盘引导的操作系统,来修改MBR。或者可以在WIN分区上安装Hello China,由Hello China帮你完成修改活动分区标志的工作。

再绕回原题,MBR根据活动标志选择一个分区,并根据分区表中的分区起始位置确定操作系统引导扇区,然后把该扇区读入内存,并跳转到起始位置处继续执行。由此可见,MBR本身,是与特定操作系统无任何关系的。实际上,MBR扇区的可执行代码,自从DOS开始,就一直没有改变过。

一个物理硬盘最多有四个分区,某些软件公司,比如MS,认为这是不够的。于是又发明了一种技术,叫做扩展分区。扩展分区本质上就是一个硬盘分区(四个分区之一),但是在此基础上,又进行进一步扩展,把一个分区再进行细分,分为更小的分区(这些更小的分区叫逻辑分区),即分区套分区的结构。与硬盘的MBR一样,逻辑分区的相关信息,被记录在扩展分区的第一个扇区上。但是与普通分区不一样的是,扩展分区上的逻辑分区是不能引导操作系统的,即操作系统不能安装在逻辑分区上。既然操作系统不能安装在逻辑分区上,那么肯定也不能安装在扩展分区上了。因为扩展分区是逻辑分区的“容器”,其本身没有空间存储操作系统文件。因此要安装操作系统,必须要安装在普通的磁盘分区上。为显示这种“容纳”操作系统的特性,普通分区又被冠以“主要分区”的称号。

至此,下列一些概念或原理,您应该清楚了:

1、         MBR和分区表;

2、         MBR上的代码与操作系统无关;

3、         操作系统特定的引导扇区,是其所安装分区的第一个扇区;

4、         分区活动标志;

5、         主要分区、扩展分区、逻辑分区;

6、         MBR与操作系统引导扇区的关系。

操作系统引导扇区的功能和局限

接下来我们把目光转移到操作系统引导扇区上,即操作系统所在分区的第一个扇区。操作系统引导扇区与操作系统密切相关,其主要功能就是,在操作系统分区上,找到引导操作系统内核相关的文件,完成操作系统的加载。这里说的“引导操作系统相关的文件”,既可能是操作系统核心模块,也可能是为进一步引导操作系统核心模块而作准备的一些可执行代码。毕竟现代操作系统十分复杂,核心模块很大,无法直接完成引导。这样就可能有一些辅助的引导模块,毕竟引导扇区代码的功能是十分有限的。

但不论如何,引导扇区的代码必须在操作系统所在分区的文件系统里找到一个模块(实际上是一个文件),并加载到内存。因此下列两项功能是引导扇区代码的核心:

1、         在分区的文件系统上,找到一个特定文件;

2、         把这个文件装入内存,并跳转执行。

第二项工作比较容易,一般情况下,引导扇区还是运行在CPU的实模式下(以PC为例),可以调用BIOS提供的磁盘读写服务,很容易把文件读入内存。关键是第一项工作,如何在一个文件系统里搜索到一个特定的文件。实际上“搜索到一个文件”也不是关键,关键是如何以“一个扇区”的代码、在一个复杂的文件系统里找到一个想要的文件。这里的两个因素,形成一对矛盾:

1、         引导扇区代码尺寸有限,比如只有512字节,无法适应复杂的计算要求;

2、         文件系统结构复杂,访问文件系统所需要的代码量很大。

引导扇区需要很好的平衡这对矛盾,以使得引导过程能够继续。一般情况下,有下列几种方式解决这个问题:

1、         扩展引导扇区大小。一般认为,操作系统引导扇区是512字节,操作系统的初始引导完全是由这512字节代码完成的。实际上不然,很多操作系统,比如Windows,已经大大扩展了引导扇区尺寸。既然整个分区都是操作系统的地盘,那么每个分区怎么使用,就完全由操作系统决定了。引导扇区是分区的第一个扇区,这个不能变。那么我完全可以把第二个、第三个、…第N个扇区也作为引导扇区。第一个扇区只是作为跳板,MBR把第一个扇区读入内存并运行后,第一个扇区再把后面连续的一片扇区读入内存,这些所有的扇区共同组成引导模块。这样无论文件系统多么复杂,我只要多分配几个扇区,就可以装下访问文件系统的代码了。显然,这种方式很有效,且被广泛采用。比如windows操作系统,在NTFS文件系统上的引导扇区,就有16个(0~15号扇区),有8K的代码空间。这对分析NTFS文件系统并读取引导文件(比如NTLDR),就足够了;

2、         引导扇区维持一个不变,但是固定操作系统核心或相关文件在磁盘上的位置。还是那句话,整个地盘都是我的,我愿意安排谁在哪里都行。操作系统可以把引导相关的代码固定在磁盘的一个特定位置上,比如1024号扇区位置处。这样引导扇区就无需分析文件系统了,直接从1024号扇区处读取操作系统核心就行了。这种策略在DOS时代似乎被用过。记得我在上大学的时候,制作了一张DOS启动软盘,上面有IO.SYS等文件。有一次把IO.SYS文件删除了,又重新拷贝了一个进去,结果就不能启动DOS了。据此推测,DOS可能把IO.SYS等固定在了软盘的某个位置。一旦删除再拷贝,其位置变化了,就直接导致不能引导。

上述两种解决方案都有其局限性。第一种方案,在一个分区上只安装一个操作系统,或者安装相同软件厂商的不同操作系统时是有效的,但如果安装两个不同厂商的操作系统,可能就会有问题。假设操作系统A和B都使用的是第一种策略,A先安装到分区上。在第二个操作系统B安装的时候,为了能同时引导A系统,B会把A的引导扇区(第一个扇区)备份到一个文件里(比如windows系统下的BOOTSECT.DOS),然后把自己的引导扇区(可能连续几个)写入分区的开始处。这样A操作系统除第一个以外的引导扇区,都被B覆盖了。显然,这时候是无法再次引导A系统的。但是如果A和B是同一个软件公司的产品,比如Windows 98系列和Windows 2000/XP系列,由于都是微软开发,对引导扇区的结构和数量都是已知的,这样在windows 98上安装xp或其它更高版本的OS的时候,更高版本的OS(比如XP)就会把原有系统的所有引导扇区都统一打包到一个文件里,这样就不会出现覆盖问题。如果这种打包仍然有问题(比如第一个扇区会调用BIOS服务读取后续扇区,即使打包了,也无法改变这种动作),xp甚至会用修改已打包后的引导扇区文件。这里的关键就是,最新版本的操作系统,对原有版本的操作系统能够识别,并作出有效处理。

第二种方案的缺点是,需要文件系统的良好支持。比如你固定了某个文件的位置,而且要求该位置不能变动(除非文件被删除),这样就要求文件系统不能随便改变文件位置(或者针对操作系统文件做单独处理),否则这种方法就会失效。这显然是苛刻的,导致的结果就是,由于文件系统不能改变已有文件的位置,会导致大量的磁盘碎片产生。常用的文件系统,比如FAT、NTFS、EXT等,都不提供这种功能。因此第二种方案的应用范围非常有限。只有早期的一些操作系统会采用,目前大部分操作系统都采用第一种方案进行设计。

至此,下列一些概念或原理,您应该已经清楚:

1、         操作系统的引导扇区可能不止一个;

2、         对于FAT32/NTFS等复杂的文件系统,需要多个引导扇区才能完全容纳引导代码;

3、         可通过固定操作系统核心文件在磁盘上的位置,来确保引导代码只占一个扇区;

4、         不同厂商操作系统很难共存于同一个分区的原因。

 

那么,是否就意味着一定不能在同一个分区上安装不同生产厂家提供的操作系统呢?我认为答案是否定的,我们可以通过一些设计,来有效协调不同厂商的操作系统,在同一个分区上和谐共存。在Hello China操作系统的设计中,就采用了一种称为“预置引导法”的策略,有效规避了上述两个问题。

预置引导法的整体思路是,在操作系统安装的时候,根据实际硬盘的文件系统情况,预先读取操作系统核心模块在磁盘上的物理位置,并直接写入引导扇区。这样引导扇区在引导操作系统的时候,就无需再自行分析文件系统、确定操作系统核心文件的位置了,而只要从引导扇区中预先设定的位置中,把文件在磁盘上的物理位置找出来,加载进内存即可。可见,预置引导法有一个前提:一旦操作系统核心文件被写入硬盘,其位置也不能变动。因为核心文件在磁盘上的位置,会被写入引导扇区。如果文件的位置改变,则仍然无法引导。这显然也是苛刻的,与固定操作系统在磁盘上的位置的策略有同样限制(但这两者有根本不同,预置引导法要求操作系统核心文件在磁盘上的位置不变即可,其位置不固定,具体位置是文件被拷贝到磁盘上时确定的。而固定操作系统核心模块在磁盘特定位置的做法,则是要求系统文件一定要位于磁盘的某个固定位置,比如1024扇区开始)。

我们可以通过一些策略,来改进预置引导法,使得该方法能够避免上述局限。总体改进策略就是,在操作系统安装的时候动态生成(或动态配置)引导扇区内容,把能够固定的数据,事先写入引导扇区,避免引导扇区自行计算这些参数,从而降低引导扇区的代码量。比如,大部分引导扇区都需要计算一个cluster的大小,具体计算方法是根据每个扇区的字节数,乘以每个cluser的扇区数。显然,在操作系统安装的时候,cluster的大小就固定了。因此可直接在引导扇区中设置一个变量(cluster的尺寸),并写入cluster的尺寸值。这样引导扇区就无需计算cluster的大小,而直接引用即可。这种方法可大大减少引导扇区代码量。

下面以Hello China操作系统的引导程序为例,针对不同的文件系统,来说明预置引导法的设计思想。

预置引导法在FAT32文件系统上的实现

显然,FAT32文件系统是一个相对复杂的文件系统,一个引导扇区的空间,很难装载完整的引导代码,因为即使操作系统核心文件放在根目录下,也需要搜索整个根目录,找到操作系统文件,并加载该文件。这个过程需要两个扇区左右的代码量。但是通过预置一些变量到引导扇区,可以大大减少FAT32文件系统的引导扇区尺寸,使得能够容纳在一个引导扇区中。比如,下列是标准的引导扇区的布局:

字段名称                 字段偏移               字段长度              含义

BS_jmpBoot               0                          3                         跳转代码

BS_OEMName            3                   8                         OEM名字

BPB_BytsPerSec       11                        2                        每扇区长度(字节数)

BPB_SecPerClus       13                         1                        每cluster的扇区数

BPB_RsvdSecCnt     14                         2                         保留扇区数

BPB_NumFATs   16     16                        1                         FAT16的数量

BPB_RootEntCnt      17                        2                         有多少个根目录

BPB_TotSec16           19                        2                         FAT32已废弃

BPB_Media         21                        1                         媒体类型

BPB_FATSz16            22                        2                        FAT16文件分配表长度

BPB_SecPerTrk       24                         2                       每磁道扇区数

BPB_NumHeads      26                         2                       磁头数

BPB_HiddSec            28                         4                       隐藏扇区数

BPB_TotSec32       32                          4                      分区总扇区数

……

此后就是可执行的引导代码。

显然,这其中的很多信息是无用的,尤其是在FAT32文件系统上。比如BPB_TotSec16等变量。在配置启动扇区的时候,我们可以把这些变量省略,以腾出更多的空间来安排引导代码,使得FAT32文件系统的分析功能代码能够放到一个扇区内。下面是经过“预置”处理后的引导扇区结构:

; 3字节的跳转指令

 JMP SHORT _BOOT_CODE ; 跳转到真正的引导代码

 NOP       ; 空指令以保证字节数为3

SectorsPerCluster  DB 00 ; 每个簇的扇区数 ( 1 2 4 8 16 32 64 128 )

ReservedSectors   DW 00 ; 从卷的第一个扇区开始的保留扇区数目;

NumberOfFATs   DB   00; 卷上FAT数据结构的数目,该值通常应为2

HiddenSectors   DD   00; 包含该FAT卷的分区之前的隐藏扇区数

SectorsPerFAT32  DD 00; 对于FAT32,该字段包含一个FAT的大小

RootDirectoryStart  DD 00; 根目录的起始簇号,通常为2;

DriveNumber    DB 00 ; 用于INT 0x13的驱动器号,0x00为软盘,0x80为硬盘

此后跟着真正的可执行代码。

这样预置后,不但节约了大约20字节的空间,而且很多变量已经被预置(这些被预置的变量,称为预置变量),无需计算(比如cluster大小)。而如果按照传统的引导扇区,则需要安排专门代码计算这些变量值。这样综合下来,可节约大约60字节的空间。不要小看这60个字节,在汇编语言实现的引导扇区中,60个字节可以实现分析FAT32根目录项的功能,而这是FAT32引导扇区的核心功能。

同时,可以优化启动扇区的代码,省略一些不必要的判断。比如int13号调用功能,目前基本所有BIOS都提供这项功能,就无需判断BIOS是否支持int13调用了。同时,由于操作系统是运行在32位CPU上,可通过使用CPU的32位寄存器(比如EAX、EBX等)和32位指令增加数据处理范围,以节约代码量。

具体实现过程是,在Hello China的安装过程中,提供一个磁盘分析工具,用于读取或计算cluster的尺寸等预置变量,然后写入引导扇区。

经过上述措施后,Hello China实现了在一个引导扇区内,引导FAT32文件系统上的操作系统的功能。而通常情况下,这些功能是需要在两个以上的扇区内实现的。

而这种实现方法,是不需要操作系统核心文件在硬盘上固定位置的。虽然对某些变量做了预置,但是引导过程并没有改变,引导扇区还是首先读入根目录,在根目录中搜索操作系统核心文件。找到后再查询FAT表,找到操作系统核心文件在磁盘上的具体位置,然后依次读入。因此,即使操作系统核心文件的位置不断变化,也不会影响操作系统的加载。显然,这种“预置引导法”既克服了操作系统引导扇区过大的问题,也规避了固定操作系统核心文件位置的不利之处。

预置引导法在NTFS文件系统上的实现

相比FAT32,NTFS是一个更加复杂的文件系统。我们通过预置引导法,可以勉强将FAT32的引导代码塞到一个扇区里,但是对NTFS来说,这是绝对不可能的。在MS的windows系列操作系统中,NTFS分区的引导扇区一共用了16个(也就是说,要引导NTFS上的操作系统文件,需要8K的代码空间)。因此只能更进一步的使用预置引导法。

预置引导法最彻底的用法是,把操作系统核心文件在磁盘上的位置及分布情况,全部写入引导扇区。引导扇区不做任何文件系统相关的分析代码,直接根据写入的数据读取磁盘分区即可。比如,操作系统核心文件存储在磁盘上的布局如下:

起始扇区号    扇区数量

2048            512

4096            512

8000            256

即操作系统核心文件在磁盘上分成了三部分存储,第一和第二部分分别占用连续的512个扇区,第三部分占用连续的256个扇区。可以算出,操作系统核心文件的大小是640K。这时候可以把上面的表格,直接写入引导扇区。比如,如下是引导扇区开始部分的代码:

JMP SHORT _BOOT_CODE ; 跳转到真正的引导代码

 NOP       ; 空指令以保证字节数为3

startSectNum1    DD  00

sectorCount1      DD  00

startSectNum2    DD  00

sectorCount2     DD  00

startSectNum3    DD  00

sectorCount3      DD  00

此后紧跟真正的引导代码。

一旦操作系统在NTFS磁盘分区上安装完成,操作系统核心文件的位置就固定了(即就是上面表格中的描述)。这时候可以通过一个工具软件,读取操作系统核心文件的位置信息,然后写入引导扇区中startSectNum和sectorCount的位置处。这样真正的引导扇区代码,无需做任何NTFS文件系统分析工作,只需要根据startSectNum和sectorCount处的信息,把相应扇区读入内存即可。显然,这样的预置变量和磁盘读取代码加在一起,绝不可能超过512字节。

但这样处理的问题也很明显,就是要求操作系统核心文件在磁盘上的位置一定要固定。一旦文件系统挪动了操作系统核心文件的位置,则就无法引导。显然,对NTFS文件系统来说,这几乎是不可能的。为了充分避免碎片,NTFS可能会定期对文件系统进行扫描和碎片整理,通过移动文件在磁盘上的具体位置,把不连续的磁盘空间链接起来。

为避免由于文件位置的变动而导致的无法引导问题,我们需要更进一步,把更加位置更加稳定的内容写入引导扇区。为了找出位置更加稳定的内容,我们首先从分析NTFS文件系统原理开始。需要说明的是,NTFS文件系统内容非常庞大,在这里只对几个关键概念进行描述。详细的NTFS文件系统信息,请参考NTFS文件规范等相关资料。

NTFS文件系统中,分区上任何文件的具体位置,都是记录在MFT(主文件表)中。而MFT本身的起始位置,则是在引导扇区中存储。操作系统在处理NTFS文件系统的时候,首先从NTFS分区的引导扇区中获取MFT的位置,然后读取MFT的相关内容。对任何文件的查找,NTFS也是根据文件名等关键字段搜索MFT(实际上是从根目录开始逐级搜索),找到对应的文件记录,然后获取到文件在磁盘上的存储位置(NTFS中叫做数据运行,data run)。一旦一个文件被创建或被拷贝到磁盘上,NTFS文件系统代码就会在MFT中分配一个记录,记录该文件的相关信息。对我们来说,文件的位置信息是最关键的。一般情况下,文件记录在MFT中的位置是固定的。同时,MFT本身的位置也是固定的(虽然从理论上讲,MFT本身位置也可以不固定,但是一般NTFS文件系统的实现,MFT的位置都是固定的)。即使文件本身被移动,NTFS文件系统代码也只是修改文件的MFT记录,更确切的说,是文件记录中的数据运行属性(data run),已反映出文件在分区内的最新位置信息。

因此,从上面的分析来看,只要我们把操作系统核心文件所对应的MFT记录所在的扇区预先置入引导扇区,就可保证不出问题。假设操作系统核心文件被移动位置,这时候NTFS文件系统代码会修改对应的MFT记录,而MFT记录本身所在位置不会变化。

基于这个原理,在NTFS文件系统上的预置引导法,预先置入引导扇区的是操作系统核心文件所对应MFT记录所在的位置。这样引导扇区只要根据这个预置位置,读取操作系统文件的MFT记录,然后从记录中读出文件的数据运行(即位置信息),再分析数据运行、加载操作系统文件即可。

Hello China操作系统在NTFS文件系统上的引导程序,就是这样实现的。在Hello China的安装程序中,安装程序首先把操作系统核心文件(HCNIMGE.BIN)拷贝到NTFS分区的根目录下,然后运行一个NTFS文件系统分析工具,读出HCNIMGE.BIN文件所对应的MFT记录在磁盘上的扇区号,再把这个扇区号写入引导扇区的预置变量中。这样引导扇区在引导操作系统的时候,只需要根据预置的磁盘扇区编号,读入HCNIMGE.BIN对应的文件记录,然后根据文件记录找到数据运行,分析数据运行,并读取即可。

即使如此,在512字节的引导扇区中实现NTFS文件系统的引导程序,也有点困难。主要是数据运行的解码程序有点复杂,占用了大部分的代码空间。

对Hello China引导程序实现代码的说明

Hello China操作系统V1.69版中针对FAT32和NTFS文件系统的引导程序,都是通过预置引导法实现的。可通过阅读引导程序的源代码,获得对本文更进一步的理解。所有代码(包括Hello China操作系统核心模块代码)都可以通过下列链接下载:

 

其中,与引导程序相关的源文件说明如下:

1、         FAT32和NTFS文件系统的引导扇区代码(汇编语言编写),存放在sysinit目录下。HDBS.ASM是针对FAT32文件系统的引导扇区代码,NTFSBS.ASM则是NTFS的引导扇区代码;

2、         Dumpf32目录下,存放了FAT32文件系统引导扇区的修改程序。该程序读取安装分区的相关信息,然后写入引导扇区程序;

3、         MKNTFSBS目录下,存放了NTFS文件系统下引导扇区的修改工具。该工具分析Hello China安装分区的根目录,找到HCNIMGE.BIN(操作系统核心模块)所对应文件记录的磁盘扇区编号,并写入引导扇区。同时写入的还有其它预置变量,比如cluster大小等。

如有任何相关问题,可与 何问起 联系讨论。