arch/x86/boot/compressed/head_64.S

发布时间:2026/8/7 12:14:01
arch/x86/boot/compressed/head_64.S arch/x86/boot/compressed/head_64.S是 Linux 内核在 x86_64 架构下启动流程中的核心解压引导文件。它的主要功能是接收来自引导程序的控制权为进入 64 位长模式做准备然后将压缩的内核镜像解压到正确位置最终跳转到内核的入口。这个文件的核心功能和代码执行逻辑可以分解为以下几个关键阶段入口点与模式切换文件的核心是两个入口点分别对应不同的启动路径其核心工作都是从实模式/32位模式跳转到64位模式。startup_32(32位入口)这是传统引导流程中CPU从实模式跳转后的第一个入口。在此处会完成计算内核实际加载地址与编译地址的偏移量relocation delta、设置临时全局描述符表GDT并加载段寄存器、启用物理地址扩展PAE并建立初步的 4 级页表然后跳转到startup_64。startup_64(64位入口)这是进入 64 位长模式后的主要入口也是此文件的核心。startup_64自身也会重复计算一些地址信息并继续完成后续的初始化和解压工作。核心初始化与解压准备进入startup_64后代码会执行一系列环境准备工作为调用 C 语言编写的解压函数铺路。环境清理与设置首先会重置并设置新的段寄存器确保它们符合 64 位模式的要求。接着会设置内核栈rsp为后续的函数调用做准备。同时会重置 EFLAGS 寄存器清零以确保 CPU 状态是已知且干净的。一个重要的步骤是重置控制寄存器CR4只保留PAE物理地址扩展、MCE机器检查异常和LA575级页表支持等必须保留的标志位清除其他可能带来问题的设置这有助于解决一些启动兼容性问题。内核镜像重定位在解压前需要将压缩的内核镜像vmlinuz从初始加载位置复制到一个安全的目标地址这个地址通常是按 2MB 对齐的物理内存地址可以安全地进行原地解压in-place decompression。整个复制过程是从后向前std,rep movsq进行的以避免数据覆盖。解压与启动内核当所有环境准备就绪后startup_64就会调用真正的解压函数并最终跳转到解压后的新内核。调用解压核心在跳转前会先清理.bss段因为即将进入 C 语言环境需要清零全局变量区域。然后代码会准备好参数并调用extract_kernel函数在misc.c中实现。这个函数是解压的真正执行者负责将压缩的内核数据解压到目标地址。head_64.S在调用时会将boot_params指针、堆区地址、输入输出数据地址和长度等关键信息作为参数传递。最终跳转extract_kernel函数执行完毕后会返回解压后内核的入口点地址通常是arch/x86/kernel/head_64.S中的startup_64。head_64.S中的最后一条指令jmp *%rax将 CPU 控制权完整移交给这个新内核自此系统启动流程进入下一个阶段。arch/x86/boot/compressed/head_64.S充当了一个承上启下的“桥梁”它以汇编语言的高效和精确在几KB的空间内完成了从引导程序Bootloader到内核镜像解压之间的所有关键硬件状态准备。