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
Repository mit diesem Beispiel arbeiten: https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/osdev –