X86 使用GRUB2引导非多引导内核
我想用GRUB2引导一个定制内核(非多引导),我读到我需要X86 使用GRUB2引导非多引导内核,x86,osdev,grub,X86,Osdev,Grub,我想用GRUB2引导一个定制内核(非多引导),我读到我需要grub.cfg如下: menuentry "custom kernel" { set root=(hd0,0) chainloader +1 } 因此,我有一些问题: grub如何检测内核?(对于multiboot规范,我使用了kernel/boot/kernel.bin) 我的内核应该是什么样子(抱歉我的英语不好)?它必须是512字节(就像加载到0x7c00中的自定义引导加载程序) (hd0,0)是硬盘分区,如果我使
grub.cfg
如下:
menuentry "custom kernel" {
set root=(hd0,0)
chainloader +1
}
因此,我有一些问题:
kernel/boot/kernel.bin
)(hd0,0)
是硬盘分区,如果我使用CD,我必须放什么?可能是(cdrom0,0)
Linux
命令,我可以使用它来引导我的自定义内核(进行一些更改)吗是的,通过使内核与linux引导过程兼容,您可以使用
linux
命令引导内核,但这比简单地使内核与多引导兼容要复杂得多。当计算机启动时,它将从硬盘开始加载一个扇区(512字节)到内存位置0x7C00,并执行它。这是真实模式。当您使用GRUB时,它会将自己的代码安装到此区域(MBR或主引导记录)。存在链加载的原因是其他操作系统都有自己的引导加载程序。它允许GRUB用作主引导加载程序,但当它链接加载一个条目时,它会从该条目所在的分区加载512字节,并以实模式将其加载到0x7C00,并假装计算机正在加载。这意味着,操作系统可以安装到其VBR(卷引导记录)中,而不是安装到MBR中,如果用户选择该操作系统,则由GRUB加载
如果你走这条路,你将不得不编写你自己的引导加载程序,而且使用GRUB是没有意义的,除非你想加载多个OSs。只使用multiboot会更容易,因为GRUB进入保护模式并为您启用A20线路。我不知道Linux格式,但对于一个简单的内核来说,它肯定有点过分。如果您走得更远,那么切换到Linux格式——甚至为自定义格式编写自己的引导加载程序——可能会有用
我的内核应该是什么样子
通过使用chainloader
,GRUB使其得到与引导扇区完全相同的处理。最简单的例子:
iso/boot/grub/grub.cfg
menuentry "hello-world" {
chainloader /boot/main.img
}
main.S
.code16
.global _start
_start:
cli
/* Sane programs should also do some extra
* initialization here like stack and segments.
*/
mov $0x0E61, %ax
/* BIOS call that prints 'a' to screen. */
int $0x10
hlt
编译并运行
as -o main.o main.S
/* Sane programs should use a dedicated linker script. */
ld --oformat binary -o main.img -Ttext 0x7C00 main.o
cp main.img iso/boot/
grub-mkrescue -o main.iso iso
qemu-system-i386 -hda main.iso
在Ubuntu 14.04 ADM64上测试
预期结果:a
被打印到屏幕上
GitHub存储库上的以下示例:
Grub是否将进入保护模式
使用chainloader
时,我们仍然处于实模式,因为我们使用了BIOS
使用multiboot
(GRUB2用于内核
),内核处于保护模式,如multiboot规范中所述:“'CR0'位0(PE)必须设置”。”
grub如何检测内核
它没有,您已经告诉了它使用
+1
的确切位置,就像我使用/boot/main.img
一样 您的回答掩盖了这样一个事实:您仍然处于real模式的原因是,当您专门使用chainloader
时,它必须像BIOS加载引导扇区并直接跳转一样工作。如果OP使用了内核
(并将hit bootloader写入了multiboot规范),那么默认情况下他将处于保护模式。另一方面,如果你在386上开机,那么很可能你在默认情况下处于非真实模式(而不是真实模式)@MichaelPetch谢谢你的反馈。我也试着把这些信息加进去。