Multiboot

来自osdev
跳到导航 跳到搜索

Multiboot多重引导规范是一个开放标准,它为内核提供了一种由兼容Multiboot的引导加载程序引导的统一方式。 多引导规范的参考实现由GRUB提供。

Multiboot 1

最初的Multiboot是由布莱恩·福特和埃里希·斯特凡·博林·1995年创建的。 从那时起,它就已经被自由软件基金会发展和更新。

与Multiboot 1兼容的内核使用幻数0x1BADB002,而与Multiboot兼容的引导加载器使用幻数0x2BADB002报告自身。(译者注:Magic Number这个词实在好多地方有,翻译成幻数,固定数,神奇的数字,魔术编号,魔法数字什么的,都随意吧……)

你可以通过运行 grub-file 来检查程序是否具有有效的Multiboot 1标头,该程序什么也不做,但如果找到标头将退出0,否则将退出1。

grub-file --is-x86-multiboot myos.bin

Multiboot 2

新的Multiboot规范是为了解决原始规范存在的一些问题而创建的。 它不是向后兼容的,使用不同的结构和不同的幻数。

兼容Multiboot 2的内核使用幻数0xE85250D6,兼容Multiboot的引导加载程序(bootloaders)以幻数0x36D76289报告自己。 在x86上,在调用内核之前,这个幻数存储在EAX中。

你可以通过运行grub-file来检查程序是否具有有效的Multiboot 2标头,grub-file也什么都不做,但如果找到标头将退出0,否则将退出1。

grub-file --is-x86-multiboot2 myos.bin

注意:对于elf64,GNU LD的默认页面大小为0x00200000,这将导致multiboot2测试失败。 你可以使用“-z max-page-size=SIZE”来解决这个问题。

GNU GRUB与Multiboot2规范的版本2.02兼容。

标头格式

Multiboot2头的第一部分是一个在8字节边界上对齐的结构,其中包含四个“魔术”32位整数。 这些字段分别包含魔术编号0xE85250D6,描述体系结构的标志,包括后续标签的标头总长度以及魔术字段的校验和。

标题中的魔法字段后面是一个8字节对齐结构列表,在规范中称为tags(标签)。 Bootloader使用这些标签作为提示,以提供有关内核映像的信息,并请求它在引导信息结构中提供附加信息。

可用标签及其结构因平台而异,并在Multiboot2规范中进行了记录。 最新草案见下文#外部链接。 此标签列表必须以类型为0且大小为8的标签结尾。

信息结构

与Multiboot2兼容的引导加载程序提供了内核启动时的信息格式信息结构。 在x86上,物理指针存储在EBX中。 此信息结构是8字节对齐的,并且包含标签。 这些标签可能包含有关系统的有用信息, 例如:the memory mapelf sections of the image和有关帧缓冲区的framebuffer相关信息

struct multiboot_tag {
    uint32_t type;
    uint32_t size;
};

struct multiboot_info {
    uint32_t total_size;
    uint32_t reserved;
    struct multiboot_tag tags[0];
};

Multiboot 2模块

(请注意,本节可能不是100%准确,有待测试。)

Multiboot2规范支持引导模块,引导模块是引导加载程序引导内核时加载到内存中的数据片段。 通常,这些只是驻留在引导介质上的文件,这些文件由引导加载程序加载,但是确切的实现取决于引导加载程序。 对于GRUB,在引导内核之前,使用“module2”命令加载这些模块。

内核引导后,你可以使用多重引导信息结构体(multiboot information structure)来定位和识别这些模块。 请注意,在GRUB的情况下,模块的字符串还将包含模块名称之后的文本,例如,如果你使用 “module video 1024x768” 加载模块,则该模块结构的字符串字段将包含 “video 1024x768”。 通过这种方式,可以在加载模块时为模块指定“参数”。(这似乎是multiboot规范的预期行为。)

GRUB可以支持在加载模块之前对其进行解压缩,这似乎是由文件扩展名驱动的。

放置Multiboot结构体

如前所述,结构必须是8字节对齐的,并放置在可执行文件的前8K中。 要确保这一点,最简单的解决方案是为具有attribute的结构体创建一个新节(section):

struct multiboot_header {
  ...
} __attribute__((section(".multiboot")));

然后告诉 链接器脚本中的 链接器 以正确对齐方式启动此节的文件:

...
.text: {
  /* 在此处链接多引导结构 */
  . = ALIGN(8);
  KEEP(*(.multiboot))
  /* 之后放置所有代码 */
  *(.text)
}
...

关键字ALIGN保证对齐,KEEP告诉链接器将该部分保留在文本段(text segment)的开头。

另见

文章

论坛文章

外部链接

de:Multiboot