Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grub 2 not detecting Multiboot header in kernel

I'm having an issue with Grub 2 (and QEMU's -kernel) not detecting the Multiboot v1 header in my kernel. I have the header in a separate section before .text.

linker.ld:

SECTIONS
{
    . = 1M;

    .multiboot ALIGN(4K) :
    {
        *(.multiboot)
    }

    .text ALIGN(4K) :
    {
        *(.text)
    }

    [snip]

boot.s (GNU as syntax):

.set MAGIC, 0x1badb002
.set FLAGS, (1<<0 | 1<<1) # align, provide mem map
.set CHECKSUM, -(MAGIC + FLAGS)

.section .multiboot
    .long MAGIC
    .long FLAGS
    .long CHECKSUM

.section .text
    [snip]

I have verified that the header section is being added as specified with the magic number:

kernel.bin:     file format elf32-i386

Contents of section .multiboot:
 101000 02b0ad1b 03000000 fb4f52e4           .........OR.    
Contents of section .text:
 [snip]

Yet Grub 2 says that the kernel does not have a valid Multiboot header, and using QEMU's -kernel option causes:

qemu: fatal: Trying to execute code outside RAM or ROM at 0x000a000

which seems to be an address in the BIOS-mapped range, not where Multiboot should be.

I've compared against the usual code in Bran's and OSDev (plus a previous kernel of mine) yet I can't seem to figure out what I'm doing wrong.

like image 318
Sam Kingston Avatar asked Oct 04 '22 14:10

Sam Kingston


1 Answers

I ran into the very same error with my multiboot kernel. I got the same error whem the size of the .text section exceeded about 4k. The cause of my problem was that upon linking, I specified kernel.o first, and loader.o second in the ld arguments (I wrote a Makefile to make my project, based on the OSDev Wiki Bare Bones more comfortable to develop). Multiboot is supposed to look for the header in the first 4k, and as my code grew, it pushed the header out of this area (as it was located before the loader in the kernel .text section). You used a separate section for the multiboot header, which may or may not be a good idea, I don't know. Things I'd try:

  • remove the .multiboot section, and put its contents into the beginning of the loader, and make sure that the loader.o is the first argument to the linker, and kernel.o comes after.
  • use readelf -a kernel to make sure the multiboot header is indeed in the first 4k (that is, if the beginning is at 0x00100000, its offset is below 0x00101000.
like image 69
AttishOculus Avatar answered Oct 08 '22 01:10

AttishOculus