Problem with multiboot kernel

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
EjzSpb
Posts: 2
Joined: Sun Jan 31, 2010 4:19 am
Location: Saint-Petersburg

Problem with multiboot kernel

Post by EjzSpb »

I use the following code for my kernel...

Code: Select all

/* kernel.c */
#define MULTIBOOT_HEADER_MAGIC		0x1badb002
#define MULTIBOOT_BOOTLOADER_MAGIC	0x2badb002
#define MULTIBOOT_PAGE_ALIGN		0x00000001
#define MULTIBOOT_MEMORY_INFO		0x00000002
#define MULTIBOOT_VIDEO_MODE		0x00000004
#define MULTIBOOT_AOUT_KLUDGE		0x00010000
#define MULTIBOOT_HEADER_FLAGS	(MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE)

typedef unsigned long int dword;

typedef struct {
	dword magic;
	dword flags;
	dword checksum;
	dword header_addr;
	dword load_addr;
	dword load_end_addr;
	dword bss_end_addr;
	dword entry_addr;
} __attribute__ ((aligned (4))) multiboot_t;

void kernel();

void _start() { kernel(); }

void kernel() {
	for(;;);
}

multiboot_t multiboot = {
	MULTIBOOT_HEADER_MAGIC,
	MULTIBOOT_HEADER_FLAGS,
	-(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS),
	0x100800,
	0x100000,
	0x200000,
	0x200000,
	0x100000
};
then i compile, link it and check via 'mbchk'

Code: Select all

# gcc -O0 -fno-stack-protector -ffreestanding -Wall -c kernel.c -o kernel.o
# ld -Ttext=0x100000 -Tdata=0x100800 --oformat=binary kernel.o -o kernel.bin
# mbchk kernel.bin
kernel.bin: The Multiboot header is found at the offset 2048.
kernel.bin: Page alignment is turned off.
kernel.bin: Memory information is turned on.
kernel.bin: Address fields is turned on.
kernel.bin: All checks passed.
Install grub to floppy...

Code: Select all

# dd if=/dev/zero of=floppy.img bs=1024 count=1440
# losetup /dev/loop0 floppy.img
# mkfs -q /dev/loop0
# mount /dev/loop0 /mnt/fdd/
# mkdir -p /mnt/fdd/boot/grub
# cp /boot/grub/stage[12] /mnt/fdd/boot/grub/
# cp kernel.bin /mnt/fdd/
# grub --device-map=/dev/null
grub> device (fd0) /dev/loop0
grub> root (fd0)Unknown partition table signature
grub> setup (fd0)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... no
 Running "install /boot/grub/stage1 (fd0) /boot/grub/stage2 p /boot/grub/menu.lst "... succeeded
Done.
grub> quit
# umount /mnt/fdd/
# losetup -d /dev/loop0
When i start bochs, it says me "Error 13: Invalid or unsupported executable format" (see screen attached)
What's wrong in my code, please help.
Attachments
bochs.jpg
ATC
Member
Member
Posts: 45
Joined: Sun Jan 24, 2010 9:27 am

Re: Problem with multiboot kernel

Post by ATC »

You're compiling the kernel to flat .bin? :o Why is that? I'd recommend you use .elf or even PE. I'm working in Visual Studio and using PE format.

But if you insist, check this thread out. It describes implementing multi-boot compliance in a flat bin and even PE. I haven't tried the bin method, but his PE information is very good and nearly identical to mine.

http://forum.osdev.org/viewtopic.php?f=1&t=21260
There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Problem with multiboot kernel

Post by jal »

EjzSpb wrote:When i start bochs, it says me "Error 13: Invalid or unsupported executable format" (see screen attached)
What's wrong in my code, please help.
Your assumption that there is something wrong with your code is wrong. What is wrong is that your executable format is invalid or unsupported. The fact that GRUB is served a valid MB header doesn't mean that GRUB can load your executable.


JAL
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Problem with multiboot kernel

Post by Combuster »

For starters, you are telling GRUB that your kernel image is 1MB in size (via the multiboot header), while it is more likely 2.5kb in size
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
EjzSpb
Posts: 2
Joined: Sun Jan 31, 2010 4:19 am
Location: Saint-Petersburg

Re: Problem with multiboot kernel

Post by EjzSpb »

Thx for your help. Finally i decided to use ELF format (thx to ATC advice)!

My multiboot code became...

Code: Select all

.set MBOOT_HEADER_MAGIC, 0x1badb002
.set MBOOT_PAGE_ALIGN, 0x1
.set MBOOT_MEMORY_INFO, 0x2
.set MBOOT_VIDEO_MODE, 0x4
.set MBOOT_AOUT_KLUDGE, 0x10000
.set MBOOT_FLAGS, MBOOT_MEMORY_INFO

.set STACK_SIZE, 0x8000

.extern kernel

.text
.code32
.globl _start
_start:
jmp _real_start

.align 4
_mboot_header:
.long MBOOT_HEADER_MAGIC
.long MBOOT_FLAGS
.long -(MBOOT_FLAGS + MBOOT_HEADER_MAGIC)

_real_start:
mov $(_stack + STACK_SIZE), %esp
push $0x0
popf
push %ebx
push %eax
call kernel
jmp .
/* Our stack */
.comm _stack, STACK_SIZE
... kernel code...

Code: Select all

void kernel(unsigned long magic, unsigned long addr) {
	for(;;);
}
... Makefile...

Code: Select all

CC = gcc -O0 -fno-stack-protector -fomit-frame-pointer -ffreestanding -Wall
LD = ld
OBJECTS = kernel.o mboot.o
FDD = fdd.img
FDDMOUNT = /mnt/fdd/
all: kernel.elf
kernel.elf: $(OBJECTS)
	$(LD) -Ttext=0x100000 $(OBJECTS) -o kernel.elf
.c.o:
	$(CC) -c $< -o $*.o
.s.o:
	$(CC) -c $< -o $*.o
install: all
	losetup /dev/loop0 $(FDD)
	mount /dev/loop0 $(FDDMOUNT)
	cp kernel.elf $(FDDMOUNT)
	umount /dev/loop0
	losetup -d /dev/loop0
	rm -f *.o
GRUB installation remains the same.
ATC
Member
Member
Posts: 45
Joined: Sun Jan 24, 2010 9:27 am

Re: Problem with multiboot kernel

Post by ATC »

Cool! Now you ought to do a more complete and robust implementation and gather every bit and byte of data from the loader for more advanced options/error handling/diagnostics/etc. GNU has a lovely beginner's example which uses the .elf format for teaching. I even learned a thing or to from it for working with PE. The cool thing about developing (brand new) operating systems is that code can actually be portable in our environment. No Windows or *Nix to depend on, heheh. :) Only to a certain extent, of course...

http://www.gnu.org/software/grub/manual ... l#Examples

Scroll down a bit and look through their code. Don't cheat yourself and just copy it though. Look up references for anything you don't understand and try to re-implement your own version. :wink: If you just copy people's code, sure, it will probably work. But you'll be terribly confused when you need to venture out from the umbrella of tutorials and references.

A good place to start is in your main(...) function. Check if the first param is == 0x1BADB002 (Magic #), and have your code handle that. If not, it could be another bootloader and require other steps. So branch out from there. Also, do you realize the addr parameter is the pointer to a multiboot information structure? You need to capture that pointer and use the data to do more sophisticated setup and initialization. It won't kill you to ignore the data, but why? There's no benefit to ignoring something that might be incredibly useful. Read all of the information at that GNU link I gave you until you can't stomach another word of it. Then you'll be glad you did! ;)
There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson
Post Reply