2013-01-14 4 views
23

Ich lerne ein bisschen von OS-Entwicklung von OSDev.org. Ich habe einen Kernel und versuche in GRUB Legacy (0.97) mit qemu zu booten. Allerdings, wenn ich kernel 200+9 eingeben, erhalte ich die MeldungEinfache Kernel wird nicht in GRUB starten

[Multiboot-elf, <0x100000:0x80:0x4008>(bad), entry=0x10000c] 

Dies ist, was ich mit Ausnahme des (sehr schlecht) Teil erwarten. Wenn ich boot jetzt schreibe, hängt GRUB gerade.

Ich denke, die Zahlen 0x100000, 0x44, 0x4008 stehen für die Startadresse des .text-Segments, die .bss-Startadresse und die Abschnittsgröße .bss. Ich denke, dies weil objdump -h auf dem Kernel-Image läuft diese Ausgabe gibt:

kernel.bin:  file format elf32-i386 

Sections: 
Idx Name   Size  VMA  LMA  File off Algn 
    0 .text   00000044 00100000 00100000 00001000 2**4 
        CONTENTS, ALLOC, LOAD, READONLY, CODE 
    1 .bss   00004008 00100044 00100044 00001044 2**2 
        ALLOC 

So können Sie sehen, dass die Zahlen, die ich erwähnt fast zusammenpassen. Das Problem ist, dass anstelle von 100044 der Start von .bss nur 44 ist. Und ich denke, das ist der Grund, warum GRUB schlecht sagt. Ich kann keinen Abschnitt unterhalb von 1 MB im Speicher haben (geringer Speicher). Aber objdump sagt mir, dass meine Sektionen über dieser Schwelle sind, also weiß ich nicht, was los ist. Wie auch immer, ich werde meinen Code unten einfügen, es ist relativ kurz. Obwohl meine Frage wahrscheinlich sehr einfach ist, wenn Sie OS dev zuvor gemacht haben, so könnte der Code von außen sein.

;loader.s - contains the multiboot header for grub and calls the main kernel method 

global loader       ; making entry point visible to linker 
global magic       ; we will use this in kmain 
global mbd        ; we will use this in kmain 

extern kmain       ; kmain is defined in kmain.cpp 

; setting up the Multiboot header - see GRUB docs for details 
MODULEALIGN equ 1<<0     ; align loaded modules on page boundaries 
MEMINFO  equ 1<<1     ; provide memory map 
FLAGS  equ 0x03;MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field 
MAGIC  equ 0x1BADB002    ; 'magic number' lets bootloader find the header 
CHECKSUM equ -(MAGIC + FLAGS)  ; checksum required 

section .text 

loader: 

align 4 
    dd MAGIC 
    dd FLAGS 
    dd CHECKSUM 

; reserve initial kernel stack space 
STACKSIZE equ 0x4000     ; that's 16k. 

    mov esp, stack + STACKSIZE   ; set up the stack 
    mov [magic], eax     ; Multiboot magic number 
    mov [mbd], ebx      ; Multiboot info structure 

    call kmain       ; call kernel proper 

    cli 
.hang: 
    hlt         ; halt machine should kernel return 
    jmp .hang 

section .bss 

align 4 
stack: resb STACKSIZE     ; reserve 16k stack on a doubleword boundary 
magic: resd 1 
mbd: resd 1 

.

// kernel.c - Contains the main kernel method 

void kmain() { 
    extern unsigned int magic; 

    if (magic != 0x2BADB002) { 
    // Something went wrong 
    } 

    volatile unsigned char *videoram = (unsigned char *) 0xB800; 
    videoram[0] = 65; 
    videoram[1] = 0x07; 
} 

Unten ist mein benutzerdefinierte Linker-Skript:

ENTRY (loader) 

SECTIONS { 
    . = 0x00100000; 

    .text ALIGN (0x1000) : { 
     *(.text) 
    } 

    .rodata ALIGN (0x1000) : 
    { 
     *(.rodata*) 
    } 

    .data ALIGN (0x1000) : 
    { 
     *(.data) 
    } 

    .bss : 
    { 
     sbss = .; 
     *(COMMON) 
     *(.bss) 
     ebss = .; 
    } 

    /DISCARD/ : { 
     *(.eh_frame) 
     *(.comment) 
    } 
} 

Und schließlich baue ich den Kernel mit den folgenden Zeilen:

nasm -f elf -o loader.o loader.s 
gcc -c -o kernel.o kernel.c 
ld -T linker.ld -o kernel.bin loader.o kernel.o 
cat stage1 stage2 pad kernel.bin > floppy.img 

Wo stage1 und stage2-Datei von GRUB sind Vermächtnis und Pad ist jede 750 Byte Datei (So stage1 + stage2 + pad haben eine Dateigröße von 102400 Bytes oder 200 Blöcke, weshalb ich mit Kernel 200 + 9 boote).

Schließlich laufe ich den Kernel in qemu:

qemu-system-x86_64 -fda floppy.img 
+0

Repository mit diesem Beispiel arbeiten: https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/osdev –

Antwort

22

+1 für schöne Frage mit allen Details, danke.

zumindest auf meinem Maschine kommt das erzeugte kernel.bin als 4869 Bytes aus, die 9. Auch in 10 Sektoren passt nur nicht, wird die VGA-Textspeicher an 0xb8000 nicht 0xb800 (noch eine Null - 0xb800 die Real-Mode-Segment ist, muss mit 16 multipliziert werden). Mit diesen kleinen Anpassungen funktioniert es hier gut.

+0

Wow, das Problem war mit 0xb800 ... dachte ich, es hing aber es war wirklich nicht einfach, den Charakter an die richtige Stelle zu stellen ... Obwohl ich immer noch verwirrt bin, was das bedeutet, dann: '<0x100000: 0x80: 0x4008> (schlecht)', da solltest du nicht sein erlaubt, ein Segment in wenig Speicher zu haben (wenn ich die Bedeutung der Zahlen richtig interpretiere) ... – gsingh2011

+0

Und um für andere ein bisschen zu klären, bootet es trotzdem, obwohl es (schlecht) sagt. – gsingh2011

+2

Es heißt '(schlecht)', wenn Sie nicht genügend Sektoren laden. Es kann immer noch funktionieren, wenn sich in diesem Teil nichts Wichtiges befindet. Hast du es mit '200 + 10' probiert? – Jester

Verwandte Themen