当我尝试使用BIOS从磁盘读取时,我得到错误0x0C80,以下是我的代码:
disk_load:
push dx
mov ah, 0x42 ; BIOS extended read routine
mov dl, 0x80 ; Drive number (0x80 for the first HDD)
mov si, DAP ; DS:SI -> Disk Address Packet
int 0x13 ; BIOS Disk interrupt
jc disk_error
pop dx
cmp dh, al
jne disk_sectors_error
jmp disk_success
jmp disk_exit
DAP:
db 0x10 ; Size of DAP
db 0x00 ; Reserved
dw 16 ; Number of sectors to read, equal to value in dh
dw 0x1000 ; Offset to buffer
dw 0x0000 ; Segment of buffer
dq 1 ; Starting absolute block number (LBA)
disk_success:
mov bx, SUCCESS_MSG
jmp disk_exit
disk_error:
mov bx, DISK_ERR_MSG
call print_string
mov dh, ah ; AH contains the error code
call print_hex
jmp disk_loop
disk_sectors_error:
mov bx, SECTORS_ERR_MSG
call print_string
SUCCESS_MSG:
db "Disk was successfully read ", 0
DISK_ERR_MSG:
db "Disk read error! Error code: ", 0
SECTORS_ERR_MSG:
db "Incorrect number of sectors read ", 0
disk_loop:
jmp $
disk_exit:
ret
个字符
我需要读取前16个扇区并加载内核,然后进入32位保护模式并执行
我从Github中获取了代码的基础
Console的
我试着在互联网上搜索,但我找不到任何可以帮助我:(
1条答案
按热度按时间csbfibhn1#
关于
disk_load
字符串
您没有向我们显示'print_string.asm'或'print_hex.asm'的内容,因此我们无法检查AH是否在 print_string 调用中存活,或者 print_hex 是否期望输入DH!
错误代码0 Ch从IBM/MS INT 13扩展读取“不支持的轨道或无效的媒体”。
这可能是因为你使用了一个硬编码的驱动器号,就像在
mov dl, 0x80 ; Drive number (0x80 for the first HDD)
中一样。你确实把BIOS给你的 * Boot _DRIVE* 代码传递给了你的 disk_load 例程,那么你为什么要覆盖它呢?另外,如果你不打算使用DH中的扇区计数,而只是信任磁盘地址包中已经硬编码的值,那么在DH中传递扇区计数有什么意义呢?对于 KERNEL_OFFSET 参数也是如此。正如@拿骚在评论中所写的,确保你用qemu创建的磁盘映像至少包含这16个扇区。
型
“ExtendedRead”函数不报告通过AL寄存器成功传输的块数!在DAP中查找此信息。
在可能失败时,您可以打印一条合适的消息,但允许CPU开始执行文本消息!这些消息属于最后的
disk_exit:
ret
。这样,disk_sectors_error 代码可以正确地落入disk_loop:
jmp $
代码。关于IBM/MS INT 13扩展
永远不要只是假设这些扩展是可用的!它们带有一个“安装检查”功能,将通知您有关其功能。使用它:
型
如果扩展不可用,则使用适当的消息中止或回退到正常的CHS(HackderHeadSector)功能。
bootloader
BIOS将我们的 Boot 驱动器存储在DL中,所以最好记住这一点以备后用。(记住BIOS在 Boot 时将我们的 Boot 驱动器设置在'dl'中)
你的评论是正确的,但它比这更深入。DL是唯一的寄存器,保证在启动 Bootstrap 时保存有意义的值。你必须自己设置段寄存器和堆栈指针,而不是相信BIOS已经为你做了这些。
%include“OS/boot/print_string_pm.asm”
%include“OS/boot/switch.asm”
%包含“OS/boot/gdt. asm”
切换到保护模式不是 Bootstrap 应该做的事情!它属于内核的设置代码。
%include“OS/boot/print_string. asm”
%include“OS/boot/print_hex. asm”
%include“OS/boot/disk_load.asm”
为什么你有这么多的包含文件?它们所做的工作并不足以证明一个单独的文件是正确的,更重要的是,它们诱使你犯这些错误。我指的是引导加载程序和 disk_load 之间的参数不匹配,以及 disk_load 和 print_hex 之间的参数不匹配。
只需在引导加载程序源代码中插入它们的实际源代码文本。
型