硬盘结构

            硬盘主引导扇区是一个敏感的区域, 它的安全与否直接决定硬盘是否能够正常使用。 深入认识和灵活使用硬盘主引导扇区将有助于你的系统维护和许多特殊工作完成。
一、与DOS 引导扇区的区别
  对于DOS系统来说, 有两种不同的引导扇区,即DOS 引导扇区和硬盘主引导扇区。 DOS 引导扇区存在于软盘的第一逻辑扇区或硬盘DOS分区的第一逻辑扇区  
,是用FORMAT命令对磁盘格式化时产生的, 是引导DOS 系统或正确使用磁盘的必要条件,在DOS下可用DEBUG方便地读出:
C>DEBUG
-L 100 2 0 1
;读C盘0扇区到内存当前段的100H处
-D ;显示DOS 引导扇区内容
  硬盘主引导扇区则指的是硬盘的物理地址0 面0 道1 扇区,是用FDISK 进行硬盘分区时产生的, 它属于整个硬盘而不属于某个独立的DOS 分区, 是硬盘正确引导和使用的必要条件。由于它不在DOS分区范围之内,所以无法用上述方法读出, 只有用相关的汇编程序代码读出:
C>DEBUG
-A
XXXX:0100 MOV AX,0201H ;指定扇区数
XXXX:0103 MOV BX,0800H ;指定内存地址
XXXX:0106 MOV CX,0001H ;指定磁道和扇区号
XXXX:0109 MOV DX,0080H ;指定磁头和驱动器号
XXXX:010C INT 13H ;读磁盘操作
XXXX:010E INT 3-d800 ;显示读出内容
二、扇区结构
  硬盘主引导扇区占据一个扇区,共512(200H)个字节,具体结构如下:
1.硬盘主引导程序,位于该扇区的0-1BDH处;
2.硬盘分区表,位于1BEH-1FDH处,每个分区表占用16个字节,共4个分区表,16个字节各字节意义如下:
0:自举标志,80H为可引导分区,00为不可引导分区;
1~3:本分区在硬盘上的开始物理地址;
4:分区类型,其中1表示为12位FAT表的基本DOS分区;4为16位FAT表的基本DOS分区;5为扩展DOS 分区;6为大于32M的DOS分区;其它为非DOS分区。
5~7:本分区的结束地址;
8~11:该分区之前的扇区数,即此分区第一扇区的绝对扇区号;
12~15:该分区占用的总扇区数。
3.引导扇区的有效标志,位于1FEH-1FFH处,固定值为AA55H。
三、硬盘主引导扇区的作用
硬盘主引导扇区在各个DOS版本下其内容基本一致,主要完成的任务是:
1.存放硬盘分区表,这是硬盘正确读写的关键数据。
2.检查硬盘分区的正确性,要求只能且必须存在一个活动分区。
3.确定活动分区号,并读出相应操作系统的引导记录。
4.检查操作系统引导记录的正确性, DOS引导扇区末尾也存在着一个AA55H标志,供引导程序识别。
5.释放引导权给相应的操作系统。例如,当确认DOS 操作系统引导记录存在时, 则调出DOS引导程序并执行。
另外,当它发现引导故障时将给出部分提示信息,如:
Invalid partition table?表示硬盘分区表错误, 没有或存在两个以上活动分区;
Error loading operating system?表示读DOS引导记录时出错;
Missing operating system?表示 DOS引导记录无有效标志AA55H。
四、硬盘主引导扇区的应用
  正是硬盘主引导扇区直接决定硬盘的安全性, 所以利用它可以完成很多特殊的功能操作, 简单列举如下:
1.清除硬盘引导功能。
  由于硬盘引导必须使用引导程序, 并检测活动分区的正确性, 所以人为的修改或破坏引导程序部分, 或者清除活动分区引导标志, 都将使硬盘无法启动。
