Перезагрузите цикл при попытке загрузить ядро - PullRequest
0 голосов
/ 15 сентября 2018

Когда я пытаюсь загрузиться на 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 голосов
/ 28 сентября 2018

У этого кода много проблем.

Прежде всего, убедитесь, что процессор не выполняет 0x00.

В строке 3 у вас есть bootdrive db 0.Он должен выглядеть следующим образом:

[BITS 16]
[ORG 0x7C00]
jmp main
bootdev db 0
main:

Во-вторых, вы пытаетесь присвоить DL слово (указатель bootdev). Это неверно. Оно должно выглядеть следующим образом:

mov dl,[bootdev]

И вы пытаетесь прочитать заголовок: 0 Цилиндр / гусеница: 0 и сектор 2. Вы думаете, что он будет загружен по адресу BX, который равен 0x1000.но он будет загружаться со скоростью [ES: BX]. Если вы хотите перейти 0x1000, то убедитесь, что ES равен 0.

xor ax,ax ;AX is 0 now.
mov es,ax ;Thats how you reset ES.

Вы должны включить A20 перед загрузкой GDT.

Ваш новыйкод должен выглядеть следующим образом:

[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" в верхнем левом углу.

Счастливого кодирования!

...