Grub 2未在内核中检测到Multiboot标头 [英] Grub 2 not detecting Multiboot header in kernel

查看:242
本文介绍了Grub 2未在内核中检测到Multiboot标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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):

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

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

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

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

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

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

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.

推荐答案

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

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:

  • 删除.multiboot节,并将其内容放入加载程序的开头,并确保loa​​der.o是链接程序的第一个参数,然后是kernel.o.
  • 使用readelf -a kernel确保多重引导标头确实在前4k中(也就是说,如果起始位置在0x00100000处,则其偏移量小于0x00101000.
  • 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.

这篇关于Grub 2未在内核中检测到Multiboot标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