BIOS int 0x13 失败但没有错误
我正在编写一个用于教育用途的引导加载程序,并且运行良好。但是当我尝试在真机上启动时,我的磁盘读取代码无法加载某些扇区。没有给出错误代码,也没有设置 CF。它还在 al 中返回 1,这意味着已读取 1 个扇区(这应该是正确的)。但是当我尝试跳转到加载的扇区时,它只是挂起并且不执行任何操作。第一阶段打印一个 A,第二阶段用 F 覆盖。当您使用真实硬件启动时,仅显示 A。所以该扇区不在内存中应有的位置。
这是我的 MBR:
LOADOFF equ 0x7C00
BUFFER equ 0x600
[bits 16]
[org 0x7c00]
jmp _start
nop
bootdisk db 0
_start: ; entry point
jmp 0x0:.flush
.flush:
xor ax, ax
mov ds, ax
mov es, ax
cli
mov ss, ax
mov sp, LOADOFF ; stack setup
sti
mov [bootdisk], dl ; boot drive number given by the bios in dl
mov si, migrate ; move the code below to the buffer
mov di, BUFFER
mov cx, 256
cld
rep
movsw
jmp 0x0:BUFFER ;get my ass in the buffer
migrate:
.reset:
xor ax, ax ; reset the disk
mov dl, [bootdisk]
int 0x13
jc .reset
.read:
mov ah, 0x2
mov al, 1 ; read 1 sector
xor cx, cx ; cylinder 0
mov cl, 2 ; sector 2
mov dl, [bootdisk]
xor dh, dh ; head 0
; setup buffer
xor bx, bx
mov es, bx
mov bx, 0x7c00 ; chain load it
int 0x13
jc .read
test ah, ah
jnz .reset
cmp al, 0x1 ; is there one and only one sector loaded?
jne .reset
mov ax, 0xb800
mov es, ax
xor di, di
mov al, 65 ; capital A
mov ah, 0xc
stosw
; mov ax, 0x7c0
; mov es, ax
; xor di, di
;
; mov [es:di], byte 191 ; this code proves that my far jump does its work
; mov [es:di+1], byte 160 ; if you would like to test, comment it out.
; mov [es:di+2], byte 128
; mov [es:di+3], byte 184
; mov [es:di+4], byte 0
; mov [es:di+5], byte 176
; mov [es:di+6], byte 142
; mov [es:di+7], byte 192
; mov [es:di+8], byte 184
; mov [es:di+9], byte 88
; mov [es:di+10], byte 14
; mov [es:di+11], byte 171
jmp 0x0:0x7c00 ; execute the loaded sector
times 510 - ($ - $$) db 0
dw 0xAA55
ORG 0x7C00
[BITS 16]
第 2 阶段:
stage2:
mov ax, 0xb800
mov es, ax
xor di, di
mov al, 70
mov ah, 0xc
stosw
jmp $
times 512 - ($ - $$) db 0
它在 kvm 中完美运行,但在具有真实 BIOS 的真实硬件上却无法运行。我使用 USB 闪存驱动器在真实硬件上测试启动。
问题可能是我没有在 mbr 的第一个字节定义的 BPB 吗?我不这么认为,因为我只是阅读原始扇区......如果我错了,请纠正我。
有人知道它可能是什么吗?
谢谢
I'm writing a bootloader for educational use and it goes quit well. But when I tried to boot on a real machine my disk read code fails to load some sectors. No error code is given nor is the CF set. It also returns 1 in al which means that 1 sector has been read (which should be correct). But when I try to jump to the loaded sector it just hangs and does nothing.. The first stage prints an A which the second stage overwrites with an F. Only the A is shown when you boot with real hardware. So the sector is not in memory where it should be..
This is my MBR:
LOADOFF equ 0x7C00
BUFFER equ 0x600
[bits 16]
[org 0x7c00]
jmp _start
nop
bootdisk db 0
_start: ; entry point
jmp 0x0:.flush
.flush:
xor ax, ax
mov ds, ax
mov es, ax
cli
mov ss, ax
mov sp, LOADOFF ; stack setup
sti
mov [bootdisk], dl ; boot drive number given by the bios in dl
mov si, migrate ; move the code below to the buffer
mov di, BUFFER
mov cx, 256
cld
rep
movsw
jmp 0x0:BUFFER ;get my ass in the buffer
migrate:
.reset:
xor ax, ax ; reset the disk
mov dl, [bootdisk]
int 0x13
jc .reset
.read:
mov ah, 0x2
mov al, 1 ; read 1 sector
xor cx, cx ; cylinder 0
mov cl, 2 ; sector 2
mov dl, [bootdisk]
xor dh, dh ; head 0
; setup buffer
xor bx, bx
mov es, bx
mov bx, 0x7c00 ; chain load it
int 0x13
jc .read
test ah, ah
jnz .reset
cmp al, 0x1 ; is there one and only one sector loaded?
jne .reset
mov ax, 0xb800
mov es, ax
xor di, di
mov al, 65 ; capital A
mov ah, 0xc
stosw
; mov ax, 0x7c0
; mov es, ax
; xor di, di
;
; mov [es:di], byte 191 ; this code proves that my far jump does its work
; mov [es:di+1], byte 160 ; if you would like to test, comment it out.
; mov [es:di+2], byte 128
; mov [es:di+3], byte 184
; mov [es:di+4], byte 0
; mov [es:di+5], byte 176
; mov [es:di+6], byte 142
; mov [es:di+7], byte 192
; mov [es:di+8], byte 184
; mov [es:di+9], byte 88
; mov [es:di+10], byte 14
; mov [es:di+11], byte 171
jmp 0x0:0x7c00 ; execute the loaded sector
times 510 - ($ - $) db 0
dw 0xAA55
ORG 0x7C00
[BITS 16]
Stage 2:
stage2:
mov ax, 0xb800
mov es, ax
xor di, di
mov al, 70
mov ah, 0xc
stosw
jmp $
times 512 - ($ - $) db 0
It works perfectly in kvm, but NOT on real hardware with a real bios. I use an USB flash drive to test boot on real hardware.
Could the problem be the BPB which I do not define at the first bytes of my mbr? I don't think so because I just read raw sectors.. correct me if I'm wrong.
Anyone any clue what it could be?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的代码尝试从“第一个软盘驱动器”磁盘 0 加载。现代 HDD(和 USB 闪存盘)通常作为磁盘
0x80
进行访问。所以只要尝试一下你的代码。
Your code tries to load from disk 0 which ist "first floppy drive". Modern HDD (and USB flash disks) ususally are accessed as disk
0x80
. So just tryin your code.