I use qemu for testing, a GRUB image in drive a: and a raw copy of the linked kernel in drive b: and kernel (fd1)+100000 or so and then boot in GRUB.
It simply halts and prints nothing. I've tried printing individual characters out to the serial console and screen and various other tricks which do work, but anything involving strings or loops seems to fail.
loader.s
Code: Select all
.global _loader # making entry point visible to linker
# setting up the Multiboot header - see GRUB docs for details
.set ALIGN, 1<<0 # align loaded modules on page boundaries
.set MEMINFO, 1<<1 # provide memory map
.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum required
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
# reserve initial kernel stack space
.set STACKSIZE, 0x4000 # that is, 16k.
.comm stack, STACKSIZE, 32 # reserve 16k stack on a quadword boundary
_loader:
mov $(stack + STACKSIZE), %esp # set up the stack
push %eax # Multiboot magic number
push %ebx # Multiboot data structure
call k_main # call kernel proper
hlt # halt machine should kernel return
Code: Select all
void k_main() { // like main in a normal C program
int num;
char ch;
char *text_video = (char*)0xB8000;
char attrib = 0x07;
char *str="Kernel Loaded";
while(*str!=0) {
*text_video = *str;
*text_video++;
*text_video = attrib;
*text_video++;
*str++;
}
return;
};
Code: Select all
ENTRY (_loader)
SECTIONS{
. = 0x00100000;
.text :{
*(.text)
}
.rodata ALIGN (0x1000) : {
*(.rodata)
}
.data ALIGN (0x1000) : {
*(.data)
}
.bss : {
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}
Code: Select all
all: loader kernel link
cp krnl ..
loader: loader.s
$(AS) -o loader.o loader.s
kernel: kernel.c
$(GCC) -o kernel.o kernel.c -Wall -nostdlib -nostartfiles -nodefaultlibs
link: loader.o kernel.o
ld -T linker.td -o krnl loader.o kernel.o