扩展int13h调用详解(修正)
一般多系统引导程序 (如 SmartFDISK, BootStar, PQBoot 等)都是将标准主引导记录替换成自己的引导程序, 在运行系统启动程序 之前让用户选择要启动的分区. 而某些系统自带的多系统引导程序 (如 lilo, NT Loader 等)则可以将自己的引导程序放在系统所处分区的第一个扇区中, 在 Linux 中即为 SuperBlock (其实 SuperBlock 是两个扇区).
注: 以上各步骤中使用的是标准 MBR, 其他多系统引导程序的引导过程与此不同.
第二部分 技术资料
第一章 扩展 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,即10H,指本结构所占用的存储空间) 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 |