kernel - Grub 2 未检测到内核中的多重引导 header

标签 kernel grub multiboot

我遇到了 Grub 2(和 QEMU 的 -kernel)问题,无法检测到内核中的 Multiboot v1 header 。我将标题放在 .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]

我已经验证标题部分是按照魔数(Magic Number)指定添加的:

kernel.bin:     file format elf32-i386

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

但是 Grub 2 表示内核没有有效的 Multiboot header ,并且使用 QEMU 的 -kernel 选项会导致:

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

这似乎是 BIOS 映射范围内的地址,而不是 Multiboot 应该在的位置。

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

最佳答案

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

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

关于kernel - Grub 2 未检测到内核中的多重引导 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17539464/

相关文章:

c - Linux Kernel Module程序从IP获取域名

linux - 肮脏的 fatal error : unable to find a suitable template

linux - linux内核页表更新

linux - 如何在Eclipse中包含Linux内核开发的asm头目录?

Windows 7 x86 使用 sysenter 执行直接系统调用

linux - 07C0 :0000, 不是 x86 机器上与 0000 :7C00? 相同的物理地址吗

linux - 以编程方式编辑 grub 选项

有人可以解释一下我如何使用来自 grub 的 C 数据结构吗?我不明白 hi mem 和 lo mem

x86 - 多重引导 1 引导信息总大小

c - x86 保护模式下的键盘中断导致处理器错误