MBR的功能就是读取PBR到0x7C00然后转移控制权,说到底就是对于磁盘的操作,如何读扇区。
根据资料得知,硬盘目前有三种工作模式:
1.NOMAL模式(支持最大容量为528MB)
2.LBA模式=Logical Block Addressing Mode(线性表示扇区,支持最大容量为137.4GB)
3.LARGE模式
PBR在什么位置决定了读取方式,而不是仅由硬盘容量判断。
比如一个2T硬盘,但PBR在528MB以内,则NOMAL模式就能读取。
当前已经实现了LBA方式读取PBR,貌似就是BIOS的扩展磁盘服务,其定义如下:
;BIOS服务中断定义 ;从下一设备启动 BIOS_BOOT_FROM_NEXT_DEVICE = 0x18 ;直接磁盘服务,功能号=AH,下面列出 BIOS_DIRECT_DISK_SERVICE = 0x13 ;复位驱动器 BIOS_DDS_RESET_DEVICE = 0x00 ;读取驱动器参数 ;成功返回值:DH=磁头,DL=驱动器数,CL低6位=扇区 BIOS_DDS_READ_DEVICE_PARAMETER = 0x08 ;读扇区 ;参数:AL=扇区数,CH=柱面,CL=扇区,DH=磁头 ;DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘 ;ES:BX=缓冲区的地址 BIOS_DDS_READ_SECTOR = 0x02 ;检测扩展DDS是否存在 ;参数:DL=驱动器,0x80=第一块硬盘,0x81=第二块硬盘...... BIOS_DDS_CHECK_EXTENSION = 0x41 ;扩展直接硬盘读写数据包结构 struct STRUCT_DDS_EXTENSION_PACK ;大小必须=0x10 Size db ? ;保留 Resvered1 db ? ;数据块数量 BlockCount dw ? ;缓冲区段偏移 BufferOffset dw ? ;缓冲区段值 BufferSegment dw ? SC_L dw ? SC_H dw ? ;未知=0 Unknown1 dd ? ends BIOS_DDS_EXTENSION_READ = 0x42 BIOS_DDS_EXTENSION_WRITE = 0x43通过LBA读取PBR的核心代码如下:
mov dl, [bp + STRUCT_PARTITION_TABLE.State];驱动器 mov ah, BIOS_DDS_CHECK_EXTENSION;参数 int BIOS_DIRECT_DISK_SERVICE jc .LoadPbrByLarge;不支持LBA模式,尝试LARGE模式(失败时CF=1) mov si, Pack_Extend mov ax, [bp + STRUCT_PARTITION_TABLE.InfoAreaSectors_L] mov [si + STRUCT_DDS_EXTENSION_PACK.SC_L], ax mov ax, [bp + STRUCT_PARTITION_TABLE.InfoAreaSectors_H] mov [si + STRUCT_DDS_EXTENSION_PACK.SC_H], ax mov ah, BIOS_DDS_EXTENSION_READ int BIOS_DIRECT_DISK_SERVICE jc .LoadPbrByLarge jmp 成功
至此,已经完成了MBR的工作,还要研究一下其他模式,以保证兼容性。
不过对于一般的活动分区都能用LBA模式读取,因此这一种模式是最常用的。