No se puede saltar o llamar al kernel cargado a 0x8000
Estoy tratando de desarrollar un sistema operativo. El diseño es el siguiente: tengo un cargador de arranque cargado a 0x7c00 que carga la segunda etapa y salta a ella a 0x7e00. La segunda etapa también está en modo real y hace muchas cosas, como cargar gdt, habilitar A20 y cambiar al modo protegido. También carga un kernel muy simple de 32 bits a 0x8000. El problema ahora es que no puedo llamar o jmp a 0x8000 ya que el núcleo no parece cargarse (hice un volcado de memoria enVirtualBox) Ya he hecho unJMP LEJOS dentro de la segunda etapa para establecer elCS registro. Estoy probando mi sistema operativo enVirtualBox.
Código para mi gestor de arranque:
org 0x7c00
bits 16
Start:
jmp Reset
bpbOEM DB "SKULLOS "
bpbBytesPerSector: DW 512
bpbSectorsPerCluster: DB 1
bpbReservedSectors: DW 1
bpbNumberOfFATs: DB 2
bpbRootEntries: DW 224
bpbTotalSectors: DW 2880
bpbMedia: DB 0xF0
bpbSectorsPerFAT: DW 9
bpbSectorsPerTrack: DW 18
bpbHeadsPerCylinder: DW 2
bpbHiddenSectors: DD 0
bpbTotalSectorsBig: DD 0
bsDriveNumber: DB 0
bsUnused: DB 0
bsExtBootSignature: DB 0x29
bsSerialNumber: DD 0xa0a1a2a3
bsVolumeLabel: DB "MOS FLOPPY "
bsFileSystem: DB "SKFS "
Set:
mov al , 02h
mov ah , 00h
int 10h
jmp Print
Print:
mov al , 'A'
mov bl , 0Fh
mov cx , 01h
mov ah , 09h
int 10h
jmp Reset
Reset:
; mov dl , 0x00
mov [0x500] , dl
mov ah , 0x00
int 0x13
jc Reset
mov ax , 0x7E0
mov es , ax
xor bx , bx
mov ah , 0x02
mov al , 1
mov ch , 0
mov cl , 2
mov dh , 0
mov dl , [0x500]
int 0x13
jmp 0x0000 :0x7e00
times 510-($-$$) db 0
db 0x55
db 0xAA
Código para la segunda etapa:
org 0x7E00
bits 16
Start:
jmp Setup
;;;;;;;;;;;;;stack;;;;;;;;;;
Setup:
cli
xor ax , ax
mov ds , ax
mov es , ax
mov ax , 0x9000
mov ss , ax
mov sp , 0xFFFF
sti
jmp Set
;;;;;;;;;;;;;video;;;;;;;;;;;
Set:
mov al , 03h
mov ah , 00h
int 10h
mov ah , 09h
mov al , 'A'
mov bh , 00h
mov bl , 0x0F
mov cx , 01h
int 10h
jmp loadgdt
;;;;;;;;;;;;gdt;;;;;;;;;;;;;;;
gdt_start:
null:
dd 0
dd 0
code:
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0
data:
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
end:
load: dw end - gdt_start -1
dd null
;;;;;;;;;;;;;loadgdt;;;;;;;;;;
loadgdt:
lgdt [load]
jmp A20
;;;;;;;;;;;;A20;;;;;;;;;;;;;;;
A20:
mov ax , 0x2401
int 0x15
jc A20
jmp Reset
;;;;;;;;;;;;;floppy;;;;;;;;;;;
Reset:
mov ah , 00h
mov dl , [0x500]
int 13h
jc Reset
jmp Read
Read:
mov ah , 02h
mov al , 01h
mov ch , 00h
mov cl , 03h
mov dh , 00h
mov dl , [0x500]
mov ax , 0x800
mov es , ax
xor bx , bx
int 13h
jc Read
jmp Begin
Begin:
mov ah , 09h
mov al , 'G'
mov bh , 00h
mov bl , 0x0F
mov cx , 01h
int 10h
jmp protected
;;;;;;;;;;;switching to protected;;;;
protected:
mov ah , 09h
mov al , 'P'
mov bh , 00h
mov bl , 0x0F
mov cx , 01h
int 10h
xor ax, ax
mov ds, ax
cli
mov eax, cr0
or eax , 1
mov cr0 , eax
jmp (code-gdt_start):transfer_control
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
bits 32
transfer_control:
mov ax, (data-gdt_start)
mov ds, ax
mov ss, ax
mov es, ax
mov esp, 90000h
mov [0xB8000], word 0x0F58 ; Print 'X'
call 0x8000
hlt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times 512-($-$$) db 0
Código para el núcleo:
org 0x8000
bits 32
jmp Start
Start:
mov ax , 0x10
mov ds , ax
mov ss, ax
mov es, ax
mov esp, 90000h
mov [0xB8002], word 0x0F58 ; Print 'X'
ret
times 512-($-$$) db 0
Actualmente, solo se está imprimiendo una 'X'. Sin embargo, se deben imprimir dos 'X'. Comandos utilizados para crear disquetes:
dd seek=0 if=boot of=os.img
dd seek=1 if=second_stage of=os.img
dd seek=2 if=third_stage of=os.img