我想了解Linux x86_64的启动步骤,看了一些文章和linux-3.14.65/Documentation/x86/boot.txt
,几乎知道第一个运行的指令vmlinux
是,但是当我看到aboutstartup_x86
中的评论时:arch/x86/kernel/head_64.S
startup_64
.text
__HEAD
.code64
.globl startup_64
startup_64:
/*
* At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 0,
* and someone has loaded an identity mapped page table
* for us. These identity mapped page tables map all of the
* kernel pages and possibly all of memory.
我仍然对评论感到困惑,我不知道是谁发表CPU runs in 64bit mode
的has loaded an identity mapped page table for us
?这是Grub
?我想念什么?
答案1
startup_64
可以输入
/* The entry point for the PE/COFF executable is efi_pe_entry. */
ENTRY(efi_pe_entry)
...
movl BP_code32_start(%esi), %eax
leaq startup_64(%rax), %rax
jmp *%rax
ENDPROC(efi_pe_entry)
或者,我相信Linux 感知的 EFI 引导加载程序可以直接跳转到例程handover_entry
内部。efi_pe_entry
这种混合方法允许引导加载程序继续提供某些特定于 Linux 的功能,同时允许内核使用特定于 EFI 的功能。看EFI 系统上的引导过程 (LWN.net)。
最后,startup_64
可能会跳转到 from startup_32
;当内核由 Linux 感知的 BIOS 引导加载程序加载时,就会发生这种情况。
(好吧,还有一种情况。64 位内核可能有一个efi32_stub_entry
点,然后跳转到startup_32
。我忽略这一点。无论如何,32 位 EFI 上的 64 位内核仍然标记为实验性)。
根据以上所述,我不确定这startup_64
是曾经运行的第一条指令vmlinux
。评论说它可以“直接从 64 位引导加载程序”输入,但我不知道有这样的事情。
在 BIOS 案例中,您可以清楚地看到它startup_32
负责设置初始 64 位页表(“早期 4G 启动页表”),当然还有切换到 64 位模式(又名“长模式”)。
在 EFI64 情况下,CPU 已经处于 64 位模式。 efi_pe_entry
呼叫make_boot_params()
并efi_main()
进入eboot.c
。 (handover_entry
只是调用efi_main()
,在本例中是引导加载程序提供的struct boot_params
)。 eboot.c
不设置页表。因此,评论假设 EFI 至少为它加载的内核的所有页面(包括任何BSS空间),这对我来说很有意义:-)。
https://elixir.bootlin.com/linux/v4.20/source/arch/x86/boot/compressed/head_64.S
答案2
根据“初始化页表”部分中的第一个项目符号http://www.cse.iitd.ernet.in/~sbansal/os/lec/l14.html、entry.S负责建立页表。我们确实找到了逻辑https://github.com/torvalds/linux/blob/master/arch/x86/entry/entry_64.S处理这个问题(“页表的设置使得......”)。
在https://github.com/torvalds/linux/blob/v4.14/arch/x86/boot/compressed/head_64.S不过,我们找到了更多有关设置页表的参考资料。在这里我们看到“构建早期 4G 启动页表”和“启用启动页表”。
本文提供了如何启用寻呼(包括身份寻呼)的示例:https://github.com/littleosbook/littleosbook/blob/master/paging.md。请注意,该示例使用控制寄存器 cr3、cr4 和 cr0,如中所述https://en.wikipedia.org/wiki/Control_register。 Entry_64.S 和 head_64.S 文件也使用这些控制寄存器。