磁盘系统简介

. 硬盘结构简介

1. 硬盘参数释疑
到目前为止, 人们常说的硬盘参数还是古老的 CHS (Cylinder/Head/Sector)参数. 那么为什么要使用这些参数, 它们的意义是什么? 它们的取值范围是什么? 很久以前, 硬盘的容量还非常小的时候, 人们采用与软盘类似的结构生产硬盘. 也就是硬盘盘片的每一条磁道都具有相同的扇区数. 由此产生了所谓的3D参数 (Disk Geometry). 既磁头数(Heads), 柱面数(Cylinders), 扇区数(Sectors),以及相应的寻址方式.
其中:
磁头数(Heads) 表示硬盘总共有几个磁头,也就是有几面盘片, 最大为 255 ( 8 个二进制位存储); 柱面数(Cylinders) 表示硬盘每一面盘片上有几条磁道, 最大为 1023 ( 10 个二进制位存储); 扇区数(Sectors) 表示每一条磁道上有几个扇区, 最大为 63 ( 6 个二进制位存储).
每个扇区一般是 512个字节, 理论上讲这不是必须的, 但好象没有取别的值的.所以磁盘最大容量为: 255 * 1023 * 63 * 512 / 1048576 = 8024 GB ( 1M = 1048576 Bytes ) 或硬盘厂商常用的单位:
255 * 1023 * 63 * 512 / 1000000 = 8414 GB ( 1M = 1000000 Bytes )
CHS 寻址方式中, 磁头, 柱面, 扇区的取值范围分别为 0 Heads - 1, 0 Cylinders - 1, 1 Sectors (注意是从 1 开始).
2.
基本 Int 13H 调用简介
BIOS Int 13H 调用是 BIOS 提供的磁盘基本输入输出中断调用, 它可以完成磁盘(包括硬盘和软盘)的复位, 读写, 校验, 定位, 诊断, 格式化等功能.它使用的就是 CHS 寻址方式, 因此最大识能访问 8 GB 左右的硬盘 ( 本文中如不作特殊说明, 均以 1M = 1048576 字节为单位).
3.
现代硬盘结构简介
在老式硬盘中, 由于每个磁道的扇区数相等, 所以外道的记录密度要远低于内道, 因此会浪费很多磁盘空间 (与软盘一样). 为了解决这一问题, 进一步提高硬盘容量, 人们改用等密度结构生产硬盘. 也就是说, 外圈磁道的扇区比内圈磁道多. 采用这种结构后, 硬盘不再具有实际的3D参数, 寻址方式也改为线性寻址, 即以扇区为单位进行寻址.为了与使用3D寻址的老软件兼容 (如使用BIOS Int13H接口的软件), 在硬盘控制器内部安装了一个地址翻译器, 由它负责将老式3D参数翻译成新的线性参数. 这也是为什么现在硬盘的3D参数可以有多种选择的原因 (不同的工作模 , 对应不同的3D参数, LBA, LARGE, NORMAL).
4.
扩展 Int 13H 简介
虽然现代硬盘都已经采用了线性寻址, 但是由于基本 Int 13H 的制约, 使用 BIOS Int 13H 接口的程序, DOS 等还只能访问 8 G 以内的硬盘空间.为了打破这一限制, Microsoft 等几家公司制定了扩展 Int 13H 标准(Extended Int13H), 采用线性寻址方式存取硬盘, 所以突破了 8 G 的限制, 而且还加入了对可拆卸介质 (如活动硬盘) 的支持.
. Boot Sector 结构简介
1. Boot Sector 的组成
Boot Sector 也就是硬盘的第一个扇区, 它由 MBR (Master Boot Record代码段), DPT (Disk Partition Table数据段) Boot Record ID(标记位55AA) 三部分组成. MBR 又称作主引导记录占用 Boot Sector 的前 446 个字节 ( 0 to 0x1BD ), 存放系统主引导程序 (它负责从活动分区中装载并运行系统引导程序). DPT 即主分区表占用 64 个字节 (0x1BE to 0x1FD), 记录了磁盘的基本分区信息. 主分区表分为四个分区项, 每项 16 字节, 分别记录了每个主分区的信息(因此最多可以有四个主分区).Boot Record ID 即引导区标记占用两个字节 (0x1FE and 0x1FF), 对于合法引导区, 它等于 0xAA55, 这是判别引导区是否合法的标志.Boot Sector 的具体结构如下图所示:
0000 |------------------------------------------------|
| |
| |
| Master Boot Record |
| |
| |
|
主引导记录(446字节) |
| |
| |
| |
01BD | |
01BE |------------------------------------------------|
| |
01CD |
分区信息 1(16字节) |
01CE |------------------------------------------------|
| |
01DD |
分区信息 2(16字节) |
01DE |------------------------------------------------|
| |
01ED |
分区信息 3(16字节) |
01EE |------------------------------------------------|
| |
01FD |
分区信息 4(16字节) |
|------------------------------------------------|
| 01FE | 01FF |
| 55 | AA |
|------------------------------------------------|
2.
分区表结构简介
分区表由四个分区项构成, 每一项的结构如下:
BYTE State :
分区状态, 0 = 未激活, 0x80 = 激活 (注意此项) (如果是引导盘,必须有一个是0x80,否则可以都是00
BYTE StartHead : 分区起始磁头号
WORD StartSC : 分区起始扇区和柱面号, 底字节的低6位为扇区号,2位为柱面号的第 9,10 , 高字节为柱面号的低 8

BYTE Type : 分区类型, 0X7 = NTFS,0x0B = FAT32, 0x83 = Linux ,,
00
表示此项未用 ,DE表示是个隐藏扇区
BYTE EndHead : 分区结束磁头号
WORD EndSC : 分区结束扇区和柱面号, 定义同前
DWORD Relative : 在线性寻址方式下的分区相对扇区地址
(对于基本分区即为绝对地址)
DWORD Sectors :
分区大小 (总扇区数)
注意: DOS / Windows 系统下, 基本分区必须以柱面为单位划分( Sectors * Heads 个扇区), 如对于 CHS 764/255/63 的硬盘, 分区的最小尺寸为 255 * 63 * 512 / 1048576 = 7.844 MB.
3.
扩展分区简介
由于主分区表中只能分四个分区, 无法满足需求, 因此设计了一种扩展分区格式. 基本上说, 扩展分区的信息是以链表形式存放的, 但也有一些特别的地方.首先, 主分区表中要有一个基本扩展分区项, 所有扩展分区都隶属于它, 也就是说其他所有扩展分区的空间都必须包括在这个基本扩展分区中. 对于DOS / Windows 来说, 扩展分区的类型为 0x050XF(代表扩展分区), 除基本扩展分区以外的其他所有扩展分区则以链表的形式级联存放, 后一个扩展分区的数据项记录在前一个扩展分区的分区表中, 但两个扩展分区的空间并不重叠.扩展分区类似于一个完整的硬盘, 必须进一步分区才能使用. 但每个扩展分区中只能存在一个其他分区. 此分区在 DOS/Windows 环境中即为逻辑盘. 因此每一个扩展分区的分区表 (同样存储在扩展分区的第一个扇区中)中最多只能有两个分区数据项(包括下一个扩展分区的数据项). 扩展分区和逻辑盘的示意图如下:
|-----------------------| --------
|
主扩展分区(/dev/hda2) | ^
|-----------------------| |
|
| 分区项 1 |--\ |
| |------------| | |
|
分区表 | 分区项 2 |--+--\ |
|-----------------------| | | |
| | | | |
|
逻辑盘 1 (/dev/hda5) |<-/ | |
| | | |
|-----------------------| |

| 扩展分区 2 |<----/
|-----------------------|

| | 分区项 1 |--\
| |------------| |

| 分区表 | 分区项 2 |--+--\
|-----------------------| | |

| | | |
|
逻辑盘 2 (/dev/hda6) |<-/ |
| | | |
|-----------------------| | |
|
扩展分区 3 |<----/ |
|-----------------------| |
|
| 分区项 1 |--\ |
| |------------| | |
|
分区表 | 分区项 2 | | |
|-----------------------| | |
| | | |
|
逻辑盘 3 (/dev/hda7) |<-/ |
| | |
|-----------------------| ---------

. 系统启动过程简介
系统启动过程主要由一下几步组成(以硬盘启动为例):
1.
开机 :-)
2. BIOS
加电自检 ( Power On Self Test -- POST )
内存地址为 0ffff:0000
3.
将硬盘第一个扇区通过int19 (001扇区, 也就是Boot Sector)
读入内存地址 0000:7c00 .
4.
检查 (WORD) 0000:7dfe 是否等于 0xaa55, 若不等于
则转去尝试其他启动介质, 如果没有其他启动介质则显示
"No ROM BASIC" 然后死机.
5.
跳转到 0000:7c00 处执行 MBR 中的程序.

