J'apprends un peu de développement d'OS de OSDev.org. J'ai un noyau et j'essaye de démarrer dans GRUB Legacy (0.97) en utilisant qemu. Cependant, quand je tape kernel 200+9
, je reçois le messageLe noyau simple ne démarrera pas dans GRUB
[Multiboot-elf, <0x100000:0x80:0x4008>(bad), entry=0x10000c]
Voilà ce que je pense à l'exception de la partie (mauvais). Si je tape boot
maintenant GRUB se bloque juste.
Je pense que les nombres 0x100000, 0x44, 0x4008 représentent l'adresse de début de segment .text, l'adresse de début .bss et la taille de section .bss, respectivement. Je pense que cela, car l'exécution objdump -h
sur l'image du noyau donne cette sortie:
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
vous pouvez donc voir que les chiffres que je mentionnés correspondent presque. Le problème est qu'au lieu de 100044, le début de .bss est juste 44. Et je pense que c'est la raison pour laquelle GRUB dit mauvais. Je ne peux pas avoir une section inférieure à 1 Mo en mémoire (mémoire insuffisante). Mais objdump me dit que mes sections sont au-dessus de ce seuil, donc je ne sais pas ce qui ne va pas. Quoi qu'il en soit, je vais coller mon code ci-dessous, c'est relativement court. Bien que ma question soit probablement très simple si vous avez déjà fait des dev de système d'exploitation, le code pourrait être superflu.
;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;
}
Ci-dessous mon script linker personnalisé:
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)
}
}
Et enfin, je construis le noyau avec les lignes suivantes:
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
Où stage1 et stage2 sont fichier de Grub Legacy et pad est un fichier de 750 octets (donc stage1 + stage2 + pad ont une taille de fichier de 102400 octets, soit 200 blocs, c'est pourquoi je démarre avec le noyau 200 + 9).
Enfin, je lance le noyau dans qemu:
qemu-system-x86_64 -fda floppy.img
Repository avec ce travail exemple: https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/osdev –