我想用GRUB2引导一个自定义内核(非多引导),我已经读到我需要grub.cfg
,如下所示:
menuentry "custom kernel" {
set root=(hd0,0)
chainloader +1
}
所以,我有一些问题:
- 幼虫如何检测内核?(使用我使用的
kernel /boot/kernel.bin
的multiboot规范) - 我的内核应该是什么样子的(对不起我英语不好)?它必须是512字节吗(就像自定义引导加载程序,它加载到0x7c00中)
(hd0,0)
是硬盘分区,如果我使用CD,我必须放什么?也许是(cdrom0,0)
- 要引导Linux内核,我们可以使用
linux
命令,我可以使用它来引导我的自定义内核吗(有一些更改) - Grub是否会进入
Protected mode
请参阅文档:
Multiboot(请参阅Multiboot规范)是GRUB支持的本机格式。为了方便起见,还支持Linux、FreeBSD、NetBSD和OpenBSD。如果你想引导其他操作系统,你必须链加载它们(请参阅链加载)。
因此,对于非多引导内核,您必须使用链式加载器功能。链加载意味着GRUB将加载指定硬盘分区的第一个扇区(512字节),并像BIOS引导MBR一样引导它。这意味着CPU处于真实模式,并且引导扇区在0x7C00加载。
是的,您可以通过使linux
命令与Linux引导过程兼容来引导内核,但这比简单地使内核多引导兼容更复杂。
当计算机启动时,它会从硬盘的开头加载一个扇区(512字节)到内存位置0x7C00,并执行它。这是在真实模式下。当您使用GRUB时,它会将自己的代码安装到这个区域(MBR或主引导记录)。存在链加载的原因是其他操作系统有自己的引导加载程序。它允许GRUB用作主引导加载程序,但当它链接加载一个条目时,它会从该条目所在的分区加载512个字节,并在真实模式下加载到0x7C00,并假装计算机正在加载。这意味着操作系统可以安装到其VBR(卷引导记录)中,而不是安装到MBR中,如果用户选择该操作系统,则由GRUB加载。
如果你走上这条路,你无论如何都必须编写自己的引导程序,除非你想加载多个操作系统,否则使用GRUB是没有意义的。只使用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存储库上的此示例:https://github.com/cirosantilli/x86-bare-metal-examples/tree/cba0757990843f412b14dffad45467ad0034d286/grub/chainloader
Grub是否会进入保护模式?
有了chainloader
,由于我们使用了BIOS,所以我们仍然处于真实模式。
对于multiboot
(对于kernel
为GRUB2),内核处于保护模式,如Multiboot规范中所述:https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Machine-state:"必须设置'CR0'位0(PE)"。实例
幼虫如何检测内核?
它没有,你已经告诉它+1
的确切位置,就像我/boot/main.img
的一样。