2076 字
10 分钟
设备树踩坑记:Pearl (Redmi Note 12T Pro) 开发实录

设备树踩坑记:Pearl 开发实录#

本文基于 Xiaomi-Pearl-Development/android_device_xiaomi_pearl 的 commit 整理,目标 ROM 为 LineageOS 22.2 (Android 15),设备为 Redmi Note 12T Pro (codename: pearl),SoC 为 MediaTek Dimensity 8200 Ultra (MT6896)。


1. SELinux Permissive:三种方法都不省心#

坑 1:内核命令行参数在 DSU 下不生效#

最初尝试在 BoardConfig.mk 中添加:

BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive

问题:在 DSU(Dynamic System Updates)环境下这个参数不生效。DSU 有自己的启动流程,会忽略部分内核命令行参数。

尝试的解决方案:改为在 init.pearl.rc 中写入:

on early-init
write /sys/fs/selinux/enforce 0

结果:这需要额外的 SELinux 权限 allow init kernel:security setenforce,形成鸡生蛋的问题——你要关 SELinux 先得有 SELinux 权限。

最终方案:直接使用 SELINUX_IGNORE_NEVERALLOWS := true(开发阶段),后来在 sepolicy 基本完成后移除。

教训:DSU 是开发利器,但 SELinux 相关的内核命令行参数在 DSU 下可能不生效。开发初期直接用 SELINUX_IGNORE_NEVERALLOWS 最省事,但记得在提交前移除实际上,SeLinux Permissive的相关配置在我的开发中基本没有生效,这是MediaTek的问题。


2. keymint-mitee 服务启动失败#

坑 2:Could not start service 'vendor.keymint-mitee' as part of class 'early_hal'#

现象:开机后 keymint 服务无法启动,导致指纹、锁屏等功能全部失效。

原因vendor.keymint-mitee 是 Xiaomi 私有的 TEE keymint 实现,默认的 service 定义不完整,缺少 interface 声明。

解决方案:在 init.pearl.rc 中 override 这个服务:

service vendor.keymint-mitee /vendor/bin/hw/android.hardware.security.keymint@1.0-service.mitee
override
class early_hal
interface android.hardware.keymaster@4.0::IKeymasterDevice default
interface android.hardware.keymaster@4.1::IKeymasterDevice default
user system
group system drmrpc
seclabel u:r:hal_keymint_default:s0
disabled
on boot
enable vendor.keymint-mitee

教训:MTK 平台的 TEE 实现(mitee)需要手动 override 服务定义并添加 interface 声明。如果看到 “Could not start service” 错误,先检查服务定义是否完整。


3. 内核模块:多了会出事#

坑 3:添加 xm_power_debug.ko 后需要 revert#

过程

  1. commit e1da76a:添加了 xm_power_debug.komodules/modules.load
  2. commit 9075393revert 了这个改动

原因:这个模块不是必需的,而且可能导致启动问题。

教训:内核模块不要随意添加。只加载设备实际需要的模块。如果不确定,先不加,等出现问题再按需添加。多余的模块可能:

  • 增加启动时间
  • 引发内核 panic
  • 与其他模块冲突

4. Thermal 服务崩溃#

坑 4:android.hardware.thermal-service.mediatek 导致系统崩溃#

现象:添加 thermal HAL 后系统崩溃。

过程

  1. 添加了 android.hardware.thermal-service.mediatekthermal_info_config.json
  2. 系统崩溃
  3. commit 1bf46cbrevert 整个 thermal 配置

原因:thermal config 文件与设备的硬件不匹配,thermal zone 路径或阈值配置错误。

教训:thermal 配置需要精确匹配硬件。错误的 thermal config 会导致系统崩溃甚至硬件损坏。建议:

  • 先从同 SoC 的其他设备树复制
  • 逐步调整参数
  • 测试时注意温度监控

5. Blob 命名冲突:fingerprint HAL#

坑 5:fingerprint blob 命名冲突导致 HAL 无法加载#

现象:指纹功能不工作。

原因:从 stock ROM 提取的 fingerprint.fpc.so 与系统中的 ODM HAL 命名冲突。

解决方案(commit ee2dea9):

vendor/lib64/hw/fingerprint.fpc.so
vendor/lib64/hw/fingerprint.fpc.so:vendor/lib64/hw/fingerprint.fpc.default.so;FIX_SONAME