下面是MBR干的事情
6. MBR
首先将自己复制到 0000:0600 , 然后继续执行.
7.
在主分区表中搜索标志为活动的分区(搜索0x80标志,只有一个才正常,2个会不知道从哪个开始). 如果发现没有活动
分区或有不止一个活动分区, 则转停止.
8.
将活动分区的第一个扇区读入内存地址 0000:7c00 .(比如NTFS的BootLoader)
9.
检查 (WORD) 0000:7dfe 是否等于 0xaa55, 若不等于则(所以劫持他就不安全了,bios的安全缺陷)
显示 "Missing Operating System" 然后停止, 或尝试
软盘启动.
10.
跳转到 0000:7c00 处继续执行特定系统的启动程序.
11.
启动系统 ...
以上步骤中 2,3,4,5 步是由 BIOS 的引导程序完成. 6,7,8,9,10
步由MBR中的引导程序完成.
一般多系统引导程序 ( SmartFDISK, BootStar, PQBoot ) 都是将标准主引导记录替换成自己的引导程序, 在运行系统启动程序之前让用户选择要启动的分区. 而某些系统自带的多系统引导程序 ( lilo, NT Loader ) 则可以将自己的引导程序放在系统所处分区的第一个扇区中, Linux 中即为 SuperBlock (其实 SuperBlock 是两个扇区). : 以上各步骤中使用的是标准 MBR, 其他多系统引导程序的引导过程与此不同.


