I've been trying to set up the bare bones tutorial from the wiki, but with grub2 instead of normal grub. I created a qemu virtual system with a hard disk, booted using an ubuntu 10.04 livecd, installed grub onto an ext4 partition, and then booted the system with `qemu -hda hd.img -hdb fat:.`. Grub can see the virtual fat filesystem fine, but when I actually try to pass grub the image (exos.bin - but it's actually an ELF file) with `multiboot (hd1,1)/exos.bin` and `boot`, it just sits there. If I put those instructions in /boot/grub/grub.cfg on the ext4 filesystem, it clears the screen and then sits there.
I can boot the same image, with the same configuration, on the Grub2 actually installed on my computer, and it displays the glorious A to my screen.
Is this a problem with grub2? Or is this a problem with me compiling something wrong (see actual stuff below)? I seem to remember having a very similar (identical as far as I know - but what can you tell from a blank screen?) problem when I was setting stuff up with grub 1, the first time. (I lost those files by passing qemu /dev/sda3 as the disk image to use. "That's not a disk image - but I can fix that for ya!" Whoops.)
Ok, now the code I'm using. Makefile
Code: Select all
all: exos.bin
exos.bin: linker.ld loader.o kernel.o
ld -melf_i386 -T linker.ld -o exos.bin loader.o kernel.o
loader.o: loader.s
nasm -f elf -o loader.o loader.s
kernel.o: kernel.c
gcc -o kernel.o -c kernel.c -Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs -m32 -march=i386
clean:
rm -f *.bin *.o
export:
cp exos.bin /boot
Code: Select all
global loader ; making entry point visible to linker
extern kmain
; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
section .text
align 4
MultiBootHeader:
dd MAGIC
dd FLAGS
dd CHECKSUM
; reserve initial kernel stack space
STACKSIZE equ 0x4000 ; that's 16k.
loader:
mov esp, stack+STACKSIZE ; set up the stack
push eax ; pass Multiboot magic number
push ebx ; pass Multiboot info structure
call kmain
cli
hang:
hlt ; halt machine should kernel return
jmp hang
section .bss
align 4
stack:
resb STACKSIZE ; reserve 16k stack on a doubleword boundary
Code: Select all
void kmain( void* mbd, unsigned int magic ) {
if ( magic != 0x2BADB002 ) {
/* Something went not according to specs. Print an error */
/* message and halt, but do *not* rely on the multiboot */
/* data structure. */
}
/* You could either use multiboot.h */
/* (http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#multiboot_002eh) */
/* or do your offsets yourself. The following is merely an example. */
char * boot_loader_name =(char*) ((long*)mbd)[16];
/* Print a letter to screen to see everything is working: */
unsigned char *videoram = (unsigned char *) 0xb8000;
videoram[0] = 65; /* character 'A' */
videoram[1] = 0x07; /* forground, background color. */
/* Write your kernel here. */
}
Code: Select all
ENTRY (loader)
SECTIONS{
. = 0x00100000;
.text :{
*(.text)
}
.rodata ALIGN (0x1000) : {
*(.rodata)
}
.data ALIGN (0x1000) : {
*(.data)
}
.bss : {
sbss = .;
*(COMMON)
*(.bss)
ebss = .;
}
}
Thanks in advance.
PS: since this is 32 bit code, I've tried it in both `qemu` (a 32-bit system) and `qemu-system-x86_64` - with identical results.