1.关于硬盘分区:
IDE接口硬盘中,不管什么操作系统,都有如下结构:
MBR(Master Boot Record)及基本分区表 |
分区1 |
分区2 |
...... |
分区n |
|
MBR和基本分区表共用硬盘的第一个扇区(即0面0道1扇区,以后简称第一扇区MBR),分区表位于扇区的最后中日关系论文66字节,除了最后的2字节55AA外,为4条分区记录,每条分区记录16字节。
各字段含义如下:
社会化用工
偏移 | 意义 |
0 | 自举标志(80为活动分区,00为非活动分区) |
1 | 起始磁头号H |
2 | 起始扇区号S |
3 | 起始柱面号CYL(CYL的高2位存放在S字节的高2位 |
4 | 分区格式标志(01:fat12;05:extended;06:fat16;07:hpfs/ntfs; 0b,0d:win95 fat32换命快递;0e:win95 fat16;82:linux swap;83:linux;85:linux extended) |
5 | 终止磁头号H |
6 | 终止扇区号S |
7 | 终止柱面号CYL |
8-11 | 本分区之前已用扇区数(当分区表属于扩展分区中的记录时,该值为相对扩展分区首地址的位置) |
12-15 | 本分区扇区总数 赛钛客rat9 |
| |
(注意:C/H/S的编址从0/0/1开始)
可以看出,使用C/H/S三维地址时,磁盘的寻址空间最多只有224个扇区,即8GB的容量,当磁盘容量大于8GB时,C/H/S就无法寻址了。
于是采用LBA(logic block address)线性地址来寻址。在LBA方式下系统把所以的物理扇区都按某种方式或规则看做是一线性编号的扇区,即从0到某个最大值方式排列。
C/H/S到LBA:
LBA=(C-c)*PH*PS+(H-h)*PS+(S-s)
一般情况下c=0,h=0,s=1,PS=63,PH=255,PS表示每磁道多少扇区,PH表示每柱面多少磁道。
LBA到C/H/S:
C=LBA/(PH*PS)+c
H=(LBA/PS)MOD PH +h
S=LBA MOD PS + s
由于MBR只能记录4个分区的信息,windows通过扩展分区来记录多于4个分区的记录,称
做虚拟MBR。
做法是:
让主MBR在定义分区时,将多余容量定义为扩展分区,指定该分区的起始位置,根据起始位置指向硬盘的某一扇区,作为下一个分区表,在该扇区继续定义分区。如果只有一个分区,就定义该分区,然后结束;如果不止一个分区,就定义一个基本分区和一个扩展分区,扩展分区再指向下一个分区表,在下一个分区表中继续定义分区,直至结束。这样就形成一个分区链,可以描述所有的分区。
一个分区表的例子:
MBR | 80 01 01 00 0C FE FF FF 3F 00-00 00 FC 8A 38 01 00 00 C1 FF 83 FE FF FF 3B 8B-38 01 6E 9A F6 00 00 00 C1 FF 82 FE FF FF A9 25-2F 02 E1 16 08 00 00 00 C1 FF 0F FE FF FF 8A 3C-37 02 62 43 53 07 55 AA |
EXT-1: | 00 01 C1 FF 0B FE FF FF 3F 00-00 00 37 16 71 02 00 00 C1 FF 05 FE FF FF 76 16-71 02 3B 8B 38 01 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA |
EXT-2: | 00 01 C1 FF 0B FE FF FF 3F 00-00 00 FC 8A 38 01 00 00 C1 FF 05 FE FF FF B1 A1-A9 03 2C D5 FB 02 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA |
EXT-3: | 00 01 C1 FF 0B FE FF FF 3F 00-00 00 ED D4 FB 02 00 00 C1 FF 05 FE FF FF DD 76-A5 06 3E 15 AC 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA |
EXT-4: | 00 01 C1 FF 0B FE FF FF 3F 00-00 00 FF 14 AC 00 00 00 C1 FF 05 FE FF FF 1B 8C-51 07 47 B7 01 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA |
EXT-5: | 00 01 C1 FF 07 FE FF FF 3F 00-00 00 08 B7 01 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA |
| |
(注意:系统在启动时按照分区链的顺序查分区,直到出所有分区,如果分区链形成一个环,就形成所谓硬盘"逻辑锁",导致系统无法启动,软盘也无法启动。由于windows启动过程在io.sys中决定的,可以查io.sys,将第一个55AA改成其他数值,程序还没开始查分区表就结束,就避开了对分区表的检测)
2.关于INT 13
2.1通过int 13来读取物理扇区的例子:
a100 mov ax,201 mov bx,200 mov cx,1 mov dx,80 int 13 int 3 g=100 |
|
参数解释:
∙ al:读写扇区数
∙ bx:缓冲区地址
∙ dh:磁头号
∙ dl:设备号(A盘是0,B是1,第一硬盘是80,第二硬盘是81)
∙ ch:柱面号低8位
∙ cl:低6位为要读的起始扇区号,高2位为柱面号的高2位。
2.2扩展INT 13:
数据类型约定:
BYTE | 1字节整型(8 位) |
WORD | 2字节整型(16 位) |
DWORD | 4字节整型(32 位) |
QWORD 东湖电影院 | 8字节整型(64 位) |
| |
磁盘地址数据包 Disk Address Packet (DAP):
DAP 是基于绝对扇区地址的, 因此利用 DAP, Int13H the creep可以轻松地逾
越 1024 柱面的限制, 因为它根本就不需要 CHS 的概念.
DAP 的结构如下:
struct DiskAddressPacket
{
BYTE PacketSize; // 数据包尺寸(16字节)
BYTE Reserved; // ==0
WORD BlockCount; // 要传输的数据块个数(以扇区为单位)
DWORD BufferAddr; // 传输缓冲地址(segment:offset,在内存中为offset在低地址
如166b:400在内存中为:00 04 6b 16)
QWORD BlockNum; // 磁盘起始绝对块地址(即LBA地址)
};
驱动器参数数据包 Drive Parameters Packet: 驱动器参数数据包是在扩展 Int13H 的取得驱动器参数子功能调用中 使用的数据包. 格式如下:
struct DriveParametersPacket
{
WORD InfoSize; // 数据包尺寸 (26 字节)
WORD Flags; // 信息标志
DWORD Cylinders; // 磁盘柱面数
DWORD Heads; // 磁盘磁头数
DWORD SectorsPerTrack; // 每磁道扇区数
QWORD Sectors; // 磁盘总扇区数
WORD SectorSize; // 扇区尺寸 (以字节为单位)
};
2.2.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.2.2) 扩展读
入口:
AH = 42h
DL = 驱动器号
DS:SI = 磁盘地址数据包(Disk Address Packet)
返回:
CF = 0, AH = 0 成功
CF = 1, AH = 错误码
这个调用将磁盘上的数据读入内存. 如果出现错误, DAP 的BlockCount
项中则记录了出错前实际读取的数据块个数.
2.2.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项中则记录了出错前实际写入的数
据块个数.
2.2.4) 校验扇区
入口:
AH = 44h
DL = 驱动器号
DS:SI = 磁盘地址数据包(Disk Address Packet)
返回:
CF = 0, AH = 0 成功
CF = 1, AH = 错误码
这个调用校验磁盘数据,但并不将数据读入内存.如果出现错误, DAP 的
BlockCount 项中则记录了出错前实际校验的数据块个数.
2.2.5) 锁定/解锁驱动器
入口:
AH = 45h
AL
= 0 锁定驱动器
= 1 驱动器解锁
= 02 返回锁定/解锁状态
= 03h-FFh - 保留
DL = 驱动器号
返回:
CF = 0, AH = 0 成功
CF = 1, AH = 错误码
这个调用用来缩定指定驱动器中的介质.
所有标号大于等于 0x80 的可移动驱动器必须支持这个功能.如果
在支持可移动驱动器控制功能子集的固定驱动器上使用这个功能调用,将
会成功返回.
驱动器必须支持最大255次锁定, 在所有锁定被解锁之前,不能在物理上
将驱动器解锁. 解锁一个未锁定的驱动器,将返回错误码 AH= B0h.如果锁定一
个已锁定了255次的驱动器, 将返回错误码 AH = B4h.
锁定一个没有介质的驱动器是合法的.
2.2.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.