ARM64 Linux内核启动调试与启动时间优化 - 第1节

1.1 ARM64 架构概述

ARM64(AArch64)是 ARM 公司推出的 64 位指令集架构,广泛应用于移动设备、服务器、嵌入式系统及边缘计算领域。与传统的 32 位 ARM(AArch32)相比,ARM64 在寄存器宽度、寻址能力、异常模型和启动协议上均有根本性变化。

1.1.1 核心特性

特性 描述
寄存器 31 个通用寄存器 X0–X30(64 位),外加 SP、PC、XZR 零寄存器
异常等级 EL0(用户态)、EL1(内核态)、EL2(虚拟化)、EL3(安全监控)
页表 支持 4KB/16KB/64KB 页,最多 4 级页表(L0–L3),48 位虚拟地址
启动协议 遵循 PSCI(Power State Coordination Interface),由固件(TF-A/UEFI)引导
中断模型 GICv2/v3/v4,支持 SPI、PPI、SGI 中断类型
关键差异: ARM64 没有 x86 的实模式/保护模式切换,启动时直接处于 EL1 或 EL2,页表在早期汇编阶段即需建立。

1.1.2 异常等级与启动路径

ARM64 的异常等级(Exception Level)决定了 CPU 的特权级别和启动阶段。Linux 内核通常运行在 EL1,而引导固件(如 U-Boot、TF-A)运行在 EL2 或 EL3。

ARM64 异常等级与启动路径 EL3 — Secure Monitor (TF-A / ATF) EL2 — Hypervisor (KVM / Xen / U-Boot) EL1 — Linux Kernel (OS) EL0 — User Space (Applications)
启动顺序: 上电 → EL3 固件初始化 → 降级到 EL2 加载引导程序 → 最终跳转到 EL1 内核入口。每一步都涉及异常等级切换和上下文保存。

1.2 Linux 内核启动流程全景图

Linux 内核启动是一个从汇编到 C、从单核到多核、从物理地址到虚拟地址的渐进过程。以下全景图展示了 ARM64 启动的核心阶段。

Linux 内核启动流程全景图(ARM64) 阶段 1 汇编入口 head.S 阶段 2 早期页表 & MMU 开启 阶段 3 start_kernel() C 入口 阶段 4 中断 & 调度器初始化 阶段 5 设备驱动 & 文件系统 阶段 6 init 进程启动 各阶段关键动作 1. head.S:CPU 模式检测、异常等级确认、设备树解析、主核/从核分流 2. 早期页表:创建恒等映射(identity mapping)和内核映射,开启 MMU 3. start_kernel:trap_init、mm_init、sched_init 等核心子系统初始化 4. 中断 & 调度器:GIC 初始化、调度器激活、软中断/任务队列就绪 5. 设备驱动:设备树解析、platform 设备注册、块设备/网络设备初始化 6. init 进程:挂载根文件系统,执行 /sbin/init 或 /init,进入用户态
核心原则: ARM64 启动流程强调“先映射、后跳转”。在 MMU 开启之前,所有代码必须运行在物理地址空间;开启 MMU 后,立即切换到虚拟地址空间执行。

1.3 x86 与 ARM64 启动流程的宏观差异

x86 和 ARM64 在启动流程上存在根本性差异,这些差异源于架构设计哲学、历史演进和生态系统的不同。下表从多个维度进行对比。

对比维度 x86 ARM64
启动模式 实模式 → 保护模式 → 长模式 直接进入 EL1/EL2,无实模式
引导协议 BIOS/UEFI → bootloader → 内核 固件(TF-A/UEFI)→ bootloader → 内核
页表建立 由 bootloader 或内核早期代码建立 内核汇编阶段必须建立恒等映射
多核启动 BSP 核启动,AP 核通过 SIPI 唤醒 PSCI 协议,主核通过 SMC 调用唤醒从核
设备描述 ACPI 表(x86 标准) 设备树(Device Tree)或 ACPI(服务器)
中断控制器 APIC(本地 + I/O) GIC(通用中断控制器)
内核入口 startup_32 / startup_64 stext / el1_setup / el2_setup

1.3.1 启动模式对比

x86 的启动模式经历了从 16 位实模式到 32 位保护模式再到 64 位长模式的多次切换,每次切换都需要修改段寄存器、控制寄存器和页表。ARM64 则没有这种历史包袱,上电后直接处于 64 位模式,异常等级决定了特权级别。

x86 vs ARM64 启动模式切换 x86 启动路径 实模式 (16-bit) 保护模式 (32-bit) 长模式 (64-bit) ARM64 启动路径 EL3 固件 EL2 Bootloader EL1 内核
常见误区: 很多开发者认为 ARM64 启动比 x86 简单,实际上 ARM64 的页表建立和异常等级管理更为复杂。x86 的实模式虽然古老,但提供了成熟的 BIOS/UEFI 服务;ARM64 的固件生态碎片化严重,不同厂商的启动实现差异较大。

1.3.2 多核启动差异

x86 使用 BSP(Bootstrap Processor)和 AP(Application Processor)模型,通过 SIPI(Startup IPI)中断唤醒从核。ARM64 则使用 PSCI(Power State Coordination Interface)标准,主核通过 SMC(Secure Monitor Call)指令请求固件唤醒从核。

特性 x86 ARM64
唤醒机制 SIPI 中断 + 实模式代码 PSCI CPU_ON SMC 调用
从核入口 实模式地址(< 1MB) 由固件指定,通常在 DRAM 中
同步方式 全局标志位 + 自旋锁 spin_table 或 PSCI 状态机
固件依赖 低(BIOS 仅提供初始引导) 高(PSCI 实现在 EL3 固件中)

1.3.3 设备描述差异

x86 平台几乎统一使用 ACPI(Advanced Configuration and Power Interface)来描述硬件拓扑、电源管理和中断路由。ARM64 则主要使用设备树(Device Tree),但在服务器领域也开始支持 ACPI。

实际影响: 在 ARM64 上移植内核时,设备树的编写和调试是主要工作量之一。一个错误的 interrupt-parent 或 reg 属性可能导致整个系统无法启动。

1.4 本章小结

  • ARM64 架构以异常等级(EL0–EL3)为核心,启动过程涉及多次异常等级切换。
  • Linux 内核启动分为 6 个阶段:汇编入口 → 页表建立 → C 入口 → 中断/调度 → 设备驱动 → init 进程。
  • x86 与 ARM64 在启动模式、多核唤醒、设备描述和中断模型上存在显著差异。
  • 理解这些宏观差异是后续深入分析 ARM64 启动细节的基础。