X86 使用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)是硬盘分区,如果我使

我想用GRUB2引导一个定制内核(非多引导),我读到我需要
grub.cfg
如下:

menuentry "custom kernel" {
    set root=(hd0,0)
    chainloader +1
}
因此,我有一些问题:

  • grub如何检测内核?(对于multiboot规范,我使用了
    kernel/boot/kernel.bin
  • 我的内核应该是什么样子(抱歉我的英语不好)?它必须是512字节(就像加载到0x7c00中的自定义引导加载程序)
  • (hd0,0)
    是硬盘分区,如果我使用CD,我必须放什么?可能是
    (cdrom0,0)
  • 要引导Linux内核,我们可以使用
    Linux
    命令,我可以使用它来引导我的自定义内核(进行一些更改)吗
  • Grub是否会进入保护模式
  • 见:

    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是没有意义的,除非你想加载多个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谢谢你的反馈。我也试着把这些信息加进去。