2.加密整个硬盘。
  硬盘主引导扇区末尾的扇区有效标志AA55H是系统承认硬盘的前提,所以可以采取清除名修改此标志位达到加密硬盘的目的, 即使从A 驱引导系统也无法对硬盘进行操作, 恢复AA55H即可解密硬盘。
3.加密单个硬盘分区。
  硬盘单个分区的加密可采取修改分区类型的方法,比如把扩展DOS 分区的类型标志 05H改为FFH,则DOS 认为此分区为非DOS分区,无法对其进行访问, 包括此分区中的所有逻辑盘。当然修改或清除某一分区表的所有数据同样具有加密单个分区的作用, 但操作繁琐并且具有危险性。
4.加入硬盘启动口令识别。
  通过修改硬盘的主引导程序, 在引导DOS 操作系统之前,加入一段口令识别程序段,如口令正确则正常引导系统,否则拒绝引导,达到口令识别的目的。
5.先于DOS 驻留内存程序。
  在主引导程序中安装某些中断服务程序,如时钟中断等,通过对INT 21H或其它DOS关键数据的监视,完成病毒的实时检测功能,因为此方法在引导DOS系统之前完成,所以其监视效果非常可靠。
6.实现同一硬盘多个操作系统的选择启动。
硬盘可以分成4个独立的分区,装入4个不同的操作系统,通过特殊的方法可以共享多个DOS版本,但各操作系统或各DOS版本间的切换是一件非常麻烦的事,通过修改硬盘主引导程序加入按键识别过程,可实现四个分区的自由选择引导。
7.实现硬盘主引导扇区或DOS引导扇区的自我修复。
  如果在硬盘其它空闲扇区保留一份完好的主引导扇区内容,而在主引导程序中每次启动前进行主引导扇区的正确性检查工作,当发现异常时,即调入原来完好的主引导扇区内容,就可以及时发现和清除病毒,对于系统有很好的保护作用。

硬盘主引导扇区(MBS)结构,代码已注释
我们经常遇到各种各样的硬盘故障,其中有相当部分是硬盘软故障,如有些朋友在安装Linux后,发现无法安装Windows等,但很多朋友由于在对硬盘的逻辑结构不是很了解,无法判断合解决该类问题。
为了普及这些知识,增强大家的兴趣和做试验成功后的成就感,本人以提问的形式给大家展现这方面的知识,同时也提醒大家在实做时先用一个多余而且无重要数据的硬盘做试验,免得造成不必要的损失。另外,对于汇编不了解但有一定计算机基础的朋友,建议自己查找资料进一步学习,也可以记下本文中的代码,实做中灵活应用。
问题:我们在安装所有版本的Windows时,一般不管使用Win 9X的Fdisk命令对硬盘进行分区,还是由安装程序进行分区,基本上都只能分一个主分区和一个扩展分区,扩展分区里面又分若干逻辑分区,很少人尝试过分多个主分区或多个扩展分区,今天有空出下面问题,随便做了个试验(Linux下做直接读Linux分区的文件试验导致硬盘Linux彻底被破坏,干脆。。。),结果如下:10G硬盘分为了3个主分区,而且还可以从任何一个主分区启动,也就是说,3个主分区装了3个操作系统。
问题:
(1)在只有基本的DOS情况下是如何做到的?(除了DOS,不允许用其它任何软件)
(2)一块硬盘最多可分为几个主分区和几个扩展分区?
目的:通过讨论,让大家
(1)深刻理解硬盘0面0道1扇区的MBR+DPT+BRI结构;
(2)掌握手动修改MBR和DPT的手段,具备手动备份和还原硬盘0面0道1扇区的能力;
(3)了解计算机从硬盘启动的过程,了解编写多重启动程序的基本方法;
(4)为将来学习其它操作系统打下良好的基础。
答案:(由于编辑窗口太小,可能有不少错误,也已修改不少,剩下的请指出)
关键词:
MBS- Master Boot Sector 主引导扇区
MBR-Master Boot Record 主引导记录
DPT-Disk Partition Table 硬盘分区表
BRI-Boot Record ID    引导记录标志
CHS-(Cylinder柱面,也就是磁道 编号0-m /Head 头,编号0-n /Sector 扇区 编号1-t)参数。
一、 硬盘结构和逻辑编号
(1)硬盘物理结构
传统硬盘由多个双面磁碟组成,每个面都有一个读写磁头,磁头编号从0开始,所谓0面就是指0磁头所对应的面;每个面被划为若干磁道,编号从负数开始,磁道数越小,越靠近磁碟边缘,因为线速度越大,所以读写速度也越快;用户只能使用0道以后的磁道,负磁道为硬盘所带的微处理器使用的一些代码(Fireware)和本硬盘一些重要参数存放的地方;每个磁道又分为若干扇区(每个磁道扇区数量都一样),扇区的编号从1开始(不是从0开始哟!),每个扇区存放536(这个数记不清楚了,呵呵)多个字节,但共用户使用的只有512个字节,剩下的作为校验(CRC)和其它用途。这就是著名的硬盘寻址CHS(Cylinder柱面,也就是磁道 编号0-m /Head 头,编号0-n /Sector 扇区 编号1-t)参数。
对于CHS中参数中
Cylinder柱,也就是磁道,用10个二进制数表示,所以最大为1024
Head 头,用一个字节表示,最大为256个磁头
Sector 扇区,用6为二进制数表示,所以最大为 64-1(不能用0呀)=63
所以使用CHS表示的硬盘最大容量为
1024X256X63X512=8455716864字节=8064M容量,这就是8G容量的由来。
明显看出,外道比内道长,被划分为同样扇区数是非常浪费的。现代磁盘基本上也只有2个左右的磁碟,4个面左右,每个磁道上的扇区数量都不相同,一般使用LBA表示方法来表示每个扇区,所谓LBA指每个扇区都有一个编号,从0开始(负编号不给用户使用),为了与CHS方式兼容,硬盘内部代码使用了一种CHS-LBA映射的方式。

