Autor Thema: Kernel stürzt ab  (Gelesen 6874 mal)

TheThing

  • Beiträge: 105
    • Profil anzeigen
Gespeichert
« am: 17. June 2008, 10:01 »
Hi. ich hab mir einen kleinen Kernel geschrieben (hab noch so gut wie keine Ahnung von allem), der von GRUB gebootet werden soll und danach in den Protected Mode springt. Leider startet der PC, nachdem ich meinen Kernel ausgewählt habe, immer neu. Virtual PC meldet einen unbehebbaren Prozessorfehler. Bootloader ist GRUB 0.97. Hier mein Code:


; --------------- MULTIBOOTHEADER FÜR GRUB ---------------
_mbh:
Multiboot_Magic equ 0x1BADB002
Multiboot_Flags equ 0x00010000
Multiboot_Checksum equ -Multiboot_Magic-Multiboot_Flags
Multiboot_HeaderOffset equ 0x00100000+_mbh

dd Multiboot_Magic
dd Multiboot_Flags
dd Multiboot_Checksum
dd Multiboot_HeaderOffset
dd 0x00100000
dd 0x00100000+_end
dd 0x00100000+_end
dd 0x00100000+_start


; --------------- KERNEL ---------------
_start:
; jetzt gehen wir in den Protected Mode
jmp afterdeskriptor      ; jetzt werden die drei wichtigen Deskriptoren erzeugt
NULL_Desc:
dd 0
dd 0
CODE_Desc:   ; ein Code-Deskriptor für den Kernel
dw 0xFFFF
dw 0
db 0
db 0x9A
db 0xCF
db 0
DATA_Desc:    ; und noch einen Data-Deskriptor für den Kernel
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt:            ; Daten für die Global Deskriptor Table
Limit dw 0
Base dd 0
afterdeskriptor:   ; alle Deskriptoren erzeugt und übersprungen, also gehts hier weiter
; Protected Mode, wir kommen!
cli   ; keine Interrupts
mov eax, cs
mov ds, ax

; jetzt müssen wir den Deskriptor ändern, weil wir den Kernel nicht mit Code-Segment+16Bit-Adresse erreichen können
shl eax, 4
mov [CODE_Desc+2], ax
mov [DATA_Desc+2], ax
shr eax, 16
mov [CODE_Desc+4], al
mov [DATA_Desc+4], al
; Jetzt wird die GDT mit Daten gefüllt:
mov eax, cs
shl eax, 4
add eax, NULL_Desc
mov [Base], eax
mov [Limit], WORD gdt - NULL_Desc - 1
; GDT wird geladen
lgdt [gdt]
; Jetzt gehts in den Protected Mode
mov eax, cr0 ; cr0 in eax laden
or eax, 1    ; Das erste Bit auf 1 setzen
mov cr0, eax ; cr0 zurückschreiben
; jetzt noch den FAR JUMP, cs laden und Prefetch leeren
db 0xea
dw PMODE
dw 0x8

[bits 32]  ; Die 16-Bit vorbereitungen sind fertig, jetzt gehen wir auf 32 Bit
;%macro PM_Print 4   ; x, y, zeichen, attribut     ; unser Macro zum schreiben
; ;;;;;;;mov ax, %2*80+%1  ;offset errechnen
; mov ax, %2
; mov bx, 80
; mul bx
; add ax, %1
; add ax, 0xB8000
; mov bx, %3
; or bx, %4
; mov [ax], bx
;%endmacro

PMODE:          ; hierhin wird geJUMPt
mov WORD [CODE_Desc+2], 0    ; Deskriptoren wieder zurücksetzen
mov WORD [DATA_Desc+2], 0
mov WORD [CODE_Desc+4], 0
mov WORD [DATA_Desc+4], 0

mov eax, 2  ; Index 2 der GDT auswählen (also 3.  Eintrag)
shl eax, 3  ; Im Selektor beginnt der Index erst ab Bit 3
mov ds, ax
mov es, ax
mov ss, ax
mov eax, 0
mov fs, ax
mov gs, ax  ; FS und GS auf NULL Deskriptor zeigen lassen
mov gs, ax
mov esp, 0x1FFFFF  ; esp (stack) auf 2 MB setzen

; weil wir den Deskriptor verändert haben, müssen wir noch einmal FAR JUMPen, damit alles richtig geladen wird
jmp 0x8:0x10000 + main
main:         ; wir sind endlich im MAIN-Teil des Kernels angekommen! PARTY!!!
;PM_Print 40, 10, 72, 0x14
;jmp main
jmp main



_end:

achja: mein Makro für die Textausgabe funktioniert auch nicht. Der Code lässt sich dann nicht assemblieren. NASM meldet irgendwas mit invalid segmen/addres oder so. Weiß da jemand warum?
« Letzte Änderung: 17. June 2008, 10:03 von TheThing »

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 17. June 2008, 12:23 »
1. Grub schaltet dir den Protected Mode schon ein. Du befindest die also sofort im 32Bit PMode d.h. das RealMode-Addressberechnungs-Zeug brauchst du nicht.
2. Du solltest also nur noch eine neue GDT initialisieren.( Empfehlens Wert ist Base: 0; limit 4GB; für alle descriptoren)
3. Wie linkst du denn den Kernel? das +0x100000 in den Adressen solltest du nicht brachen.
4. Empfehlen ich dir das ELF-Object-Format zu verwenden, dann brauchst du im MBH das zeug nach der Checksum nicht mehr. (das entsprechende Flag musst du dann natürlich auch löschen)

5.jmp 0x8:PMode funktioniert Prima, du brauchst das nicht per Hand mit 'db ..' machen.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 17. June 2008, 13:07 »
6. Nimm als Emulator besser qemu oder für den Anfang noch besser bochs, ist hilfreicher beim Debugging.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #3 am: 17. June 2008, 13:24 »
7. In dem Lowlevel-Wiki gibts Tutorials zu grub, die könnten die evtl helfen. :-)
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

TheThing

  • Beiträge: 105
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 18. June 2008, 07:55 »
oh, danke :-)
Leider hab ich das mit den Flags noch nicht so ganz drauf... Hat jemand vielleicht eine komplette Tabelle, welche Flags für was sind? In den tuts hab ich das nicht kapiert...

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #5 am: 18. June 2008, 12:40 »
Die von grub/multiboot? Wenn ja, dann in der Multiboot Specification.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

TheThing

  • Beiträge: 105
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 19. June 2008, 11:28 »
wie muss ich nasm aufrufen, damit ich elf als output kriege?  :?

Korona

  • Beiträge: 94
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 19. June 2008, 11:38 »
nasm -f elf ...
Siehe auch das NASM Manual.

 

Einloggen