从驱动器读取扇区失败



我正在尝试制作一个非常基本的 2 阶段引导加载程序,但在阅读第二阶段时遇到了问题。当我尝试将int 13hah = 2一起使用时,中断失败,返回码为1(无效命令(。我正在使用 nasm 编译并使用 qemu 进行测试。我一直在测试它是否使用 qemu 的控制台来检查地址0x8C00并查看ax和携带标志。我总是看到0x8C00周围的内存被归零,ax = 0x0101并设置了进位标志。

引导加载程序。

[org 0x7c00]
[bits 16]
mov [driveNum], dl
mov ah, 0x0A
mov al, '-'
mov cx, 80
int 0x10
;read drive
mov ax, 0
mov es, ax
mov ah, 2
mov al, 1 ;sectors to read
mov ch, 0 ;cylinder
mov cl, 0 ;sector
mov dh, 0 ;head
mov dl, byte [driveNum] ; drive
mov bx, 0x8c00
int 13h

hang:
jmp $
driveNum: db 0xAA
times (510 - ($ - $$)) db 0
db 0x55
db 0xAA

第二阶段

jmp $
times 512 db 0xFF

编译方式

nasm -f bin bootloader.s -o bootloader
nasm -f bin secondstage.s -o secondstage
cat bootloader secondstage > boot

运行方式

qemu-system-x86_64 -fda boot

问题1(由Michael Petch解决(

BIOS 返回"无效命令"错误,因为您要求加载不存在的磁盘扇区 0。在CHS表示法中,C的ylinder数从0开始,Head数从0开始,但Setor数从1开始。
包含引导加载程序的扇区位于 (0,0,1(。如果你的第二阶段在下一个更高的扇区(但如果你选择的话,它可能在其他任何地方!(,那么你需要要求扇区(0,0,2(。

mov cx, 0002h    ;Cylinder 0, Sector 2

问题2

您危险地假设DS段寄存器指向您的引导加载程序。在这方面,您不能信任 BIOS!您唯一可以假设的是,引导加载程序位于内存中的线性地址 0000h:7C00h,并且DL寄存器保存引导驱动器的代码。

因为您编写了[org 0x7c00]缺少的设置正在设置DS=0

xor ax, ax             <<===
mov ds, ax             <<===
mov [driveNum], dl

问题3

视频BIOS功能"WriteCharacterAtCursorPosition"还需要显示BH页码,如果视频模式是图形模式,则还需要BL的颜色。请不要依赖任何您未检查的注册内容。所需要的只是写:

mov ax, 0A00h + '-'
mov bx, 0007h          <<===
mov cx, 80
int 10h

jmp $
times 512 db 0xFF

这将创建 514 个字节,比一个完整的扇区多 2 个字节。引导加载程序将读取 1 个 512 字节的扇区。从技术上讲,这里没有错误,但这可能表明存在一些误解。

jmp $
times (512 - ($ - $$)) db 255

最新更新