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 |
本分区扇区总数 |
(注意: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 132.1通过int 13来读取物理扇区的例子:
a100 mov ax,201 mov bx,200 mov cx,1 mov dx,80 int 13 int 3 g=100 |
参数解释:
2.2扩展INT 13: 数据类型约定:
BYTE |
1字节整型(8 位) |
WORD |
2字节整型(16 位) |
DWORD |
4字节整型(32 位) |
QWORD |
8字节整型(64 位) |
磁盘地址数据包 Disk Address Packet (DAP): DAP 是基于绝对扇区地址的, 因此利用 DAP, Int13H 可以轻松地逾 越 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 = 驱动器 |