第二部分 技术资料

基本Int13H 技术资料:

直接磁盘服务(Direct Disk Service——INT 13H)
00H —
磁盘系统复位
01H —读取磁盘系统状态
02H —读扇区
03H —写扇区
04H —检验扇区
05H —格式化磁道
06H —格式化坏磁道
07H —格式化驱动器
08H —读取驱动器参数
09H —初始化硬盘参数
0AH —读长扇区
0BH —写长扇区
0CH —查寻
0DH —硬盘系统复位
0EH —读扇区缓冲区
0FH —写扇区缓冲区
10H —读取驱动器状态
11H —校准驱动器
12H —控制器RAM诊断
13H —控制器驱动诊断
14H —控制器内部诊断
15H —读取磁盘类型
16H —读取磁盘变化状态
17H —设置磁盘类型
18H —设置格式化媒体类型
19H —磁头保护
1AH —格式化ESDI驱动器

(1)、功能00H
功能描述:磁盘系统复位
入口参数:AH00H
DL
=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
出口参数:CF0——操作成功,AH00H,否则,AH=状态代码,参见功能号01H中的说明

(2)、功能01H
功能描述:读取磁盘系统状态
入口参数:AH01H
DL
=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
出口参数:AH00HAL=状态代码,其定义如下:
00H — 无错
01H — 非法命令
02H — 地址目标未发现
03H — 磁盘写保护(软盘)
04H —
扇区未发现
05H — 复位失败(硬盘)
06H —
软盘取出(软盘)
07H —
错误的参数表(硬盘)
08H — DMA
越界(软盘)
09H — DMA
超过64K界限
0AH — 错误的扇区标志(硬盘)
0BH —
错误的磁道标志(硬盘)
0CH —
介质类型未发现(软盘)
0DH —
格式化时非法扇区号(硬盘)
0EH —
控制数据地址目标被发现(硬盘)
0FH — DMA
仲裁越界(硬盘)
10H —
不正确的CRCECC编码
11H — ECC校正数据错(硬盘)
 CRC:Cyclic Redundancy Check code
 ECC:Error Checking & Correcting code
20H —
控制器失败
40H — 查找失败
80H — 磁盘超时(未响应)
AAH —
驱动器未准备好(硬盘)
BBH —
未定义的错误(硬盘)
CCH —
写错误(硬盘)
E0H —
状态寄存器错(硬盘)
FFH —
检测操作失败(硬盘)

(3)、功能02H
功能描述:读扇区
入口参数:AH02H
AL
=扇区数
CH=柱面
CL=扇区
DH=磁头
DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
ES:BX=缓冲区的地址
出口参数:CF0——操作成功,AH00HAL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明

(4)、功能03H
功能描述:写扇区
入口参数:AH03H
AL
=扇区数
CH=柱面
CL=扇区
DH=磁头
DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
ES:BX=缓冲区的地址
出口参数:CF0——操作成功,AH00HAL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明

(5)、功能04H
功能描述:检验扇区
入口参数:AH04H
AL
=扇区数
CH=柱面
CL=扇区
DH=磁头
DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
ES:BX=缓冲区的地址
出口参数:CF0——操作成功,AH00HAL=被检验的扇区数,否则,AH=状态代码,参见功能号01H中的说明

(6)、功能05H
功能描述:格式化磁道
入口参数:AH05H
AL
=交替(Interleave)
CH
=柱面
DH=磁头
DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
ES:BX=地址域列表的地址
出口参数:CF0——操作成功,AH00H,否则,AH=状态代码,参见功能号01H中的说明

(7)、功能06H
功能描述:格式化坏磁道
入口参数:AH06H
AL
=交替
CH=柱面
DH=磁头
DL80H~0FFH:硬盘
ES:BX=地址域列表的地址
出口参数:CF0——操作成功,AH00H,否则,AH=状态代码,参见功能号01H中的说明

