自制OS从USB启动的BIOS设置与INT 0x13调用问题求助
用NASM编写INT 0x13调用实现USB启动(LBA模式)
嘿,我之前折腾自制OS从USB启动时也踩过一模一样的坑——传统的CHS(柱面/磁头/扇区)模式只适配软盘和老式硬盘,USB设备得用**LBA(逻辑块寻址)**的扩展BIOS调用才行,给你一步步拆解实操方案:
核心思路:放弃CHS,切换到INT 0x13扩展功能
USB设备在BIOS里会被识别为类硬盘存储设备,驱动器号从0x80开始(软盘固定是0x00),不能再用INT 0x13的传统读扇区功能(0x02),必须用功能号0x42的扩展读扇区调用,这个调用依赖DAP(Disk Address Packet)结构传递参数。
第一步:先验证BIOS是否支持LBA扩展
调用0x42之前,得先确认BIOS支持这个扩展功能,用INT 0x13的功能0x41做检测:
; 检查INT 0x13扩展支持 mov ah, 0x41 mov bx, 0x55AA mov dl, 0x80 ; USB设备驱动器号,通常是0x80(第一个硬盘/USB设备) int 0x13 jc no_lba_support ; CF置位=不支持扩展 cmp bx, 0xAA55 jne no_lba_support ; 返回BX不是0xAA55=不支持扩展
第二步:定义DAP结构
DAP是LBA模式下传递读写参数的标准结构,必须提前在内存中定义,NASM写法如下:
dap: db 0x10 ; DAP固定大小(16字节) db 0x00 ; 保留位,必须为0 dw 0x01 ; 要读取的扇区数(这里读1个,可按需修改) dw 0x7E00 ; 数据缓冲区的偏移地址(比如放在MBR之后的0x7E00) dw 0x0000 ; 数据缓冲区的段地址(实模式下0x0000:0x7E00 = 物理地址0x7E00) dq 0x01 ; LBA起始扇区号(这里读第2个扇区,MBR本身是第0扇区)
注:你的USB设备总共有15618048个扇区,所以LBA范围是0x00到0xE90FFF(15618047的十六进制)。
第三步:调用INT 0x13功能0x42读取扇区
把DAP的内存地址放到si寄存器,然后触发扩展调用:
; 执行扇区读取 mov ah, 0x42 mov dl, 0x80 ; USB驱动器号 mov si, dap ; 指向DAP结构的地址 int 0x13 jc read_error ; CF置位=读取失败
完整MBR示例代码
下面是一个简化的MBR代码,实现从USB读取第2个扇区到0x7E00并跳转执行:
org 0x7C00 bits 16 start: ; 初始化实模式段寄存器 xor ax, ax mov ds, ax mov es, ax mov ss, ax mov sp, 0x7C00 ; 栈顶设为MBR起始地址 ; 检查LBA扩展支持 mov ah, 0x41 mov bx, 0x55AA mov dl, 0x80 int 0x13 jc no_lba cmp bx, 0xAA55 jne no_lba ; 调用扩展读扇区功能 mov ah, 0x42 mov si, dap int 0x13 jc read_fail ; 读取成功,跳转到读取的扇区执行 jmp 0x0000:0x7E00 no_lba: mov si, msg_no_lba call print_str jmp $ ; 死循环 read_fail: mov si, msg_read_fail call print_str jmp $ ; 实模式字符串打印函数 print_str: mov ah, 0x0E .loop: lodsb or al, al jz .done int 0x10 jmp .loop .done: ret ; 提示信息 msg_no_lba db "BIOS不支持LBA扩展!", 0x0D, 0x0A, 0 msg_read_fail db "USB扇区读取失败!", 0x0D, 0x0A, 0 ; DAP结构定义 dap: db 0x10 db 0 dw 1 dw 0x7E00 dw 0 dq 1 ; MBR结束标志 times 510-($-$$) db 0 dw 0xAA55
关键注意事项
- 驱动器号适配:如果你的USB不是第一个存储设备,可能需要调整
dl的值(比如0x81对应第二个设备),部分BIOS会自动把启动USB设为0x80,保险起见可以做个简单遍历检测(0x80到0x8F)。 - 内存地址限制:实模式下只能访问1MB以下内存,所以缓冲区要放在0x7C00之后的安全区域,避免覆盖MBR本身。
- 错误码排查:INT 0x13调用失败时,
ah寄存器会返回错误码(比如0x01=无效命令,0x02=扇区未找到),可以根据错误码针对性排查问题。
内容的提问来源于stack exchange,提问作者石原秀一
相关产品推荐
相关产品推荐

