我正在尝试制作一个非常基本的2阶段引导加载程序,我遇到了阅读第二阶段的问题。当我尝试将int 13h
与ah = 2
一起使用时,中断失败,返回码为1(无效命令)。我正在使用nasm进行编译并使用qemu进行测试。我一直在测试是否使用qemu的控制台来检查地址0x8C00
并查看ax
和进位标志。我总是看到0x8C00
周围的内存为零,ax = 0x0101
并且进位标志已设置。
bootloader.s
[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
secondstage.s
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
答案 0 :(得分:2)
BIOS返回“无效命令”错误,因为您已要求加载不存在的磁盘扇区0.在CHS表示法中 C ylinder数字从0开始, H < / strong> ead number从0开始,但 S ector number从1开始 包含引导加载程序的扇区位于(0,0,1)。如果你的第二阶段是在下一个更高的部门(但如果你选择的话可能在其他任何地方!)那么你需要要求扇区(0,0,2)。
mov cx, 0002h ;Cylinder 0, Sector 2
假设DS
段注册指向引导加载程序,您的工作很危险。在这方面你不能相信BIOS!您唯一可以假设的是,您的引导加载程序位于线性地址0000h:7C00h的内存中,DL
寄存器保存引导驱动器的代码。
由于您编写了[org 0x7c00]
,因此缺少的设置是设置DS=0
xor ax, ax <<===
mov ds, ax <<===
mov [driveNum], dl
视频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