(8)、功能07H
功能描述:格式化驱动器
入口参数:AH07H
AL
=交替
CH=柱面
DL80H~0FFH:硬盘
出口参数:CF0——操作成功,AH00H,否则,AH=状态代码,参见功能号01H中的说明

(9)、功能08H
功能描述:读取驱动器参数
入口参数:AH08H
DL
=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
出口参数:CF1——操作失败,AH=状态代码,参见功能号01H中的说明,否则, BL01H — 360K
02H — 1.2M
03H — 720K
04H — 1.44M
CH
=柱面数的低8
CL的位7-6=柱面数的该2
CL的位5-0=扇区数
DH=磁头数
DL=驱动器数
ES:DI=磁盘驱动器参数表地址

(10)、功能09H
功能描述:初始化硬盘参数
入口参数:AH09H
DL
80H~0FFH:硬盘(还有有关参数表问题,在此从略)
出口参数:CF0——操作成功,AH00H,否则,AH=状态代码,参见功能号01H中的说明

(11)、功能0AH
功能描述:读长扇区,每个扇区随带四个字节的ECC编码
入口参数:AH0AH
AL
=扇区数
CH=柱面
CL=扇区
DH=磁头
DL80H~0FFH:硬盘
ES:BX=缓冲区的地址
出口参数:CF0——操作成功,AH00HAL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明

(12)、功能0BH
功能描述:写长扇区,每个扇区随带四个字节的ECC编码
入口参数:AH0BH
AL
=扇区数
CH=柱面
CL=扇区
DH=磁头
DL80H~0FFH:硬盘
ES:BX=缓冲区的地址
出口参数:CF0——操作成功,AH00HAL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明

(13)、功能0CH
功能描述:查寻
入口参数:AH0CH
CH
=柱面的低8
CL(7-6)=柱面的高2
DH=磁头
DL80H~0FFH:硬盘
出口参数:CF0——操作成功,AH00H,否则,AH=状态代码,参见功能号01H中的说明

(14)、功能0DH
功能描述:硬盘系统复位
入口参数:AH0DH
DL
80H~0FFH:硬盘
出口参数:CF0——操作成功,AH00H,否则,AH=状态代码,参见功能号01H中的说明

(15)、功能0EH
功能描述:读扇区缓冲区
入口参数:AH0EH
ES:BX
=缓冲区的地址
出口参数:CF0——操作成功,否则,AH=状态代码,参见功能号01H中的说明

(16)、功能0FH
功能描述:写扇区缓冲区
入口参数:AH0FH
ES:BX
=缓冲区的地址
出口参数:CF0——操作成功,否则,AH=状态代码,参见功能号01H中的说明

(17)、功能10H
功能描述:读取驱动器状态
入口参数:AH10H
DL
80H~0FFH:硬盘
出口参数:CF0——操作成功,AH00H,否则,AH=状态代码,参见功能号01H中的说明

(18)、功能11H
功能描述:校准驱动器
入口参数:AH11H
DL
80H~0FFH:硬盘
出口参数:CF0——操作成功,AH00H,否则,AH=状态代码,参见功能号01H中的说明

(19)、功能12H
功能描述:控制器RAM诊断
入口参数:AH12H
出口参数:CF0——操作成功,否则,AH=状态代码,参见功能号01H中的说明

(20)、功能13H
功能描述:控制器驱动诊断
入口参数:AH13H
出口参数:CF0——操作成功,否则,AH=状态代码,参见功能号01H中的说明

(21)、功能14H
功能描述:控制器内部诊断
入口参数:AH14H
出口参数:CF0——操作成功,否则,AH=状态代码,参见功能号01H中的说明

(22)、功能15H
功能描述:读取磁盘类型
入口参数:AH15H
DL
=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
出口参数:CF1——操作失败,AH=状态代码,参见功能号01H中的说明, 否则,AH00H — 未安装驱动器
01H — 无改变线支持的软盘驱动器
02H — 带有改变线支持的软盘驱动器
03H — 硬盘,CX:DX512字节的扇区数

(23)、功能16H
功能描述:读取磁盘变化状态
入口参数:AH16H
DL
00H~7FH:软盘
出口参数:CF0——磁盘未改变,AH00H,否则,AH06H,参见功能号01H中的说明

(24)、功能17H
功能描述:设置磁盘类型
入口参数:AH17H
DL
00H~7FH:软盘 AL00H — 未用
01H — 360K360K驱动器中
02H — 360K1.2M驱动器中
03H — 1.2M1.2M驱动器中
04H — 720K720K驱动器中
出口参数:CF0——操作成功,AH00H,否则,AH=状态编码,参见功能号01H中的说明

