尝试加载内核时重启循环

时间:2018-09-15 12:05:20

标签: assembly x86 osdev

当我尝试在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

1 个答案:

答案 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”。

快乐编码!