将 blob 重命名为 fingerprint.fpc.default.so 并修复 SONAME。

教训:Xiaomi 的 ODM 分区可能包含同名的 HAL blob。当 blob 无法加载时,检查是否有命名冲突。解决方案是重命名并用 FIX_SONAME 修复动态链接。同样的问题也出现在 audio.primary.mediatek.so 上。


6. fstab 配置:细节决定成败#

坑 6:fstab 格式错误和参数不当#

问题 1:fstab 拼写错误(commit c39ddee

问题 2:userdata 分区的 resize 标志导致问题(commit 9524ecf):

wait,check,formattable,quota,resize,latemount
wait,check,formattable,quota,latemount

问题 3:metadata 分区需要 data=journal,commit=1(commit a1767d0):

noatime,nosuid,nodev,discard
noatime,nosuid,nodev,discard,data=journal,commit=1

教训:fstab 是最容易出错的文件之一,因为:

  • 格式严格,多一个空格都可能出问题
  • 参数顺序和组合影响挂载行为
  • 不同设备的分区参数可能不同
  • 建议从同 SoC 设备复制后逐项检查

7. 虚拟接近传感器:一个功能改了 5 个 commit#

坑 7:Pearl 没有物理接近传感器#

Pearl 没有物理接近传感器,需要使用虚拟接近传感器。这个功能的实现涉及 5 个 commit:

  1. 3d6efa0:添加 sepolicy for proximity sensor
  2. 13f395b:setup overlay for pearl
  3. 6dbd948:setup policy for virtual proximity
  4. f4d1bee:add file contexts for virtual proximity
  5. 26b7859:fixup virtual proximity sensor(最终修复

关键修复(commit 26b7859):

sepolicy/vendor/file_contexts
/dev/mius(.*)? u:object_r:sensors_device:s0
/sys/bus/iio/devices u:object_r:sysfs_tp_virtual_prox:s0
/sys/devices/platform/us_prox.0/iio:device4(/.*)? u:object_r:sysfs_tp_virtual_prox:s0
# sepolicy/vendor/hal_sensors_default.te
allow hal_sensors_default iio_device:chr_file r_file_perms;
allow hal_sensors_default sysfs_tp_virtual_prox:dir r_dir_perms;

教训:虚拟接近传感器需要:

  1. 正确的 file_contexts(设备节点路径)
  2. 正确的 SELinux 策略(对 iio_device 和 sysfs 的访问权限)
  3. 正确的 property 配置(persist.vendor.fingerprint.sensor_location
  4. 传递 display ID 到 sensor location

这是一个典型的”多层配置都要对”的案例。


8. 指纹支付:微信 SoterService#

坑 8:微信指纹支付不工作#

现象:指纹功能正常,但微信指纹支付无法使用。

解决方案(commit 29d9955):添加 SoterService

PRODUCT_PACKAGES += \
SoterService

原因:微信使用 SOTER(Secure Online TEE-based biometric Authentication)框架进行指纹支付验证,需要 SoterService 支持。

教训:指纹功能和指纹支付是两回事。指纹支付需要:

  • 正确的 TEE 实现(mitee)
  • SoterService
  • IFAAService(支付宝/微信的 IFaa 认证)

9. VINTF 清理:HAL 声明不能多也不能少#

坑 9:VINTF manifest 中的冗余声明#

commit 8903f3d:cleanup vintf and Kill 2ND arch

问题:VINTF manifest 中声明了设备不支持的 HAL,或者有冗余的 HAL 声明。

教训:VINTF manifest 应该只声明设备实际提供的 HAL。多余的声明会导致:

  • CTS 测试失败
  • 框架尝试调用不存在的 HAL
  • 启动时的 VINTF 兼容性检查失败

10. Recovery 触摸固件#

坑 10:Recovery 模式下触摸不工作#

commit 8885235:Add touchscreen firmware for recovery

问题:在 recovery 模式下触摸屏不工作,无法通过触摸操作 recovery。

解决方案:将触摸屏固件添加到 recovery ramdisk。

教训:Recovery 模式需要单独的驱动和固件支持。如果 stock ROM 的 recovery 支持触摸,移植时需要确保固件也被包含。


11. 移除不必要的东西#

坑 11:Xiaomi 私有服务不都是必需的#

Pearl 移除的不必要组件:

组件原因
displayfeatureXiaomi 私有显示服务,LineageOS 不需要
vibratorfeatureXiaomi 私有振动器服务
Power-off Alarm功能不完整
多余的 kernel modules引发问题
32-bit blob设备不需要

教训:不要盲目复制 stock ROM 的所有组件。很多 Xiaomi 私有服务在 AOSP/LineageOS 环境下不工作或不需要。逐个测试,不工作的就移除。


12. Blob Fixup 常见模式#

从 Pearl 的开发中总结出的 blob fixup 常见模式:

12.1 重命名 + FIX_SONAME#

当 blob 与系统中已有 HAL 命名冲突时:

vendor/lib64/hw/fingerprint.fpc.so:vendor/lib64/hw/fingerprint.fpc.default.so;FIX_SONAME
vendor/lib64/hw/audio.primary.mediatek.so;SYMLINK=vendor/lib64/hw/audio.primary.mt6895.so

12.2 符号链接#

当 blob 期望在特定路径找到时:

vendor/lib64/hw/mt6895/camerahalserver;SYMLINK=vendor/bin/hw/camerahalserver

12.3 禁用 ELF 检查#

当 blob 的 ELF 格式不标准时:

vendor/lib64/libHalSuperSensorServer.so;DISABLE_CHECKELF

12.4 仅生成复制规则#

当 blob 只需要在构建时复制,不需要运行时检查:

vendor/bin/crossbuild/DataSet/...;MAKE_COPY_RULE_ONLY

13. 开发流程建议#

基于 Pearl 的经验,建议的开发流程:

Phase 1:能开机就行#

  1. 使用 prebuilt kernel
  2. 配置最基础的 fstab
  3. 设置 SELinux permissive(SELINUX_IGNORE_NEVERALLOWS := true
  4. 确保能进入系统(即使很多功能不工作)

Phase 2:基础功能#

  1. WiFi
  2. 蓝牙
  3. 显示
  4. 触摸

Phase 3:核心功能#

  1. 指纹
  2. 相机
  3. NFC
  4. 音频

Phase 4:调试与修复#

  1. 逐个修复 blob 问题
  2. 处理 SELinux 拒绝
  3. 测试所有功能

Phase 5:清理#

  1. 移除不必要的组件
  2. 合并到 common tree
  3. 从 permissive 切换到 enforcing

14. 调试技巧#

14.1 SELinux 拒绝#

Terminal window
# 收集所有 avc 拒绝
adb shell dmesg | grep avc | grep denied
# 生成策略规则
adb shell dmesg | grep avc | audit2allow -p policy
# 查看特定进程的拒绝
adb shell dmesg | grep avc | grep hal_fingerprint

14.2 HAL 服务问题#

Terminal window
# 查看 HAL 服务状态
adb shell service list | grep hal
# 查看 HAL 进程是否运行
adb shell ps -A | grep hal
# 查看 HAL 服务日志
adb logcat -s hal_fingerprint

14.3 内核模块问题#

Terminal window
# 查看已加载模块
adb shell lsmod
# 查看模块加载日志
adb shell dmesg | grep insmod
# 查看模块依赖
adb shell modinfo /vendor/lib/modules/xxx.ko

14.4 Blob 依赖问题#

Terminal window
# 查看 blob 依赖
readelf -d vendor/lib64/hw/xxx.so | grep NEEDED
# 查看 blob 的 SONAME
readelf -d vendor/lib64/hw/xxx.so | grep SONAME
# 检查符号链接
ls -la vendor/lib64/hw/

15. 时间线:commit 的故事#

整个开发过程约 2 周(2025-08-31 至 2025-09-14)。

工作量分布

  • Blob fixup:~30% 的 commit
  • SELinux 策略:~25% 的 commit
  • HAL 配置:~20% 的 commit
  • 清理/重构:~15% 的 commit
  • 其他:~10%

最耗时的部分

  1. Blob 调试(反复试错)
  2. SELinux 策略(每次改一点)
  3. 虚拟接近传感器(5 个 commit 才搞定)

参考#

设备树踩坑记:Pearl (Redmi Note 12T Pro) 开发实录
https://lnpo.qzz.io/posts/android-device-tree-pitfalls/
作者
Enceka
发布于
2026-06-19
许可协议
CC BY-NC-SA 4.0