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



Grub 2(和QEMU的-kernel)在我的内核中没有检测到Multiboot v1标头,我遇到了一个问题。我在.text之前的一个单独的部分中有标题。

linker.ld:

SECTIONS
{
    . = 1M;
    .multiboot ALIGN(4K) :
    {
        *(.multiboot)
    }
    .text ALIGN(4K) :
    {
        *(.text)
    }
    [snip]

boot.s(GNU语法):

.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]

然而Grub2说内核没有有效的Multiboot头,使用QEMU的-kernel选项会导致:

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

这似乎是BIOS映射范围中的一个地址,而不是Multiboot应该在哪里。

我已经将Bran和OSDev中的常用代码(加上我以前的内核)进行了比较,但我似乎不知道自己做错了什么。

我的multiboot内核也遇到了同样的错误。当.text部分的大小超过4k时,我也出现了同样的错误。我的问题的原因是,在链接时,我在ld参数中首先指定了kernel.o,其次指定了loader.o(我写了一个Makefile,使我的项目更易于开发,基于OSDev Wiki Bare Bones)。Multiboot应该在前4k中查找标头,随着代码的增长,它将标头推出了这个区域(因为它位于kernel.text部分的加载程序之前)。您为multiboot头使用了一个单独的部分,这可能是个好主意,也可能不是,我不知道。我会尝试的事情:

  • 删除.multiboot部分,并将其内容放在加载器的开头,并确保loader.o是链接器的第一个参数,kernel.o在后面
  • 使用readelf -a kernel来确保多引导头确实在前4k中(即,如果开始在0x00100000,则其偏移量低于0x00101000

相关内容

  • 没有找到相关文章

最新更新