异想天开

What's the true meaning of light, Could you tell me why

bios 13h读取硬盘

日期:2015-12-27 13:14:13
  
最后更新日期:2015-12-27 14:37:15
简单测试命令
Makefile:
[code lang="cpp"]
test: test.asm
nasm test.asm -o test.bin
sudo losetup /dev/loop0 ./a.img
sudo dd if=./test.bin of=/dev/loop0 bs=512 count=1
sudo losetup -d /dev/loop0
/usr/local/bochs_2.6/bin/bochs -f ./bochsrc2
[/code]

test.asm
[code lang="cpp"]
org 0x7c00

BUFF_OFFSET equ 0x1000

DISKID equ 0x80
RETSET_OP equ 0
READ_OP equ 0x2

start:
mov dl, DISKID
mov ah, RETSET_OP
int 0x13

xor ax, ax
mov es, ax
mov bx, BUFF_OFFSET
mov dl, DISKID
mov dh, 0
mov ch, 0
mov cl, 0x1
mov ah, READ_OP
mov al, 1
int 0x13
nop
nop
nop
times 510 - ($-$$) db 0
db 0x55,0xaa
[/code]
asm代码里面利用13h中断读取0x80硬盘,即虚拟机第一块硬盘。可以通过dd命令生成flat格式的虚拟硬盘,也可以利用bochs提供的bximage命令。
平坦格式的都无所谓。在bochsrc脚本添加硬盘配置:
ata0-master: type=disk, path="c.img", mode=flat
13h参数说明:
ah表示功能号 al表示读取的扇区数目
es:bx 表示读取到的内存缓冲区
ch 表示磁道号的低8位 cl 位7-6 表示磁道号的高2位,位5-0表示读取起始扇区号
dh 所读磁盘的磁头号 dl 磁盘驱动器号 0x0-0x7f表示软驱 0x80以上表示硬盘
出错则CF标记置1
13h中断读取的时候,有几点需要注意:
1. 起始扇区是从1开始,谁说的程序员都是从0开始
2. 该读取缓冲es:bx限制,一次最多只能读取64k,即128扇区
3.利用磁头/柱面/扇区 读取限制了大小,cylinder 最大只支持 0x3ff,head 最大只支持 0xff,sector 最大只支持 0x3f,故这种读取的范围最大为8G
扩展:
还有一种更好的办法,利用逻辑扇区的办法读取硬盘,输入的参数位一个结构体,见参考
int 0x13 的扩展读(ah = 0x42) 不喜欢抱着大块头汇编手册啃,好歹这样写可以更简洁,且行且珍惜吧。
测试例子:
[code lang="cpp"]
org 0x7c00

STACKTOP equ 0x7c00

START_SEC equ 0x0
BUFF_SEG equ 0x7c1
BUFF_OFFSET equ 0x0
STRUCT_SIZE equ 0x10
READ_SECTORS equ 129
LONG_BUFFOFFSET equ 0

DISKID equ 0x80
RETSET_OP equ 0
READ_OP equ 0x2
READ_EXT_OP equ 0x42

start:
mov dl, DISKID
mov ah, RETSET_OP
int 0x13

mov ax, cs
mov es, ax

cli
mov ss, ax
mov sp, STACKTOP
sti

push dword LONG_BUFFOFFSET
push dword START_SEC
push word BUFF_SEG
push word BUFF_OFFSET
push word READ_SECTORS
push word STRUCT_SIZE

mov ah, READ_EXT_OP
mov dl, DISKID
mov si, sp
int 0x13

nop
nop
nop
times 510 - ($-$$) db 0
db 0x55,0xaa
[/code]
在bochs里面利用逻辑扇区读取,发现一次读取可以超过129扇区,可以发现利用逻辑扇区,自动处理了跨段的问题。