int 13.docx
《int 13.docx》由会员分享,可在线阅读,更多相关《int 13.docx(12页珍藏版)》请在冰豆网上搜索。
int13
第一部分简介
一.硬盘结构简介
1.硬盘参数释疑
到目前为止,人们常说的硬盘参数还是古老的CHS(Cylinder/
Head/Sector)参数.那么为什么要使用这些参数,它们的意义是什么?
它们的取值范围是什么?
很久以前,硬盘的容量还非常小的时候,人们采用与软盘类似的结
构生产硬盘.也就是硬盘盘片的每一条磁道都具有相同的扇区数.由此
产生了所谓的3D参数(DiskGeometry).既磁头数(Heads),柱面数
(Cylinders),扇区数(Sectors),以及相应的寻址方式.
其中:
磁头数(Heads)表示硬盘总共有几个磁头,也就是有几面盘片,最大
为255(用8个二进制位存储);
柱面数(Cylinders)表示硬盘每一面盘片上有几条磁道,最大为1023
(用10个二进制位存储);
扇区数(Sectors)表示每一条磁道上有几个扇区,最大为63(用6
个二进制位存储).
每个扇区一般是512个字节,理论上讲这不是必须的,但好象没有取
别的值的.
所以磁盘最大容量为:
255*1023*63*512/1048576=8024MB(1M=1048576Bytes)
或硬盘厂商常用的单位:
255*1023*63*512/1000000=8414MB(1M=1000000Bytes)
在CHS寻址方式中,磁头,柱面,扇区的取值范围分别为0到Heads-1,
0到Cylinders-1,1到Sectors(注意是从1开始).
2.基本Int13H调用简介
BIOSInt13H调用是BIOS提供的磁盘基本输入输出中断调用,它可以
完成磁盘(包括硬盘和软盘)的复位,读写,校验,定位,诊断,格式化等功能.
它使用的就是CHS寻址方式,因此最大识能访问8GB左右的硬盘(本文中
如不作特殊说明,均以1M=1048576字节为单位).
3.现代硬盘结构简介
在老式硬盘中,由于每个磁道的扇区数相等,所以外道的记录密度要远低
于内道,因此会浪费很多磁盘空间(与软盘一样).为了解决这一问题,进一
步提高硬盘容量,人们改用等密度结构生产硬盘.也就是说,外圈磁道的扇区
比内圈磁道多.采用这种结构后,硬盘不再具有实际的3D参数,寻址方式也改
为线性寻址,即以扇区为单位进行寻址.
为了与使用3D寻址的老软件兼容(如使用BIOSInt13H接口的软件),在硬
盘控制器内部安装了一个地址翻译器,由它负责将老式3D参数翻译成新的线性
参数.这也是为什么现在硬盘的3D参数可以有多种选择的原因(不同的工作模
式,对应不同的3D参数,如LBA,LARGE,NORMAL).
4.扩展Int13H简介
虽然现代硬盘都已经采用了线性寻址,但是由于基本Int13H的制约,使
用BIOSInt13H接口的程序,如DOS等还只能访问8G以内的硬盘空间.
为了打破这一限制,Microsoft等几家公司制定了扩展Int13H标准
(ExtendedInt13H),采用线性寻址方式存取硬盘,所以突破了8G的限制,
而且还加入了对可拆卸介质(如活动硬盘)的支持.
二.BootSector结构简介
1.BootSector的组成
BootSector也就是硬盘的第一个扇区,它由MBR(MasterBootRecord),
DPT(DiskPartitionTable)和BootRecordID三部分组成.
MBR又称作主引导记录占用BootSector的前446个字节(0to0x1BD),
存放系统主引导程序(它负责从活动分区中装载并运行系统引导程序).
DPT即主分区表占用64个字节(0x1BEto0x1FD),记录了磁盘的基本分区
信息.主分区表分为四个分区项,每项16字节,分别记录了每个主分区的信息
(因此最多可以有四个主分区).
BootRecordID即引导区标记占用两个字节(0x1FEand0x1FF),对于合法
引导区,它等于0xAA55,这是判别引导区是否合法的标志.
BootSector的具体结构如下图所示(参见NightOwl大侠的文章):
0000|------------------------------------------------|
|MasterBootRecord|
||
||
|主引导记录(446字节)|
||
01BD||
01BE|------------------------------------------------|
||
01CD|分区信息1(16字节)|
01CE|------------------------------------------------|
||
01DD|分区信息2(16字节)|
01DE|------------------------------------------------|
||
01ED|分区信息3(16字节)|
01EE|------------------------------------------------|
||
01FD|分区信息4(16字节)|
|------------------------------------------------|
|01FE|01FF|
|55|AA|
|------------------------------------------------|
2.分区表结构简介
分区表由四个分区项构成,每一项的结构如下:
BYTEState:
分区状态,0=未激活,0x80=激活(注意此项)
BYTEStartHead:
分区起始磁头号
WORDStartSC:
分区起始扇区和柱面号,底字节的低6位为扇区号,
高2位为柱面号的第9,10位,高字节为柱面号的低8位
BYTEType:
分区类型,如0x0B=FAT32,0x83=Linux等,
00表示此项未用
BYTEEndHead:
分区结束磁头号
WORDEndSC:
分区结束扇区和柱面号,定义同前
DWORDRelative:
在线性寻址方式下的分区相对扇区地址
(对于基本分区即为绝对地址)
DWORDSectors:
分区大小(总扇区数)
注意:
在DOS/Windows系统下,基本分区必须以柱面为单位划分
(Sectors*Heads个扇区),如对于CHS为764/255/63的硬盘,分区的
最小尺寸为255*63*512/1048576=7.844MB.
3.扩展分区简介
由于主分区表中只能分四个分区,无法满足需求,因此设计了一种扩展
分区格式.基本上说,扩展分区的信息是以链表形式存放的,但也有一些特
别的地方.
首先,主分区表中要有一个基本扩展分区项,所有扩展分区都隶属于它,
也就是说其他所有扩展分区的空间都必须包括在这个基本扩展分区中.对于
DOS/Windows来说,扩展分区的类型为0x05或0x0F(>8GB).
除基本扩展分区以外的其他所有扩展分区则以链表的形式级联存放,后
一个扩展分区的数据项记录在前一个扩展分区的分区表中,但两个扩展分区
的空间并不重叠.
扩展分区类似于一个完整的硬盘,必须进一步分区才能使用.但每个扩
展分区中只能存在一个其他分区.此分区在DOS/Windows环境中即为逻辑盘.
因此每一个扩展分区的分区表(同样存储在扩展分区的第一个扇区中)中最多
只能有两个分区数据项(包括下一个扩展分区的数据项).
扩展分区和逻辑盘的示意图如下:
|-----------------------|--------
|主扩展分区(/dev/hda2)|^
|-----------------------||
|扩展|分区项1|--\|
||------------|||
|分区表|分区项2|--+--\|
|-----------------------||||
|||||
|逻辑盘1(/dev/hda5)|<-/||
||||
|-----------------------||主
|扩展分区2|<----/
|-----------------------|扩
|扩展|分区项1|--\
||------------||展
|分区表|分区项2|--+--\
|-----------------------|||分
||||
|逻辑盘2(/dev/hda6)|<-/|区
||||
|-----------------------|||
|扩展分区3|<----/|
|-----------------------||
|扩展|分区项1|--\|
||------------|||
|分区表||||
|-----------------------|||
||||
|逻辑盘3(/dev/hda7)|<-/|
|||
|-----------------------|---------
三.系统启动过程简介
系统启动过程主要由一下几步组成(以硬盘启动为例):
1.开机:
-)
2.BIOS加电自检(PowerOnSelfTest--POST)
内存地址为0ffff:
0000
3.将硬盘第一个扇区(0头0道1扇区,也就是BootSector)
读入内存地址0000:
7c00处.
4.检查(WORD)0000:
7dfe是否等于0xaa55,若不等于
则转去尝试其他启动介质,如果没有其他启动介质则显示
"NoROMBASIC"然后死机.
5.跳转到0000:
7c00处执行MBR中的程序.
6.MBR首先将自己复制到0000:
0600处,然后继续执行.
7.在主分区表中搜索标志为活动的分区.如果发现没有活动
分区或有不止一个活动分区,则转停止.
8.将活动分区的第一个扇区读入内存地址0000:
7c00处.
9.检查(WORD)0000:
7dfe是否等于0xaa55,若不等于则
显示"MissingOperatingSystem"然后停止,或尝试
软盘启动.
10.跳转到0000:
7c00处继续执行特定系统的启动程序.
11.启动系统...
以上步骤中2,3,4,5步是由BIOS的引导程序完成.6,7,8,9,10
步由MBR中的引导程序完成.
一般多系统引导程序(如SmartFDISK,BootStar,PQBoot等)
都是将标准主引导记录替换成自己的引导程序,在运行系统启动程序
之前让用户选择要启动的分区.
而某些系统自带的多系统引导程序(如lilo,NTLoader等)
则可以将自己的引导程序放在系统所处分区的第一个扇区中,在Linux
中即为SuperBlock(其实SuperBlock是两个扇区).
注:
以上各步骤中使用的是标准MBR,其他多系统引导程序的引导
过程与此不同.
第二部分技术资料
第一章扩展Int13H技术资料
一.简介
设计扩展Int13H接口的目的是为了扩展BIOS的功能,使其支持
多于1024柱面的硬盘,以及可移动介质的琐定,解锁及弹出等功能.
二.数据结构
1.数据类型约定
BYTE1字节整型(8位)
WORD2字节整型(16位)
DWORD4字节整型(32位)
QWORD8字节整型(64位)
2.磁盘地址数据包DiskAddressPacket(DAP)
DAP是基于绝对扇区地址的,因此利用DAP,Int13H可以轻松地逾
越1024柱面的限制,因为它根本就不需要CHS的概念.
DAP的结构如下:
structDiskAddressPacket
{
BYTEPacketSize;//数据包尺寸:
//(固定值,恒等于16,即10H,指本结构所占用的存储空间)
BYTEReserved;//==0
WORDBlockCount;//要传输的数据块个数(以扇区为单位)
DWORDBufferAddr;//传输缓冲地址(segment:
offset)
QWORDBlockNum;//磁盘起始绝对块地址
};
PacketSize保存了DAP结构的尺寸,以便将来对其进行扩充.在
目前使用的扩展Int13H版本中PacketSize恒等于16.如果它小于
16,扩展Int13H将返回错误码(AH=01,CF=1).
BlockCount对于输入来说是需要传输的数据块总数,对于输出来说
是实际传输的数据块个数.BlockCount=0表示不传输任何数据块.
BufferAddr是传输数据缓冲区的32位地址(段地址:
偏移量).数据
缓冲区必须位于常规内存以内(1M).
BlockNum表示的是从磁盘开始算起的绝对块地址(以扇区为单位),
与分区无关.第一个块地址为0.一般来说,BlockNum与CHS地址的关系
是:
BlockNum=
(cylinder*NumberOfHeads+head)*SectorsPerTrack+sector-1;
其中cylinder,head,sector是CHS地址,NumberOfHeads是磁盘
的磁头数,SectorsPerTrack是磁盘每磁道的扇区数.
也就是说BlockNum是沿着扇区->磁道->柱面的顺序记数的.这一顺
序是由磁盘控制器虚拟的,磁盘表面数据块的实际排列顺序可能与此不同
(如为了提高磁盘速度而设置的间隔因子将会打乱扇区的排列顺序).
3.驱动器参数数据包DriveParametersPacket
驱动器参数数据包是在扩展Int13H的取得驱动器参数子功能调用中
使用的数据包.格式如下:
structDriveParametersPacket
{
WORDInfoSize;//数据包尺寸:
//(固定值,等于26,即1AH,指本结构所占用的存储空间)
WORDFlags;//信息标志
DWORDCylinders;//磁盘柱面数
DWORDHeads;//磁盘磁头数
DWORDSectorsPerTrack;//每磁道扇区数
QWORDSectors;//磁盘总扇区数
WORDSectorSize;//扇区尺寸(以字节为单位)
};
信息标志用于返回磁盘的附加信息,每一位的定义如下:
0位:
0=可能发生DMA边界错误
1=DMA边界错误将被透明处理
如果这位置1,表示BIOS将自动处理DMA边界错误,也就是说
错误代码09H永远也不会出现.
1位:
0=未提供CHS信息
1=CHS信息合法
如果块设备的传统CHS几何信息不适当的话,该位将置0.
2位:
0=驱动器不可移动
1=驱动器可移动
3位:
表示该驱动器是否支持写入时校验.
4位:
0=驱动器不具备介质更换检测线
1=驱动器具备介质更换检测线
5位:
0=驱动器不可锁定
1=驱动器可以锁定
要存取驱动器号大于0x80的可移动驱动器,该位必须置1
(某些驱动器号为0到0x7F的设备也需要置位)
6位:
0=CHS值是当前存储介质的值(仅对于可移动介质),如果
驱动器中有存储介质,CHS值将被返回.
1=CHS值是驱动器支持的最大值(此时驱动器中没有介质).
7-15位:
保留,必须置0.
三.接口规范
1.寄存器约定
在扩展Int13H调用中一般使用如下寄存器约定:
ds:
si==>磁盘地址数据包(diskaddresspacket)
dl==>驱动器号
ah==>功能代码/返回码
在基本Int13H调用中,0-0x7F之间的驱动器号代表可移动驱动器
0x80-0xFF之间的驱动器号代表固定驱动器.但在扩展Int13H调用中
0x80-0xFF之间还包括一些新出现的可移动驱动器,比如活动硬盘等.
这些驱动器支持先进的锁定,解锁等功能.
ah返回的错误码除了标准Int13H调用规定的基本错误码以外,又增加
了以下错误码:
B0h驱动器中的介质未被锁定
B1h驱动器中的介质已经锁定
B2h介质是可移动的
B3h介质正在被使用
B4h锁定记数溢出
B5h合法的弹出请求失败
2.API子集介绍
1.x版的扩展Int13H调用中规定了两个主要的API子集.
第一个子集提供了访问大硬盘所必须的功能,包括检查扩展In13H
是否存在(41h),扩展读(42h),扩展写(43h),校验扇区(44h),
扩展定位(47h)和取得驱动器参数(48h).
第二个子集提供了对软件控制驱动器锁定和弹出的支持,包括检查扩展
Int13H是否存在(41h),锁定/解锁驱动器(45h),弹出驱动器(46h),
取得驱动器参数(48h),取得扩展驱动器改变状态(49h),int15h.
如果使用了调用规范中不支持的功能,BIOS将返回错误码ah=01h,
CF=1.
3.API详解
1)检验扩展功能是否存在
入口:
AH=41h
BX=55AAh
DL=驱动器号
返回:
CF=0
AH=扩展功能的主版本号
AL=内部使用
BX=AA55h
CX=API子集支持位图
CF=1
AH=错误码01h,无效命令
这个调用检验对特定的驱动器是否存在扩展功能.如果进位标志置1
则此驱动器不支持扩展功能.如果进位标志为0,同时BX=AA55h,则
存在扩展功能.此时CX的0位表示是否支持第一个子集,1位表示是否
支持第二个子集.
对于1.x版的扩展Int13H来说,主版本号AH=1.AL是副版本号,
但这仅限于BIOS内部使用,任何软件不得检查AL的值.
2)扩展读
入口:
AH=42h
DL=驱动器号
DS:
SI=磁盘地址数据包(DiskAddressPacket)
返回:
CF=0,AH=0成功
CF=1,AH=错误码
这个调用将磁盘上的数据读入内存.如果出现错误,DAP的BlockCount
项中则记录了出错前实际读取的数据块个数.
3)扩展写
入口:
AH=43h
AL
0位=0关闭写校验
1打开写校验
1-7位保留,置0
DL=驱动器号
DS:
SI=磁盘地址数据包(DAP)
返回:
CF=0,AH=0成功
CF=1,AH=错误码
这个调用将内存中的数据写入磁盘.如果打开了写校验选项,但BIOS
不支持,则会返回错误码AH=01h,CF=1.功能48h可以检测BIOS是否
支持写校验.
如果出现错误,DAP的BlockCount项中则记录了出错前实际写入的数
据块个数.
4)校验扇区
入口:
AH=44h
DL=驱动器号
DS:
SI=磁盘地址数据包(DiskAddressPacket)
返回:
CF=0,AH=0成功
CF=1,AH=错误码
这个调用校验磁盘数据,但并不将数据读入内存.如果出现错误,DAP的
BlockCount项中则记录了出错前实际校验的数据块个数.
5)锁定/解锁驱动器
入口:
AH=45h
AL
=0锁定驱动器
=1驱动器解锁
=02返回锁定/解锁状态
=03h-FFh-保留
DL=驱动器号
返回:
CF=0,AH=0成功
CF=1,AH=错误码
这个调用用来缩定指定驱动器中的介质.
所有标号大于等于0x80的可移动驱动器必须支持这个功能.如果
在支持可移动驱动器控制功能子集的固定驱动器上使用这个功能调用,将
会成功返回.
驱动器必须支持最大255次锁定,在所有锁定被解锁之前,不能在物理上
将驱动器解锁.解锁一个未锁定的驱动器,将返回错误码AH=B0h.如果锁定一
个已锁定了255次的驱动器,将返回错误码AH=B4h.
锁定一个没有介质的驱动器是合法的.
6)弹出可移动驱动器中的介质
入口:
AH=46h
AL=0保留
DL=驱动器号
返回:
CF=0,AH=0成功
CF=1,AH=错误码
这个调用用来弹出指定的可移动驱动器中的介质.
所有标号大于等于0x80的可移动驱动器必须支持这个功能.如果
在支持可移动驱动器控制功能子集的固定驱动器上使用这个功能调用,将
会返回错误码AH=B2h