当我尝试在qemu上启动时,出现了无休止的重启循环,我能够将其范围缩小
call 0x1000
这是我第一次研究osdev,如果我做错了其他任何事情,请通知我:)提前谢谢!
[org 0x7c00]
[bits 16]
bootdrive db 0x00
xor ax,ax
mov ds, ax
mov ss, ax
mov sp, 0x9c00
mov bp, sp
mov [bootdrive], dl
mov bx, 0x1000
mov dh, 0x01
mov dl, bootdrive
loadkernel:
pusha
push dx
mov ah, 0x02
mov al, dh
mov ch, 0x00
mov dh, 0x00
mov cl, 0x02
int 0x13
pop dx
popa
setgdt:
cli
lgdt[gdtr]
call openA20
call EnablePmode
openA20:
push ax
mov ax, 0x2401
int 0x15
pop ax
ret
EnablePmode:
mov eax, cr0
or al, 1
mov cr0, eax
jmp (CODE_DESC - NULL_DESC) : Pmode
NULL_DESC:
dd 0
dd 0
CODE_DESC:
dw 0xffff
dw 0
db 0
db 10011010b
db 11001111b
db 0
DATA_DESC:
dw 0xffff
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdtr:
Limit dw gdtr - NULL_DESC - 1
Base dd NULL_DESC
[bits 32]
Pmode:
mov ax, DATA_DESC - NULL_DESC
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000
mov esp, ebp
call 0x1000
jmp $
times 510-($-$$) db 0
dw 0xaa55
答案 0 :(得分:0)
此代码有很多问题。
首先,确保CPU不执行0x00。
在第3行中,您有bootdrive db 0
。
它应该看起来像这样:
[BITS 16]
[ORG 0x7C00]
jmp main
bootdev db 0
main:
第二个是您正在尝试为DL分配一个单词(bootdev的指针)。这是不正确的。它看起来应该像这样:
mov dl,[bootdev]
您正在尝试读取Head:0圆柱体/ Track:0和Sector2。您认为它将加载到BX地址0x1000。但会加载到[ES:BX]。如果您要跳过0x1000, 然后确保ES为0。
xor ax,ax ;AX is 0 now.
mov es,ax ;Thats how you reset ES.
您应该在加载GDT之前启用A20。
您的新代码应如下所示:
[org 0x7c00]
[bits 16]
jmp main
bootdrive db 0x00
main:
xor ax,ax
mov ds, ax
mov ss, ax
mov sp, 0x9c00
mov bp, sp
mov [bootdrive], dl
mov bx, 0x1000
mov dh, 0x01
mov dl, [bootdrive]
loadkernel:
pusha
push dx
xor ax,ax
mov es,ax
mov ah, 0x02
mov al, dh
mov ch, 0x00
mov dh, 0x00
mov cl, 0x02
int 0x13
pop dx
popa
setgdt:
cli
call openA20
lgdt[gdtr]
call EnablePmode
openA20:
push ax
mov ax, 0x2401
int 0x15
pop ax
ret
EnablePmode:
mov eax, cr0
or al, 1
mov cr0, eax
jmp (CODE_DESC - NULL_DESC) : Pmode
NULL_DESC:
dd 0
dd 0
CODE_DESC:
dw 0xffff
dw 0
db 0
db 10011010b
db 11001111b
db 0
DATA_DESC:
dw 0xffff
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdtr:
Limit dw gdtr - NULL_DESC - 1
Base dd NULL_DESC
[bits 32]
Pmode:
mov ax, DATA_DESC - NULL_DESC
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000
mov esp, ebp
call 0x1000
jmp $
times 510-($-$$) db 0
dw 0xaa55
还有内核:
BITS 32
org 0x1000
Start:
mov eax,0xB8000
mov byte [eax],78
mov byte [eax+1],71
jmp $
它将在左上方打印红色背景的灰色“ N”。
快乐编码!