【问题标题】:Reading Sector From Drive Fails从驱动器读取扇区失败
【发布时间】:2018-10-16 01:35:16
【问题描述】:

我正在尝试制作一个非常基本的 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

【问题讨论】:

  • 使用 CHS (Cylinder/Head/Sector),扇区编号是从 1 开始,而不是 0。如果要读取磁盘上的第二个扇区,则需要使用 Sector 2 (cl), Head 0,Cylinder 0。您的代码可能失败,因为读取扇区 0 无效。
  • @MichaelPetch 就是这样,非常感谢

标签: assembly interrupt x86-16 bios osdev


【解决方案1】:

问题 1(由 Michael Petch 解决)

BIOS 返回“无效命令”错误,因为您已要求加载不存在的磁盘扇区 0。在 CHS 表示法中,Cylinder 编号从 0 开始,H前导数从 0 开始,但S矢量数从 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

【讨论】:

    猜你喜欢
    • 2021-06-19
    • 2020-02-22
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 2010-12-17
    • 1970-01-01
    • 2012-04-11
    • 2019-01-04
    相关资源
    最近更新 更多