(25)、功能18H
功能描述:设置格式化媒体类型
入口参数:AH18H
CH
=柱面数
CL=每磁道的扇区数
DL00H~7FH:软盘
出口参数:CF0——操作成功,AH00HES:DI=介质类型参数表地址,否则,AH=状态编码,参见功能号01H中的说明

(26)、功能19H
功能描述:磁头保护,仅在PS/2中有效,在此从略

(27)、功能1AH
功能描述:格式化ESDI驱动器,仅在PS/2中有效,在此从略

扩展 Int13H 技术资料

. 简介
设计扩展 Int13H 接口的目的是为了扩展 BIOS 的功能, 使其支持
多于1024柱面的硬盘, 以及可移动介质的琐定, 解锁及弹出等功能.
. 数据结构
1. 数据类型约定
BYTE 1 字节整型 ( 8 )
WORD 2
字节整型 ( 16 )
DWORD 4
字节整型 ( 32 )
QWORD 8
字节整型 ( 64 )
2.
磁盘地址数据包 Disk Address Packet (DAP)
DAP
是基于绝对扇区地址的, 因此利用 DAP, Int13H 可以轻松地逾
1024 柱面的限制, 因为它根本就不需要 CHS 的概念.
DAP
的结构如下:
struct DiskAddressPacket
{
BYTE PacketSize; //
数据包尺寸(16字节)
BYTE Reserved; // ==0
WORD BlockCount; //
要传输的数据块个数(以扇区为单位)
DWORD BufferAddr; //
传输缓冲地址(segment:offset)
QWORD BlockNum; //
磁盘起始绝对块地址
};
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.
驱动器参数数据包 Drive Parameters Packet
驱动器参数数据包是在扩展 Int13H 的取得驱动器参数子功能调用中 使用的数据包. 格式如下:
struct DriveParametersPacket
{
WORD InfoSize; //
数据包尺寸 (26 字节)
WORD Flags; //
信息标志
DWORD Cylinders; // 磁盘柱面数
DWORD Heads; // 磁盘磁头数
DWORD SectorsPerTrack; // 每磁道扇区数
QWORD Sectors; // 磁盘总扇区数
WORD SectorSize; // 扇区尺寸 (以字节为单位)
};

信息标志用于返回磁盘的附加信息, 每一位的定义如下:
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:di ==>
磁盘地址数据包( disk address packet )
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 ), int 15h. 如果使用了调用规范中不支持的功能, 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:DI = 磁盘地址数据包(Disk Address Packet)
返回:
CF = 0, AH = 0
成功
CF = 1, AH = 错误码
这个调用将磁盘上的数据读入内存. 如果出现错误, DAP BlockCount项中则记录了出错前实际读取的数据块个数.
3)
扩展写
入口:
AH = 43h
AL
0
= 0 关闭写校验
1 打开写校验
1 - 7 位保留, 0
DL =
驱动器号
DS:DI = 磁盘地址数据包(DAP)
返回:
CF = 0, AH = 0
成功
CF = 1, AH = 错误码
这个调用将内存中的数据写入磁盘. 如果打开了写校验选项, BIOS不支持, 则会返回错误码 AH = 01h, CF = 1. 功能 48h 可以检测BIOS是否支持写校验. 如果出现错误, DAP BlockCount 项中则记录了出错前实际写入的数据块个数.
4)
校验扇区
入口:
AH = 44h
DL =
驱动器号
DS:DI = 磁盘地址数据包(Disk Address Packet)
返回:
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 (介质不可移动). 如果试图弹出一个被锁定的介质
将返回错误码 AH = B1h (介质被锁定).
如果试图弹出一个没有介质的驱动器, 则返回错误码 Ah = 31h (驱动器
中没有介质).
中没有介质).
如果试图弹出一个未锁定的可移动驱动器中的介质, Int13h会调用 Int15h
(AH = 52h)
来检查弹出请求能否执行. 如果弹出请求被拒绝则返回错误码(
Int15h). 如果弹出请求被接受,但出现了其他错误, 则返回错误码 AH = B5h.
7)
扩展定位
入口:
AH = 47h
DL =
驱动器号
DS:DI = 磁盘地址数据包(Disk Address Packet)
返回:
CF = 0, AH = 0
成功
CF = 1, AH = 错误码
这个调用将磁头定位到指定扇区.
8)
取得驱动器参数
入口:
AH = 48h
DL =
驱动器号
DS:DI = 返回数据缓冲区地址
返回:
CF = 0, AH = 0
成功
DS:DI 驱动器参数数据包地址, (参见前面的文章)
CF = 1, AH =
错误码
这个调用返回指定驱动器的参数.
9)
取得扩展驱动器介质更换检测线状态
入口:
AH = 49h
DL =
驱动器号
返回:
CF = 0, AH = 0
介质未更换
CF = 1, AH = 06h 介质可能已更换
这个调用返回指定驱动器的介质更换状态.
这个调用与 Int13h AH = 16h 子功能调用相同, 只是允许任何驱动器标号. 如果对一台支持可移动介质功能子集的固定驱动器使用此功能,则永远返回 CF = 0, AH = 0. 简单地将可移动介质锁定再解锁就可以激活检测线, 而无须真正更换介质.
10) Int 15h
可移动介质弹出支持
入口:
AH = 52h
DL =
驱动器号
返回:
CF = 0, AH = 0
弹出请求可能可以执行
CF = 1, AH = 错误码 B1h B3h 弹出请求不能执行
这个调用是由 Int13h AH=46h 弹出介质功能调用内部使用的.

