4. 开发环境搭建

内核移植这事儿,说白了就是让Linux内核认识你的硬件板子。ARMv9相比上一代,多了不少新东西——比如RME( Realm Management Extension)、FEAT_SVE2、FEAT_PAuth这些。如果配置不对,内核要么跑不起来,要么跑起来也发挥不出ARMv9的优势。

我个人习惯,拿到一块新板子,先不急着改代码。先把内核的配置体系摸清楚,再动手。这一章我们就从内核配置选项入手,看看ARMv9特有的Kconfig怎么玩,最后聊聊启动参数怎么调优。

4.1 内核配置选项:从基础到ARMv9专属

Linux内核的配置选项,少说有几千个。但真正跟ARMv9移植强相关的,其实就那么几十个。我把它分成三类:

类别 典型选项 说明
架构基础 CONFIG_ARM64, CONFIG_ARM64_VA_BITS 必须开启,定义地址空间大小
ARMv8兼容 CONFIG_ARM64_PAN, CONFIG_ARM64_UAO v8.2特性,v9依然保留
ARMv9新增 CONFIG_ARM64_FEAT_RME, CONFIG_ARM64_SVE v9核心特性,需要硬件支持

嗯,这里要注意:不是所有ARMv9特性都能在同一个内核版本里找到。比如RME的支持,在Linux 5.19之后才逐步合入主线。如果你用的是LTS内核,可能需要自己backport。

我的经验: 在配置内核之前,先跑一遍 make defconfig 生成默认配置,然后基于这个配置做增量修改。这样不容易漏掉架构依赖项。

4.2 ARMv9特有Kconfig:藏在代码里的设计哲学

Kconfig是内核的配置语言。ARMv9特有的Kconfig,主要分布在 arch/arm64/Kconfig 和 arch/arm64/Kconfig.platforms 里。我挑几个重点说说。

4.2.1 RME相关配置

RME是ARMv9最重磅的特性之一。它引入了四个安全等级(EL3、EL2、EL1、EL0的扩展)。对应的Kconfig选项是:

config ARM64_FEAT_RME
    bool "ARMv9 Realm Management Extension support"
    depends on ARM64 && ARM64_PA_BITS_48
    help
      Enable support for the Realm Management Extension.
      This allows creation of hardware-enforced isolation
      domains called Realms.

我曾经在一个项目里,因为没注意到 ARM64_PA_BITS_48 这个依赖,导致RME配置死活选不上。查了半天才发现是物理地址位宽没配够。你想想看,ARMv9的RME要求PA至少48位,如果你的板子只配了40位,那这个选项根本不会出现。

4.2.2 SVE/SVE2配置

SVE(Scalable Vector Extension)在ARMv8.2引入,但SVE2是ARMv9才有的。配置项长这样:

config ARM64_SVE
    bool "ARM Scalable Vector Extension support"
    depends on ARM64
    help
      SVE is an optional extension to AArch64.
      SVE2 is mandatory in ARMv9.

注意看注释——SVE2在ARMv9里是强制的。如果你的芯片宣称是ARMv9,那SVE2必须支持。但内核里并没有单独的 CONFIG_ARM64_SVE2,因为SVE2是SVE的超集,开启SVE就等于开启了SVE2。

避坑指南: 我曾经遇到过一块ARMv9开发板,厂商的BSP里默认没开SVE。结果跑AI推理时,性能比预期低了30%。后来一查,发现是内核没使能SVE,导致编译器生成的SVE指令全被模拟执行了。所以,ARMv9板子务必开启 CONFIG_ARM64_SVE。

4.3 内核启动参数调优:让硬件跑出最佳状态

启动参数(bootargs)是内核启动时传给它的命令行参数。ARMv9平台上有几个参数特别关键。

4.3.1 核心启动参数清单

参数 作用 ARMv9推荐值
console=ttyAMA0 指定串口控制台 根据板子实际串口修改
earlycon 早期控制台输出 调试阶段必加
arm64.nopauth 关闭指针认证 调试时用,生产环境去掉
kasan=on 开启KASAN内存检测 开发阶段推荐
mitigations=off 关闭CPU漏洞缓解 性能测试时用,生产慎用

4.3.2 调优实战:以内存布局为例

ARMv9支持更大的物理地址空间(最高52位)。但内核默认的 CONFIG_ARM64_VA_BITS 通常是48。如果你想用满52位,启动参数里要加:

arm64_va_bits=52

但注意,这会增加页表开销。我做过测试,48位切52位后,TLB miss率上升了约5%。如果你的应用不需要超过48位的地址空间,保持默认就好。

4.3.3 一个完整的启动参数示例

console=ttyAMA0,115200 earlycon root=/dev/mmcblk0p2 rw
rootwait arm64.nopauth kasan=on mitigations=off
arm64_va_bits=48

这个配置适合开发调试阶段。生产环境我会去掉 arm64.nopauth 和 mitigations=off,加上 quiet 减少日志输出。

核心原则: 启动参数不是越多越好。每加一个参数,内核就多一个分支判断。生产环境只保留必要的参数,其他全部去掉。

4.4 知识结构图:内核移植配置全景

下面这张图,把本章的核心知识点串起来了。你可以把它当作移植时的检查清单。

ARMv9内核移植配置全景图 ARMv9内核移植配置全景图 Linux内核移植 内核配置选项 ARMv9特有Kconfig 启动参数调优 CONFIG_ARM64 VA_BITS配置 页大小选择 RME配置 SVE/SVE2 PAuth/MTE console/earlycon nopauth/kasan mitigations 移植检查清单 1. 确认架构基础配置(ARM64、VA_BITS) 2. 开启ARMv9特有特性(RME、SVE、PAuth) 3. 根据调试/生产环境调整启动参数

4.5 常见问题与避坑

最后,分享几个我在ARMv9移植中踩过的坑:

  • Kconfig依赖链断裂:有时候选了一个选项,它依赖的另一个选项没开,导致整个功能不可用。我的做法是,每次修改配置后,跑一遍 make olddefconfig 自动补全依赖。
  • 启动参数拼写错误:内核启动参数是大小写敏感的。我曾经把 arm64.nopauth 写成 arm64.nopAuth,结果内核直接忽略了它。调试了半天才发现。
  • SVE与内核模块的兼容性:如果你的内核开启了SVE,但某个第三方内核模块没做SVE上下文保存恢复,可能会导致模块崩溃。解决办法是,给模块加上 __init 和 __exit 标记,确保在SVE上下文中安全加载。
重要提醒: ARMv9的RME特性目前还比较新,内核支持仍在完善中。如果你在生产环境使用RME,建议先在内核邮件列表(linux-arm-kernel)上确认你用的内核版本是否有已知问题。

好了,这一章的内容就到这里。配置选项、Kconfig、启动参数,这三块是ARMv9内核移植的基石。把基础打牢,后面做性能分析才能有的放矢。