osdever provides a pretty nice introductory tutorial for basic kernel development targeting the IA-32 platform. It assumes development in Windows using DJGPP, however. I used Linux with GCC, so things were a bit different.
First, to link between assembly and C routines, the tutorial prefaces methods and variables with an underscore. With the version of GCC ld I use, this is not necessary (and doesn't work by default). The easy fix: just remove the leading underscores. For example, in start.asm, change the following:
call _main
to:
call main
Second, they use what they call the "aout hack" to get multiboot working. It sure looks from the code that they do the Right Thing, but it just didn't work for me. I couldn't get GRUB to load the image. So, I changed to the ELF file format. I did this by making sure that NASM produced that format from source.asm, as in:
I also modified the ld script to produce ELF output:
ENTRY(start)
phys = 0x00100000;
[... and so forth ...]
Finally, I commented out the "aout hack" code from source.asm:
; Multiboot macros to make a few lines later more readable
MULTIBOOT_PAGE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_INFO equ 1<<1
MULTIBOOT_AOUT_KLUDGE equ 1<<16
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
; MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
[... and so forth ...]
I also wanted to use the IA-32 emulator, bochs, to test my code. The tutorial insinuates that this can be done, but doesn't really explain how. At first, I did it by simulating two floppies, one with GRUB and the other without. Later, I switched to simulating one harddisk with GRUB and the kernel image.