У этого кода много проблем.
Прежде всего, убедитесь, что процессор не выполняет 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" в верхнем левом углу.
Счастливого кодирования!