从驱动器读取扇区失败

时间:2018-05-05 20:57:23

标签: assembly interrupt x86-16 bios osdev

我正在尝试制作一个非常基本的2阶段引导加载程序,我遇到了阅读第二阶段的问题。当我尝试将int 13hah = 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

1 个答案:

答案 0 :(得分:2)

问题1(由Michael Petch解决)

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

Problem2

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

由于您编写了[org 0x7c00],因此缺少的设置是设置DS=0

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

Problem3

视频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