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