Files
reverse-skills-max/vendor-new/rev-skills/.claude/skills/re-kernel/references/android-kernel.md

3.6 KiB
Raw Blame History

Android 内核模块分支(GKI / vendor module)

前提认知:Android 内核不能只当普通 Linux 处理——模块身份(GKI / vendor)、KMI 符号白名单、分区与加载阶段都会决定"这份模块到底能不能加载、为什么加载失败"。

一、先分清模块身份

  • GKI module(Google 提供、随 GKI kernel 签名) vs vendor module(OEM/自建、未签名)
  • 三方符号权限不同:protected GKI module / unprotected GKI module / vendor module 各有可访问的符号集合;vendor(unsigned)模块只能使用 KMI 符号,越界会被拒绝加载
  • 构建期检查:ACK kernel/build 的 abi/check_buildtime_symbol_protection.py——unsigned 模块里所有 undefined symbol 必须在 KMI 符号清单内,或被另一个 unsigned 模块定义;否则即使构建成功,运行时也会被拒绝加载(构建期只是提前告警)
  • 运行时症状:module: Protected symbol: xxx (err -13) / module: exports protected symbol xxx → 不要按普通 Linux"找不到符号 → patch 地址"处理:这是 GKI 的符号保护策略,先识别 GKI protection / KMI 边界
  • KMI 符号清单位置:android/abi_gki_aarch64.xml 与各子系统 fragment 文件

二、KMI 分支 ≠ 内核版本

  • KMI 稳定性只存在于同一 LTS + 同一 Android 大版本的组合(例如 android14-6.1、android15-6.6、android16-6.12);android-mainline 不保证 KMI 稳定
  • 因此 android12-5.10 与 android13-5.10 虽然都是 Linux 5.10,KMI 并不兼容:用某一分支的 Module.symvers 构建的模块,与另一分支的 kernel/GKI 模块对不上;GKI 模块由 Google 签名,"只与它构建时对应的 GKI kernel 兼容"
  • 分析/移植时的正确判据:精确到 androidXX-X.Y + KMI generation + symbol list + Module.symvers/CRC,而不是 5.10 == 5.10

三、模块在哪里、会不会被加载

  • 查找位置(不要硬编码 *_dlkm backing 路径;AOSP 建议外部逻辑访问 /vendor/lib/modules、/odm/lib/modules): /vendor/lib/modules、/odm/lib/modules、/system/lib/modules(早期模块在 vendor ramdisk 的 /lib/modules)
  • 实际 backing 分区可能是:vendor_dlkm / odm_dlkm / system_dlkm
  • 加载顺序与依赖:modules.load、modules.dep、modules.softdep
    • first-stage init 从 vendor ramdisk 的 /lib/modules/modules.load 按序加载 early modules,实际顺序会因 hard/soft dependency 变化
    • 晚期 vendor 模块可能来自 vendor/ODM DLKM
  • 文件存在 ≠ 会被加载;而且依赖的模块可能位于另一个分区 / 另一个 boot stage

工具与验证

  • modinfo(vermagic / 依赖 / 签名)、readelf -S(.modinfo / .BTF)、/proc/kallsyms、/sys/module/<name>/
  • GKI 侧:以目标分支的 symbol list 与 Module.symvers 做比对;签名侧见 scripts/sign-file(GKI 由 Google 签名、vendor 由 OEM 签名,key 需在 AVB 信任链内)
  • 验证:能同时给出「模块身份(GKI/vendor)+ KMI 分支 + 所在分区 + 是否在 modules.load 计划内」

该平台的坑

  • 把 android12-5.10 与 android13-5.10 当同一个内核:KMI 不兼容
  • 见到 Protected symbol 就按普通 Linux 去 patch 符号:那是 GKI 策略,不是符号缺失
  • 硬编码 *_dlkm 路径去找模块:按 AOSP 建议走 /vendor/lib/modules 等入口
  • 认为"文件在 = 已加载":要看 modules.load、依赖与分区
  • 忘了模块可能是 built-in:Android 侧同样存在(与 Linux 分支同理)