Grub 2未在内核中检测到Multiboot标头 [英] Grub 2 not detecting Multiboot header in kernel
问题描述
我遇到了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节,并将其内容放入加载程序的开头,并确保loader.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 at0x00100000
, its offset is below0x00101000
.
这篇关于Grub 2未在内核中检测到Multiboot标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!