(2)硬盘逻辑编号
当一台计算机挂多个IDE硬盘时,Linux/Unix对硬盘的编号最为科学。它是这样处理的
hda—第一个IDE口主硬盘,
hdb—第一个IDE口从硬盘,
hdc—第二个IDE口主硬盘,
hdd—第二个IDE口从硬盘,
但对于BIOS,DOS和Windows,处理方式有点不一样,只要掌握下面原则就可以了
(1) 上面4硬盘是连续编号,从小到大,光驱不算
(2) 作为启动的硬盘编号最小,为0x80(16进制数)
如第一个IDE口,主挂硬盘,从挂光驱,第二个ide口挂2个硬盘,BIOS设置从第二个主硬盘启动,则它们的编号为:
第二个IDE主硬盘为0x80,第一个IDE主硬盘为0x81,第二个IDE从硬盘为0x82
又如第一个IDE口主空,从挂硬盘,第二个IDE口主挂光驱,从挂硬盘,BIOS设置从第一个从硬盘启动,则它们的编号为:
第一个IDE从硬盘为0x80,第二个IDE从硬盘为0x81
二、 硬盘分区规范和制作多重启动程序的方法

所谓对硬盘分区,直观意义上理解,是逻辑上把硬盘分为几个块。本来就象西瓜一样,你爱怎么切就怎么切,如在CHS参数方式下,你完全可以把0面全部扇区当成一个区。为了能保证各个操作系统的一致,所以制定了一个硬盘分区规范,如果你不按这个规范做,硬盘肯定只能被你自己开发的操作系统使用。
这个规范规定:
(1) CHS参数中0面0道1扇区为硬盘分区信息和引导代码扇区(Master Boot Sector MBS),也就是LBA=0的扇区;
(2) 分区是按空心圆柱形(蛋卷形状)划分,如图所示
由于0面0道1扇区(MBS)保存启动代码和硬盘分区信息,如果这个扇区物理损坏,这个硬盘也就无法进行分区,导致硬盘无法使用。但是对于现代硬盘,由于它内部使用的是映射机制,完全可以把个好的扇区映射过来,修复硬盘。很多硬盘修复软件可以做到这点,比较有名的是MHDD和PC3000
对于这个重要扇区(512个字节)的规范为:
MBR—Master Boot Record,主引导记录,共446个字节。规范并没有规定代码是什么,很多软件公司都有自己的MBR,如MS的MBR,Linux的Grub或Lilo,DM的等。我们常用的DOS下的Fdisk /mbr其实就是使用MS的MBR覆盖这446个字节,Fdisk程序内部本身包含这段代码,有兴趣可以把Fdisk.EXE改名为Fdisk.Txt,再用记事本打开,可以看到如下信息Invalid partition table.Error loading operating system.Missing operating system。
MS的这段代码的功能是查找引导分区信息或者叫活动分区(在MBR后面),如果没有或为2个以上,则显示以上信息,系统引导失败;否则再按引导分区项读对应引导扇区,判断结尾是否为55AA,是的话把CPU的控制权交给引导扇区对应的代码;否则引导失败。
当然我们也可以编写自己的MBR,做多重启动,这个大家先反汇编MS的MBR,认真研究以后就不难了,呵呵。
对于这个MBR,MS非常霸道,如果你安装了Linux的Grub,你就别想在这个硬盘上安装Windows,这个问题在TPY BBS里面出现过多次(本人也回答过多次,对于一些人动不动就叫别人对硬盘低级格式化的做法有点反感),最快的解决方法是:Fdisk /mbr,当然如果你的硬盘东西都不要的话,可以往MBS里面写一堆垃圾,破坏后面要说的BRI,让Windows安装程序认为MBS非法,然后在安装程序里面重新分区就可以了
DPT—Disk Partition Table 硬盘分区表,这是硬盘最重要的信息,这种信息被破坏,也就不知道硬盘是怎么分区的了,不过现在有些软件通过搜索可以找回分区信息,如easyrecovery.
DPT共64个字节,分为4项,每项16个字节对应一个分区。
分区规范规定:一个硬盘可以有多个主分区(Primary Partition),但最多只能有一个扩展分区(Extended Partition),一个扩展分区可以划分为多个逻辑分区,所以一个硬盘最多只能划为4个主分区或者3个主分区+一个扩展分区。
MS真懒,它的OS最多只让我们划一个主分区+一个扩展分区,其它OS没这个问题。
每个分区项的结构如下:
偏移 内容 大小
00h 0x80表示活动分区,00不活动 1BYTE,由于这个字节为MBR代码所识别,我们完全可以编写自己的MBR,不理会该字节内容,启动时选择所要启动的分区。甚至设置全部的分区为活动分区都可以。无论为怎么样填写,作为从盘,都能被操作系统所识别
01h 分区开始磁头编号(面号) 1BYTE
02h低6位 分区开始扇区号 6位二进制数
02h高2位和03h 分区开始的柱面数,也叫道编号 10位二进制数
04h 分区类型 1Byte,标识这个分区的类型,如果我们把这个直接内容修改了,会使得操作系统不能认出这个分区,间接保护了这个分区的资料,当然我们也可以往MBS写一堆垃圾来保护整个硬盘资料,当我们自己要用时,就恢复MBS
05h 分区结束磁头编号 1Byte
06h 分区结束的柱面和扇区,结构同上 2byte
08h 该分区第一扇区到MBS的总扇区数量 4Byte
0Ch 该分区的总扇区数量 4Byte
分区类型:
00h   未知类型或不用
01h   12bit Fat
04h    16bit fat
05h    扩展MS_DOS分区
0Bh    Fat32 容量最大2G
0Ch    Fat32 ,采用LBA模式,调用int13h扩展中断
0Fh    扩展MS_DOS分区,Fat32 ,采用LBA模式,调用int13h扩展中断
07h    NTFS
82h    Linux
83h    Linux Swap
BRI――Boot Record ID 引导记录标志 接在DPT后面的最后2个字节为 55 AA,表示这个扇区是个正常的计算机启动时,BIOS把这个扇区读入内存,发现BRI不是55 AA,则会拒绝启动。
如下面一个MBS内容
0FA2:0200   33 C0 8E D0 BC 00 7C FB-50 07 50 1F FC BE 1B 7C    3.....|.P.P....|
0FA2:0210   BF 1B 06 50 57 B9 E5 01-F3 A4 CB BE BE 07 B1 04    ...PW...........
0FA2:0220   38 2C 7C 09 75 15 83 C6-10 E2 F5 CD 18 8B 14 8B    8,|.u...........
0FA2:0230   EE 83 C6 10 49 74 16 38-2C 74 F6 BE 10 07 4E AC    ....It.8,t....N.
0FA2:0240   3C 00 74 FA BB 07 00 B4-0E CD 10 EB F2 89 46 25    .}U
0FA2:02B0   AA 74 5A 83 EF 05 7F DA-85 F6 75 83 BE 27 07 EB    .tZ.......u..'..
0FA2:02C0   8A 98 91 52 99 03 46 08-13 56 0A E8 12 00 5A EB    ...R..F..V....Z.
0FA2:02D0   D5 4F 74 E4 33 C0 CD 13-EB B8 00 00 80 58 30 17    .Ot.3........X0.
0FA2:02E0   56 33 F6 56 56 52 50 06-53 51 BE 10 00 56 8B F4    V3.VVRP.SQ...V..
0FA2:02F0   50 52 B8 00 42 8A 56 24-CD 13 5A 58 8D 64 10 72    PR..B.V$..ZX.d.r
0FA2:0300   0A 40 75 01 42 80 C7 02-E2 F7 F8 5E C3 EB 74 49   
[email protected]......^..tI
0FA2:0310   6E 76 61 6C 69 64 20 70-61 72 74 69 74 69 6F 6E    nvalid partition
0FA2:0320   20 74 61 62 6C 65 00 45-72 72 6F 72 20 6C 6F 61     table.Error loa
0FA2:0330   64 69 6E 67 20 6F 70 65-72 61 74 69 6E 67 20 73    ding operating s
0FA2:0340   79 73 74 65 6D 00 4D 69-73 73 69 6E 67 20 6F 70    ystem.Missing op
0FA2:0350   65 72 61 74 69 6E 67 20-73 79 73 74 65 6D 00 00    erating system..
0FA2:0360   00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00    ................
0FA2:0370   00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00    ................
0FA2:0380   00 00 00 8B FC 1E 57 8B-F5 CB 00 00 00 00 00 00    ......W.........
0FA2:0390   00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00    ................
0FA2:03A0   00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00    ................
0FA2:03B0   00 00 00 00 00 00 00 00-00 00 00 00 00 00
以上是MBR                                                    
0FA2:03C0   01 00 0B FE 7F 7E 3F 00-00 00 80 E2 5D 00 00 00    80 01    ................
0FA2:03D0   41 7F 05 FE FF 0F BF E2-5D 00 51 4C 62 00 00 00    .....~?.....]...
0FA2:03E0   00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00    A.......].QLb...
0FA2:03F0   00 00 00 00 00 00 00 00-00 00 00 00 00 00          ................
以上是DPT
最后这个是BRI了,呵呵                                          55 AA    ..............U.
共2个分区,一个主分区(分区类型为0B)+一个扩展分区(分区类型为05)
第一个分区信息
80 01 01 00 0B FE 7F 7E 3F 00-00 00 80 E2 5D 00
80-这是一个活动分区
01-分区起始磁头号为1,也就是0头0道除了MBS使用一个扇区以外其它没有使用,我们可以在那里保存MBS内容(备份呀),也可以放代码,因为446个字节也许不够我们用,呵呵
01 00 =0000001 00000000,分区开始扇区数为000001=1,开始磁道数为0000000000=0
0B-- Fat32主分区
FE--分区结束磁头数FE= 254,可以看出在CHS模式下,该硬盘有255个磁头
7F 7E=0111 1111 0111 1110,分区结束扇区数11 1111(b)=63
分区结束磁道数01 0111 1110=382
3F 00-00 00-分区前面的扇区数为0000003F=63,刚好是0道所占的扇区数
80 E2 5D 00-分区的总扇区数为005DE280=6152832, 6152832X512/(1024X1024)= 3004.3125M=3G,完全正确!
三、 使用BIOS直接对硬盘操作方法
(1) BIOS中断int 13
BIOS已经为我们准备了读写磁盘的代码,这就是Int 13(13h号中断),但很多操作系统在启动完成后都不使用这些代码,而使用扩展的LBA访问模式(驱动程序所带的代码),以突破8G容量的限制和实现DMA访问模式。另外在Winnt以上版本OS,由于MBS是重要的信息区,系统禁止用户对MBS进行读写操作,全部的防病毒软件也对该扇区进行了保护。
所以只有DOS和Win 9X才能使用int 13h访问MBS
调用int 13h的入口参数为
ah=2 读磁盘   =3 写磁盘
入口参数:AH=功能号,02为读盘操作;03为写磁盘;AL=一次读取的扇区数
;           ES:BX=读入内存的起始地址
;           CH=10位柱面号的低8位;CL:高两位是10位柱面号的高两位,低6位是扇区号
;           DH=磁头号;
DL=驱动器号,00代表第一个软驱;对于硬盘是硬盘编号,0x80为第一个硬盘,也就是系统启动的硬盘
主引导扇区代码(MBR)
Q:主引导扇区代码(MBR)
A:;====================================================================
;
; FlyingDragon MBR ( Master Boot Record )
;
; Author : Jack
; History:
; 0.01 - 2005-08-13 19:34 采用传统的CHS磁盘调用
; 0.02 - 2005-08-23 19:44 优先采用扩展磁盘调用
;
; Build : nasm -f bin MBR.ASM -oMBR.BIN
;
;====================================================================================
;
; MBR( Master Boot Record )主引导记录包含两部分的内容,前446字节为启动代码及数据,而
; 从446(0x1BE)开始则是分区表,分区表由四个分区项组成,每个分区项数据为16字节,记录了
; 启动时需要的分区参数。
;
; 在CPU上电之后,若由硬盘启动,则BIOS将硬盘的主引导记录(位于0柱面、0磁道、1扇区)读
; 入7C00处,然后将控制权交给主引导代码。主引导代码的任务包括:
; (1) 扫描分区表,找到一个激活(可引导)分区;
; (2) 找到激活分区的起始扇区;
; (3) 将激活分区的引导扇区装载到内存7C00处;
; (4) 将控制权交给引导扇区代码;
;
; 如果主引导代码无法完成上述任务,它将显示以下错误信息之一:
; No active partition.
; Invalid partition table.
; Error loading operating system.
; Missing operating system.
;
;====================================================================================
; FAT16分区尺寸与LBA
;====================================================================================
; LBA   HeadsPerCylinder SectorsPerTrack Maximum Size for Boot Partition
; Disabled 64     32     1GB
; Enabled 255     63     4GB
;
; 为了适应超过8G的硬盘,Windows2000忽略了Start CHS和End CHS,而使用StartLBA和TotalSector
; 来确定分区在整个磁盘中的位置和大小。
;
;====================================================================================
;     分区表项结构(16字节)
;====================================================================================
;
; typedef struct _PARTITION_ENTRY
; {
; UCHAR BootIndicator; // 能否启动标志
; UCHAR StartHead;   // 该分区起始磁头号
此信息出自广州北大青鸟:http://www.gz-benet.com.cn
UCHAR StartSector; // 起始柱面号高2位:6位起始扇区号
; UCHAR StartCylinder; // 起始柱面号低8位
; UCHAR PartitionType; // 分区类型
; UCHAR EndHead;   // 该分区终止磁头号
; UCHAR EndSector;   // 终止柱面号高2位:6位终止扇区号
; UCHAR EndCylinder; // 终止柱面号低8位
; ULONG StartLBA;   // 起始扇区号
; ULONG TotalSector; // 分区尺寸(总扇区数)
; }PARTITION_ENTRY,*PPARTITION_ENTRY;
;
;====================================================================================
;    主引导记录(MBR)结构
;====================================================================================
; typedef struct _MASTER_BOOT_RECORD
; {
; UCHAR    BootCode[446];
; PARTITION_ENTRY Partition[4];
; USHORT    Signature;
; }MASTER_BOOT_RECORD,*PMASTER_BOOT_RECORD;
;
;====================================================================================
BITS   16   ; 生成16位代码而不是32位代码
SECTION .text   ; 代码段
ORG   0600H ; 指定程序被装入内存的起始位置
;====================================================================
;
; 宏和常量定义
;
;====================================================================
?     EQU 0 ; NASM不支持DW ?这样的语法,可以使用这样的定义
        ; 模拟,以使代码的可读性更强
