|
Grub defines a multiboot specification. Grub will enter protected mode and set up a preliminary GDT for a flat memory model. It then boots any ELF binary or other binaries packed in the a.out format. To create a minimal kernel, you need an assembly file that hardcodes the multiboot header, and a C file that gets control from the assembly. Of course, for more flexibility, you would want to define a header file, as grub's sample code shows (see multiboot.h, boot.S, kernel.c). See also the NetBSD tutorial. By default, the linker loads the .text section at a high address, and grub is going to complain "selected item cannot fit into memory". To fix this, we can either use a linker script, or run gcc as so: # grub cannot load the OS below 1M (0x100000) gcc -Wl,-Ttext,0x100000 loader.s kernel.c -o kernel.bin -ffreestanding -nostdlib mount -oloop=/dev/loop0,offset=$offset $image $mount cp kernel.bin $mount sudo sync Our OS will be loaded at 1M physically, but we can set up paging to map the kernel at a high address. Grub comes with a tool, mbchk, that checks the format of a Multiboot kernel. Grub doesn't seem to honor the video mode table flag, as the information returned by it doesn't have flag[11] set, and mbchk will complain when such bit is set: mbchk.c /* Reserved flags must be zero. */ if (mbh->flags & ~0x00010003) { fprintf (stderr, "%s: Non-zero is found in reserved flags (0x%lx).\n", filename, mbh->flags); return 0; } Now, for testing purposes, we need to print to screen. Grub's sample code provides a nice printf function. Also check out Section 7.5 "console.c 程序“ of the Linux-0.11 book. |