Windows基本磁盘结构简析

在Windows系统中,对于物理磁盘的管理包括基本磁盘、动态磁盘两种形式,其中基本磁盘又是Windows系统的默认形式。在基本磁盘上,以分区的形式来划分多个连续的空间,即我们通常熟悉的主分区和逻辑分区。而在动态磁盘上,Windows以卷的形式来管理磁盘空间,包括简单卷、镜像卷、带区卷、扩展卷以及RAID5卷,且卷的空间可以不是连续的磁盘区域,甚至位于不同的动态磁盘上。由于动态磁盘的组织构件包括磁盘、组件、分区、卷等多个内容,比较复杂,且Microsoft也没有提供详细的结构分析,因此,我这里所做的磁盘结构分析都是基于基本磁盘的。

在基本磁盘上,磁盘空间的最小管理单元是扇区(Sector),我们通常所说的分区就是磁盘上连续的扇区的集合,而格式化分区时所涉及到的簇,则是文件系统管理磁盘空间的最小逻辑单元,一个簇可以包含多个扇区,通常是2的幂数,如128,512,4096等。Windows有两种不同的分区管理方式:MBR和GPT。

MBR,Master Boot Record,即主引导记录,它是磁盘的第一个扇区,MBR中包含了系统引导信息、磁盘签名以及磁盘的分区表,分区表中包含有4个分区项,每个项记录了该分区的在磁盘上的其实位置和大小。由于MBR的分区项数只有4,所以我们在创建分区时,最多只有4个主分区或者3个主分区加一个扩展分区,但是扩展分区可以包含多个逻辑分区。另外,由于在MBR分区表中,分区的偏移、大小都是采用4字节的数据来表示,所以最大能够表示的大小为2的32次方,即2T,这是MBR分区方式能够管理的最大磁盘大小和最大分区大小。

GPT,GUID Partition Table,即全局唯一标示符分区表,这种分区方式突破了MBR分区表的限制,可以创建任意个数的分区,且分区的大小没有2T的限制。为了兼容之前的磁盘管理方式,GPT磁盘还是会使用基本磁盘的第一个扇区MBR,并且将MBR的第一个分区项标示为GPT磁盘,称为保护MBR,防止在不识别GPT磁盘的系统上破坏磁盘结构。GPT磁盘上同样包含分区表信息,并且每个分区都有自己的唯一GUID,和MBR不同的是GPT分区表项采用8个字节来表示分区偏移和分区大小,且备份了分区表,加上了CRC检验信息,因此安全性要优于MBR分区方式。在Windows系统上,只为GPT分区表保留了32个扇区,且每个GPT分区项占用128个字节,因此Windows实际上限制了GPT分区的个数为128个,个人觉得这已经足够用户使用了。

在日常生活,大多数Windows系统都是安装在MBR磁盘上的,因此在磁盘管理器中初始化磁盘时,默认的都是MBR分区方式。在最新的计算机上,有很多都是支持EFI的主板,如果选择EFI方式启动系统,则必须要将Windows安装在GPT磁盘上,且必须存在EFI系统分区,在Windows上初始化磁盘时默认的分区方式则改为GPT。MBR磁盘的分区包括主分区、扩展分区、逻辑分区,其中逻辑分区是在扩展分区中创建的,当我们在MBR磁盘上创建了3个主分区后,再次创建分区时,系统会自动创建一个扩展分区,并包含所有剩余的磁盘空间,然后在这个扩展分区中创建我们指定大小的逻辑分区。在GPT磁盘上,我们最多可以创建128个分区,且都是主分区,但是这些分区的类型有所不同,它们包括OEM分区、Microsoft保留分区(MSR)、EFI系统分区、恢复分区、普通分区,其中EFI系统分区是启动系统的关键。(劫持efi启动文件也是安全问题)

