Grub 2没有检测到内核中的Multiboot头

时间:2013-07-09 03:34:48

标签: kernel grub multiboot

我遇到Grub 2(和QEMU的-kernel)没有在我的内核中检测到Multiboot v1标头的问题。我在.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]

我已经确认标题部分正在使用幻数添加:

kernel.bin:     file format elf32-i386

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

然而Grub 2表示内核没有有效的Multiboot标头,并且使用QEMU的-kernel选项导致:

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

它似乎是BIOS映射范围内的地址,而不是Multiboot的位置。

我已经比较了Bran和OSDev中的常用代码(加上我以前的内核),但我似乎无法弄清楚我做错了什么。

1 个答案:

答案 0 :(得分:3)

我的多引导内核遇到了同样的错误。当.text部分的大小超过大约4k时,我得到了同样的错误。我的问题的原因是,在链接时,我首先指定了kernel.o,并在ld参数中指定了loader.o(我编写了一个Makefile来创建我的项目,基于OSDev Wiki Bare Bones开发更加舒适)。多引导应该在前4k中查找头部,并且随着我的代码的增长,它将头部推出该区域(因为它位于内核.text部分中的加载器之前)。您使用了一个单独的部分作为多重启动标题,这可能是也可能不是一个好主意,我不知道。我尝试过的事情:

  • 删除.multiboot部分,并将其内容放入加载器的开头,并确保loa​​der.o是链接器的第一个参数,并且kernel.o在之后。
  • 使用readelf -a kernel确保多重引导标头确实位于前4k(即,如果开头位于0x00100000,则其偏移量低于0x00101000