Page 1 of 1
Thinking about executable formats for my kernel.
Posted: Fri Mar 28, 2008 4:28 pm
by wilsonsamm
G'day mates, I've started work on Brother Samuel's Magical Operating System. I'm coding it in assembler since I haven't gotten my head around a decent high-level programming language.
Well I started off rolling my own bootloader so that I would know precisely how everything worked, and then I thought, you know, I can't be bothered with this.
Then I wondered, how do I avoid this? I need to use a more standard boot loader. And that involves using a standard format for executables and so on.
And .COM files I know are so fairly simple. Just put a load of raw machine code at offset 0xFF in some sector of memory and off you go. I don't think this is the way the MS-DOS or CP/M kernels work, so I don't know if .COM is supported by LILO or GRUB or whatever.
How has everyone else solved this conundrum?
Posted: Fri Mar 28, 2008 4:53 pm
by Krox
I would advise using GRUB. It sets up 32Bit mode for you, gives you information about memory size and some more pretty nice stuff. A patched version even can init graphics mode. For the binary format you have the choice: Either using flat binary (nasm -f bin) with a very simple header (specified directly with some asm db/dd-instructions) or you use 32bit-elf object files, which can be loaded by GRUB. But I personally only have experience with the first version.
Posted: Fri Mar 28, 2008 5:37 pm
by wilsonsamm
What, oh, I was thinking of coding the header and things into the source code of the kernel. Do people reckon this is the wrong way to go about it?
What will the header need to contain?
Posted: Fri Mar 28, 2008 6:19 pm
by Krox
When you choose the binary format, the header can be located anywhere in the first few KB of the file. GRUB will find it by the magic value. Your Kernel gets loaded at 0x100000, exactly over the 1MiB mark. When GRUB starts your kernel it puts a magic value into eax, so the kernel can recognize it was loaded by grub. Furthermore, ebx contains a pointer to a really nice info-structure, where grub tells you about memory size and some other stuff. There are cuple of nice tutoirals and even a nice speicification an the official homepage (
link). Following is some code out of my kernel showing the header in asm syntax. You see, its fairly easy.
Code: Select all
; Macros for Multi Boot Header (there are more flags, search the specs)
MULTIBOOT_PAGE_ALIGN equ 1 << 0 ; make modules page aligned
MULTIBOOT_MEMORY_INFO equ 1 << 1 ; we want grub to give us some info about the memory size
MULTIBOOT_AOUT_KLUDGE equ 1 << 16 ; we will give some info about the kernel-img to grub
MULTIBOOT_MAGIC_HEADER equ 0x1BADB002 ; value for indicating the header
MULTIBOOT_MAGIC equ 0x2BADB002 ; value stored in eax on kernel-boot
MULTIBOOT_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_MAGIC_HEADER + MULTIBOOT_FLAGS)
ALIGN 4 ; GRUB only searches for aligned headers
MB_header:
dd MULTIBOOT_MAGIC_HEADER ; the magic number for multiboot headers (0x1BADB002)
dd MULTIBOOT_FLAGS ; flags - what we want grub to do and what we are doing
dd MULTIBOOT_CHECKSUM ; checksum of the header
; AOUT kludge (physical addresses)
dd MB_header ; multiboot header
dd KERNEL_START ; text-start
dd KERNEL_END ; text-end, bss-start
dd KERNEL_END ; bss end
dd start ; entrypoint
I cant tell you if it is "right" to use such binarys (and no ELF), but well, I like it and it simply works