MBR磁盘分区是使用最为广泛的一种分区结构,也被称为DOS分区,不仅仅Windows系统,Linux、UNIX等都能够支持MBR磁盘分区。MBR磁盘都有一个引导扇区,称为主引导记录, Master Boot Record,即MBR,它位于磁盘上的第一个扇区,即0号扇区,由引导代码、分区表、磁盘签名、结束标志组成,共占用512个字节,是一个特殊而重要的扇区。通过WinHex或其他工具,可查看MBR的结构如下图所示。

92060c00这四个字节不能改了,这是磁盘标志

1、引导代码

引导程序占用MBR的前440个字节,计算机在BIOS自检通过后,会将启动磁盘的MBR加载到内存中并执行引导程序,引导程序则会在分区表中查找活动分区,如果存在活动分区,则根据活动分区的偏移获得活动分区上引导扇区的地址,并判断引导扇区的合法性,将引导扇区读入内存,然后将控制权交给这个引导扇区,由它去引导操作系统。因此,MBR中的引导程序在系统启动过程中起到了承上启下的作用。在非启动磁盘上,MBR中的引导程序可能都是0,这对磁盘的使用没有任何影响。

2、分区表

MBR分区表示磁盘管理最重要的部分,通过分区表信息来定位各个分区、访问用户数据。分区表中包含4个分区项,每一项通过位置偏移、大小来唯一确定一个主分区或扩展分区。每个分区项16个字节,其中包括启动标志,起始、结束位置的CHS参数,开始扇区,分区大小,分区类型。具体描述如下图所示。需要注意的是,分区项的第一个字节表示该分区是否为活动分区,即是否包含系统引导扇区,用来启动操作系统,每个磁盘只能有一个活动分区。活动分区项的引导标识为0x80,其他均为0x00,虽然可以使用工具将多个分区项的引导标识改为0x80,但是MBR引导程序只会查找并使用第一个具有0x80标识的活动分区。

3、磁盘签名(字节偏移 0x1b8 dword)

每个MBR磁盘都有唯一的磁盘签名,是Windows在初始化磁盘时写入的一个磁盘标签,Windows依靠磁盘签名来识别基本MBR磁盘。如果两个磁盘的签名相同,则后加入的那个磁盘分区将不会显示给用户,在磁盘管理器中,可以看见不可识别硬盘上有一个红色的感叹号,描述为该磁盘因为签名冲突处于离线状态。在Vista以及之后的Windows系统中,每个系统引导项中都记录了引导磁盘的签名,如果磁盘签名丢失或修改,将会导致系统无法启动。

4、结束标志

MBR的最后两个字节固定为”55AA”,双字节值为0xAA55。每次执行系统引导代码是都会检查MBR最后两字节是否为”55AA”,如果是才会继续执行后面的程序,否则会认为这是一个非法的MBR,停止引导系统。

MBR磁盘上,系统通过分区表来管理磁盘分区,但是由于分区表只有64个字节,包含4个分区项,所以最多也只能管理4个分区,称为主分区,也可以创建3个主分区和一个扩展分区,并在扩展分区中创建逻辑分区。主分区和扩展分区的定位相对简单,因为MBR分区项中已经指明了该分区所在磁盘上的位置和大小,而逻辑分区则需要通过扩展分区项以及逻辑分区链来确定位置和大小.

在MBR磁盘上,每个逻辑分区都对应有一个数据结构,它类似于主引导记录MBR,占用一个扇区的空间,通常称为EBR。在EBR中,只有分区表中的前两项以及结束标志0xAA55有效。EBR分区表的第一项表明当前逻辑分区的偏移地址,第二项表明下一个逻辑分析EBR的开始位置。逻辑分区的管理类似于数据结构中的链表,第一个节点由链表头指定,即MBR分区表中的扩展分区指定了第一个逻辑分区EBR的开始位置,之后每个节点中都有一个属性表明下一个节点的地址。

 

MBR方式通过在启动扇区的分区表中记录分区的开始和结束位置来管理分区,由于分区表最多包含4项,且采用32位数据来表示分区偏移和大小,造成的主分区的个数限制,以及分区大小的限制。现在,硬盘容量越来越大,也变得廉价的多,为了管理超过2TB的大硬盘和分区,显然基本MBR分区方式已经无法满足要求了,且MBR分区方式无法满足UEFI主板系统的要求。

GPT,即GUID分区表,顾名思义,即使用GUID来表示每个分区,GPT磁盘用唯一的GUID来表示,磁盘分区使用唯一的分区GUID来表示。GPT分区表中,每个分区表项使用128字节,其中包括分区的GUID,分区的偏移、大小,分区的名称、类型等,并且所有这些信息只占用了92个字节,所以分区表项还保留了对未来的兼容性。GPT分区表项使用64位8字节数表示分区的偏移、大小,支持18千兆兆字节的分区大小,这已经远远超过我们现在的磁盘和分区容量了。

