谁加载了标识映射页表?

谁加载了标识映射页表?

我想了解Linux x86_64的启动步骤,看了一些文章和linux-3.14.65/Documentation/x86/boot.txt,几乎知道第一个运行的指令vmlinux是,但是当我看到aboutstartup_x86中的评论时:arch/x86/kernel/head_64.Sstartup_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 modehas 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 文件也使用这些控制寄存器。

相关内容