ACTIVE_FLAG EQU 80H ; 激活(可引导)分区标志
NOT_ACTIVE_FLAG EQU 00H ; 不激活标志
MBR_MOVE_ADDR EQU 0600H ; MBR先移动自身到该位置然后再运行
BOOT_SIGNATURE EQU 0AA55H ; 启动标志
SEC_SIG_OFF EQU 01FEH ; 启动扇区的标志位置
;====================================================================
; 分区表项结构偏移
;====================================================================
BootIndicator EQU 0 ; 能否启动标志
StartHead EQU 1 ; 该分区起始磁头号
StartSector& EQU 2 ; 起始柱面号高2位:6位起始扇区号
StartCylinder EQU 3 ; 起始柱面号低8位
PartitionType EQU 4 ; 分区类型
EndHead   EQU 5 ; 该分区终止磁头号
EndSector EQU 6 ; 终止柱面号高2位:6位终止扇区号
EndCylinder EQU 7 ; 终止柱面号低8位
StartLBA EQU 8 ; 起始扇区号
TotalSector EQU 12 ; 分区尺寸(总扇区数)
;====================================================================
; 常用的分区类型
;====================================================================
PARTITION_TYPE_EMPTY EQU 00H ; 空分区
PARTITION_TYPE_FAT12 EQU 01H ; FAT12 ( 〈 32680 sectors )
PARTITION_TYPE_FAT16 EQU 04H ; FAT16 ( 32680 - 65535 sectors )
PARTITION_TYPE_EXTENDED EQU 05H ; DOS EXTENDED
PARTITION_TYPE_BIGDOS_FAT16 EQU 06H ; FAT16 ( 33MB - 4GB )
PARTITION_TYPE_NTFS   EQU 07H ; NTFS
PARTITION_TYPE_FAT32 EQU 0BH ; FAT32
PARTITION_TYPE_FAT32_LBA EQU 0CH ; FAT32 LBA
PARTITION_TYPE_FAT16_LBA EQU 0EH ; FAT16 LBA
PARTITION_TYPE_EXTENDED_LBA EQU 0FH ; LBA EXTENDED
PARTITION_TYPE_DYNAMIC_DISK EQU 42H ; Dynamic Disk Volume
;====================================================================
; 主引导记录的入口
;====================================================================
_ENTRY_POINT:
; 初始化相关寄存器及标志位
CLI      ; 先关掉中断
CLD      ; 方向为向前递增
XOR AX,AX   ; AX = 0
MOV DS,AX   ; 设置数据段寄存器 DS:SI
MOV ES,AX   ; 设置附加段寄存器 ES:DI
MOV SS,AX   ; 设置堆栈段寄存器
MOV BP,7C00H ; 设置基址寄存器
MOV S
P,BP   ; 设置堆栈栈顶
; 将MBR代码移动到0600H处
MOV SI,BP   ; SI = 7C00H
MOV DI,MBR_MOVE_ADDR; DI = 0600H
MOV CX,512   ; 待移动的字节数
REP MOVSB
JMP 0:.RealStart
; 真正开始
.RealStart:
; 保存引导驱动器号
MOV BYTE [ DriveNumber ] , DL
;====================================================================
; 检查是否支持磁盘中断INT 13H的扩展
;====================================================================
MOV AH,41H
MOV BX,055AAH
INT 13H
JC .LookupActive   ; 如果失败,进位标志为1
MOV BYTE[DiskExtension],01H ; 设置支持磁盘扩展标志
.LookupActive:
; 查找激活分区
MOV BP,PartitionTable   ; 指向分区表
MOV BL,4      ; 最多4个分区
;检查激活分区
.CheckNext:
CMP BYTE [BP+BootIndicator],ACTIVE_FLAG ; 检查该分区是否激活
JZ .FoundActive       ; 找到激活分区
CMP BYTE [BP+BootIndicator],NOT_ACTIVE_FLAG ; 检查该分区是否激活
JNZ .InvalidTable       ; 无效值
ADD BP,10H         ; 指向下一个分区表项
DEC BL
JZ .NoActive        ; 没有找到激活分区
JMP .CheckNext
;找到了激活分区
.FoundActive:
; 保存分区表项
MOV AL,4
SUB AL,BL      ; AL = 4-BL = 第一个激活分区表项索引(0-3)
MOV BYTE [ActivePartition],AL ; 保存激活分区表项索引
MOV DI,BP      ; DI = 激活分区项
MOV DH,BYTE[BP+StartHead] ; 该分区起始磁头号
MOV CL,BYTE[BP+StartSector] ; 起始柱面号高2位:6位起始扇区号
MOV CH,BYTE[BP+StartCylinder] ; 起始柱面号低8位
; 保存起始扇区号
MOV AX,WORD[BP+StartLBA+2]
MOV WORD[DAP_SECTOR_LOW+2],AX
MOV AX,WORD[BP+StartLBA]
MOV WORD[DAP_SECTOR_LOW],AX
; 检查确信只有一个激活分区
.Recheck:
ADD BP,10H      ; 指向下一个分区项
DEC BL
JZ .LoadBootSector    ; 装载该分区的引导扇区
CMP BYTE [BP+BootIndicator],NOT_ACTIVE_FLAG ; 检查该分区是否激活
JNZ .InvalidTable    ; 无效值
JMP .Recheck
; 装载激活分区的引导扇区
.LoadBootSector:
; 设置驱动器号
MOV DL,BYTE [DriveNumber]
; 检查是否支持扩展磁盘调用
CMP BYTE [DiskExtension],01H
JNZ .NoDiskExtension
; 使用扩展磁盘调用读取引导扇区
;
; INT 13H
; AH = 42H
; DL = Drive Number
; DS:SI = 指向磁盘地址包的指针
;
MOV SI,DAP_PACKET_SIZE
MOV AH,42H
INT 13H
JC .ErrorLoadOS
JMP .CheckBootSector
.NoDiskExtension:
;====================================================================
;
; INT 13H
; AH = 2        柱面号:0 - 1023
; AL = 要读取的扇区数     磁头号:0 - 255
; CH = 柱面号低8位     扇区号:1 - 63
; CL = 柱面号高2位 : 6位扇区号
; DH = 磁头号
; DL = 驱动器号
; ES:BX = 缓冲区

你可能感兴趣的:(硬件,dos,byte,扩展,磁盘,ide,活动)