与目前普遍使用的主引导记录(MBR)分区方案相比,GPT提供了更加灵活的磁盘分区机制。它具有如下优点:

1、支持2TB以上的大硬盘。

2、每个磁盘的分区个数几乎没有限制(Windows系统最多只允许划分128个分区)。

3、分区大小几乎没有限制。又是一个“几乎”。因为它用64位的整数表示扇区号,即  = 18,446,744,073,709,551,616。

4、分区表自带备份。在磁盘的首尾部分分别保存了一份相同的分区表,其中一份被破坏后,可以通过另一份恢复;

5、循环冗余检验值针对关键数据结构而计算,提高了数据崩溃的检测几率;

6、 虽然MBR提供1字节分区类型代码,但GPT使用一个16字节的全局唯一标识符(GUID)值来标识分区类型,这使分区类型更不容易冲突;

7、每个分区可以有一个名称(不同于卷标)。

为了兼容不支持GPT磁盘的操作系统,GPT分区格式保留了磁盘第一个扇区MBR的使用,并且也填写MBR的第一个分区表项,这个扇区又被称为保护MBR,而实际上EFI根本不使用这个分区表。在第一个分区表项中,分区开始扇区为1,分区大小扇区数为FFFFFFFF,分区类型为0xEE,它的目的是使计算机认为这个磁盘是合法的,并且已经被划分了分区,从而使系统不再试图重新初始化或格式化磁盘。

真正的GPT区域从硬盘的第二个扇区即1号扇区开始,主要包括GPT头、分区表、GPT分区、分区表备份、GPT头备份这几个部分。GPT磁盘布局如下图所示。

 

 

GPT头:也称为EFI信息区,从硬盘1号扇区开始,占用1个扇区的空间,其中记录了磁盘的GUID,当前GPT头的位置和GPT头备份的位置,分区表的开始扇区、分区表项的个数以及每个分区表项的大小,GPT头校验和,GPT分区表校验和等。GPT结构如下图所示:

分区表:分区表一般从2号扇区开始,占用32个扇区,即从GPT头之后一个扇区开始。理论上,GPT磁盘上可以创建任意多个主分区,但是由于在初始化GPT磁盘上,只给GPT分区表保留了32个扇区,且每个分区表项128个字节,所以最多也只能创建128个分区,而128个分区也就足够了。分区表项中包含分区的开始、结束位置,类型GUID,分区GUID,名字,属性标志等内容。

 

PT分区:GPT分区有不同的分区类型,每种类型都在分区表项中使用类型GUID来标识,主要包括微软保留分区、OEM保留分区、LDM元数据分区、LDM数据分区、EFI系统分区、主分区。Windows使用保留分区来存放临时文件、配置数据,以及保留兼容性,或者其他用途。LDM元数据分区、LDM数据分区用户动态GPT磁盘,元数据分区即LDM数据库,包含动态磁盘和动态卷的配置信息,LDM数据分区包含所有动态卷,用来划分数据卷。EFI系统分区中存在系统引导文件,类似于MBR磁盘的活动分区。主分区是普通的数据分区,也是唯一一种普通用户能够在我的电脑里看见的分区。

LBA 2–33

LBA 2–33的位置存放的是分区表项。GPT分区表使用简单而直接的方式表示分区。一个分区表项的前16字节是分区类型GUID。接下来的16字节是该分区唯一的GUID(这个GUID指的是该分区本身,而之前的GUID指的是该分区的类型)。再接下来是分区起始和末尾的64位LBA编号,以及分区的名字和属性。

http://blog.csdn.net/chongyang198999/article/details/43408249

 

用管理员权限打开 CMD
然后输入diskpart  启动diskpart  然后依次输出
 

  • list disk-------------------------  列出系统中拥有的磁盘
  • select disk 0-------------------- 选择EFI引导分区所在的磁盘,请根据实际情况选择
  • list partition-------------------- 列出所选磁盘拥有的分区
  • select partition 1---------------选择EFI引导分区,类型为系统的分区,就是EFI引导分区
  • assign letter=p:----------------为所选分区分配盘符,请分配空闲盘符
  • EFI分区分配盘符之后,不要着急在我的电脑中打开EFI分区(打开会提示权限不够),这时候在命令提示符中退出diskpart命令,之后将文件浏览器进程杀死然后重启一下就可以任意访问EFI分区了。在命令提示符中输入以下指令:
    exit
    taskkill /im explorer.exe /f
    explorer.exe

    接下来就可以放心的修改EFI分区了

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值