[OS programming] Ładowanie kernela

0

à propos tematu o ORG - chciałem napisać mały system: boot.s (bootloader, ładuje loader), start.s (loader, ustawia ekran, gdt i skacze do kernela), kernel.c (niech się ładnie wita ;)

Bootloader działa bezproblemowo, ładuje z 2 sektora dyskietki kernel pod adres 0800h:0000h i skacze tam. Start.s ustawia ekran, ładuje tablice GDT (wpisy są na pewno dobre) i... może dam kod:

cli
xor ax, ax
mov ds, ax
lgdt [gdt_decr]
jmp .pmode

.pmode:   
mov eax, cr0
or eax, 1
mov cr0, eax
      
jmp _start32 ; (*)

[BITS 32]
[EXTERN main]
_start32:
mov ax, 08h    ;08h to selektor dla sekcji kodu
mov ds, ax
mov ss, ax
         
jmp main
jmp $

kernel.c:

void main(void){
funkcja_do_drukowania();
for(;;);
}

Oba pliki kompiluje jako ELF (bo pisze pod linuksem) i linkuje - wszystko niby ok. Po uruchomieniu pod Bochsem OS albo się resetuje albo robi coś dziwnego w pamięci. Próbowałem też pisać

jmp 08h:main

ale nic z tego. To samo przy (*) w start.s. Powinno tam być chyba

jmp 08h:_start32

ale wtedy nie działa.

Bochs twierdzi, że wchodze do PMode a CS=0800h.

Nie wiem co robie tutaj źle :(

0

na pewno musi być

 jmp 08h : _start   ; musisz przeładować cs 

poza tym, chyba ds musi być ustawione na 0800h przed lgdt [gdt_decr] - zamień xor ax, ax na mov ax, 0800h
jeżeli to nie to, to może podaj jak masz ustawione deskryptory
aha bym zapomniał .... po co ci to:

jmp .pmode
.pmode:
0

Dzięki za szybką odpowiedź.
Tamte

jmp .pmode

to tak przez pomyłkę ;)

No więc próbowałem tak jak radziłeś, ale nadal nie działa. Moje gdt:

gdt:     ;bo GDT
         dd 0           ;NULL descriptor
         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
gdt_end: ;eo GDT

gdt_descr ;we wcześniejszym przepisywaniu to była literówka gdt_decr :>
         dw gdt_end - gdt - 1
         dd gdt

Takie gdt występuje w większości kursów w ogóle, sam też to analizowałem i wygląda dobrze.
W kursie na 4programmers jest napisane jeszcze o ustawieniu rejestrów segmentowych po przejściu do PMode.

load_gdt:lgdt [gdt_descr]

pmode:   mov eax, cr0
         or eax, 1
         mov cr0, eax   

         mov ax, 10h    
         mov ss, ax
         mov ds, ax
         mov es, ax
         mov fs, ax
         mov gs, ax

Wcześniej robiłem to jeszcze w RM i wtedy niby działało, ale kiedy chce to zrobić w ten sposób loader wywala się na:

mov ss, ax

Kiedy cały ten kod umieszcze w samym bootsectorze - wszystkie segmenty ustawiają się bezproblemowo... przestaje działać dopiero potem - problemy z linkowaniem :>

Może tu chodzi o to, że loader jest już wcześniej ładowany przez bootsector?

[BITS 16]
[GLOBAL _start]
[ORG 7C00h]

_start:  mov ah, 2
         mov al, 10
         xor ch, ch
         mov cl, ah
         xor dh, dh
         mov bx, 0800h
         mov es, bx
         xor bx, bx
read: int 13h
         jc read

         jmp 0800h:0000h

fin:     times 510-($-$$) db 0
         db 55h
         db 0AAh

Musze dodawać jeszcze jakieś offsety/inaczej ustawić segmenty?

0

Coś mi się wydaje że trzeba skorzystać z org 0x8000... bo przeciez w tym momencie ( RM ) masz adresowanie przez DS(które jest różne od zera a więc ma znaczenie ) i to on zapewnia dobre adresowanie, ale kiedy przechodzisz do trybu chronionego powinieneś już do wszystkich danych dodawać 0x8000... tak mi się wydaje - może to przez ten szczegół wszystko sie psuje?

0

Czyli lgdt [gdt_descr] wykonuje jeszcze normalnie?
Zmieniłem tam dalej:

gdt_descr:
         dw 8*3 - 1
         dd 8000h+gdt ;albo 0800h + gdt, już sam nie wiem

Ale nadal wywala się przy

mov ss, ax

ORG nie mogę tutaj dać, bo to plik ELF.

0

Ok, dla przyszłych pokoleń ;)

jmp 08h:8000h+_start32   ;bo kod laduje własnie pod 0800h:000h
 
[BITS 32]
[EXTERN main]
 
_start32: 
         mov ax, 10h    ;[data segment]
         mov ss, ax
         mov ds, ax
         mov es, ax
         mov fs, ax
         mov gs, ax
 
         call main
         jmp $

1 użytkowników online, w tym zalogowanych: 0, gości: 1