skeleton meaty cross compiler assembly kernel qemu osdev grub

assembly - meaty - Kernel simple no se iniciarĂ¡ en GRUB



osdev cross compiler (1)

+1 para una buena pregunta con todos los detalles, gracias.

Al menos en mi máquina el kernel.bin generado sale como 4869 bytes, que solo cabe en 10 sectores, no 9. Además, la memoria de texto VGA está en 0xb8000 no en 0xb800 (uno más cero - 0xb800 es el segmento de modo real, tiene que ser multiplicado por 16). Con esos pequeños ajustes funciona bien aquí.

Estoy aprendiendo un poco de desarrollo de SO de OSDev.org . Tengo un kernel y estoy tratando de arrancar en GRUB Legacy (0.97) usando qemu. Sin embargo, cuando escribo kernel 200+9 , obtengo el mensaje

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

Esto es lo que espero, excepto la parte (mala). Si escribo boot ahora GRUB simplemente cuelga.

Creo que los números 0x100000, 0x44, 0x4008 representan la dirección de inicio del segmento .text, la dirección de inicio .bss y el tamaño de la sección .bss, respectivamente. Creo que esto porque ejecutar objdump -h en la imagen del núcleo da esta salida:

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

Entonces puedes ver que los números que mencioné casi coinciden. El problema es que en lugar de 100044, el comienzo de .bss es solo 44. Y creo que esta es la razón por la que GRUB dice mal. No puedo tener una sección por debajo de 1 MB en memoria (memoria baja). Pero objdump me dice que mis secciones están por encima de ese umbral, así que no sé qué sucede. De todos modos, pegaré mi código a continuación, es relativamente corto. Aunque mi pregunta es probablemente muy básica si ya has hecho el desarrollo del sistema operativo antes, entonces el código podría ser extraño.

;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; }

A continuación está mi script del enlazador personalizado:

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) } }

Y finalmente, construyo el kernel con las siguientes líneas:

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

Donde stage1 y stage2 son archivos de GRUB Legacy y pad es cualquier archivo de 750 bytes (entonces stage1 + stage2 + pad tiene un tamaño de archivo de 102400 bytes, o 200 bloques, por eso reinicio con kernel 200 + 9).

Finalmente, ejecuto el kernel en qemu:

qemu-system-x86_64 -fda floppy.img