三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

在openEuler 20.03 LTS SP3上编译内核踩坑记:FT2000+平台启动卡在EFI stub的排查与解决

在openEuler 20.03 LTS SP3上编译内核踩坑记:FT2000+平台启动卡在EFI stub的排查与解决

FT2000+平台内核编译实战:从EFI启动卡死到完美避坑指南

那天深夜的机房,显示器蓝光映着我凝固的表情——FT2000+服务器卡在EFI stub: Exiting boot services...的启动画面已经整整47分钟。作为在ARM架构摸爬滚打五年的老手,我没想到会在最基础的make defconfig流程上翻车。本文将还原这场持续72小时的故障拉锯战,揭示openEuler发行版与标准内核间的"隐形鸿沟"。

1. 故障现场:当标准流程遭遇国产化平台

FT2000+的UEFI固件版本显示为1.8.3,openEuler 20.03 LTS SP3系统运行正常。按照教科书式操作:

wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.90.tar.gz tar -xf linux-4.19.90.tar.gz cd linux-4.19.90 make defconfig make -j64 make modules_install make install

重启后却遭遇经典卡死:

[ 0.000000] EFI stub: Booting Linux Kernel... [ 0.000000] EFI stub: Exiting boot services and installing virtual address map...

关键现象诊断:

  • 系统完全挂起,无任何错误提示
  • 相同操作在x86平台完全正常
  • 使用发行版自带内核(/boot/config-4.19.90-2112.8.0.0131.oe1.aarch64)则启动顺利

2. 配置差异的深度解构

通过diff对比标准配置与openEuler配置,发现ARM64架构相关关键差异:

配置项defconfig值openEuler值影响范围
CONFIG_ARM64_PAGE_SHIFT1216内存页大小(4KB vs 64KB)
CONFIG_PGTABLE_LEVELS43页表层级
CONFIG_ARM64_64K_PAGESnot sety大页支持
CONFIG_FORCE_MAX_ZONEORDER1114内存区块最大阶数
CONFIG_NR_CPUS641024CPU核心数支持

致命陷阱:飞腾处理器对内存管理有特殊要求:

  1. 必须启用64KB大页(CONFIG_ARM64_64K_PAGES)
  2. 页表层级需设置为3级(CONFIG_PGTABLE_LEVELS=3)
  3. 内存区域最大阶数影响DMA性能(CONFIG_FORCE_MAX_ZONEORDER=14)

3. 渐进式排错实验记录

3.1 初试:补丁式修改(失败)

在defconfig基础上仅修改最明显差异项:

sed -i 's/CONFIG_ARM64_PAGE_SHIFT=12/CONFIG_ARM64_PAGE_SHIFT=16/' .config sed -i 's/CONFIG_PGTABLE_LEVELS=4/CONFIG_PGTABLE_LEVELS=3/' .config echo "CONFIG_ARM64_64K_PAGES=y" >> .config

结果:仍然卡在EFI stub,证明存在隐藏依赖。

3.2 进阶:配置嫁接术(部分成功)

采用发行版config作为基础,嫁接自定义修改:

cp /boot/config-4.19.90-2112.8.0.0131.oe1.aarch64 .config make olddefconfig

操作技巧:

  • 通过make menuconfig交互界面保留所需功能模块
  • 必须手动检查以下关键项:
    grep -E "ARM64_64K_PAGES|PAGE_SHIFT|PGTABLE_LEVELS" .config

3.3 终局:源码级适配(成功)

最终解决方案需要修改arch/arm64/Kconfig:

+config ARCH_PHYTIUM + bool "Phytium Processor Support" + select ARM64_64K_PAGES + select PGTABLE_LEVELS=3 + help + This enables support for Phytium FT-2000+/2500 processors

重新生成配置后,必须执行:

make clean make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j64

4. 可持续维护方案

对于长期维护需求,推荐建立配置管理仓库:

kernel-config/ ├── base_config # 官方基础配置 ├── oE_patches # openEuler特有补丁 │ ├── 0001-arm64-phytium.patch │ └── 0002-memory-layout.patch └── merge_config.sh # 自动化合并脚本

关键脚本片段:

#!/bin/bash KERNEL_SRC=$1 cd ${KERNEL_SRC} # 应用所有补丁 for patch in ../oE_patches/*.patch; do patch -p1 < $patch done # 合并配置 cp ../base_config .config ./scripts/kconfig/merge_config.sh .config ../oE_patches/*.config make olddefconfig

5. 深度避坑清单

  1. 内存对齐陷阱:

    • FT2000+要求64KB对齐的物理地址
    • 在arch/arm64/mm/init.c中增加调试语句:
      pr_info("Physical memory layout:\n"); pr_info(" PHY_OFFSET = 0x%llx\n", PHYS_OFFSET);
  2. ACPI表差异:

    • 飞腾平台需要特殊APIC配置
    • 检查drivers/acpi/tables.c的解析逻辑
  3. 早期控制台输出:

    # 在cmdline添加早期调试参数 console=ttyAMA0,115200 earlycon=pl011,mmio32,0x28000000

那次凌晨4点的成功启动让我明白:国产化平台的"特性"不是障碍,而是通向深度定制的门票。现在我的团队维护着20+台FT2000+服务器,每台都带着这份血泪经验编译出的内核稳定运行——这就是最好的技术勋章。

← 返回列表