为客户固定内核编译 RK1828 PCIe 驱动模块
本文说明如何在不修改客户板内核的前提下,为 RK1828 PCIe 端点编译并验证 pcie-rkep.ko。
适用的客户板内核为:
6.12.69-gREDACTED_COMMIT-dirty
目标与前提
目标模块必须能在客户内核中加载,并创建 PCIe RK1828 设备节点:
/dev/pcie-rkep-0000:01:00.0
准备条件:
- 客户板可通过 ADB 连接。
- 主机已有 RK3588 SDK 的
kernel-6.1Git 仓库及 ARM64 交叉编译器。 - RK1828 已枚举为 PCIe 端点
0000:01:00.0,设备 ID 为1d87:182a。
不要使用版本不同的 .ko。即使主版本同为 6.12.69,Git 提交号或 -dirty 后缀不同,内核也会拒绝加载。
读取客户板的内核版本与配置
先以客户板实际运行结果为准:
adb shell uname -r
adb pull /proc/config.gz /tmp/rk3572-customer-config.gz
gzip -dc /tmp/rk3572-customer-config.gz > /tmp/rk3572-customer.config
检查与模块构建直接相关的配置:
grep -E '^(CONFIG_LOCALVERSION|CONFIG_LOCALVERSION_AUTO|CONFIG_PCIE_FUNC_RKEP|CONFIG_MODVERSIONS|CONFIG_MODULE_SIG)=' \
/tmp/rk3572-customer.config
本次客户板的关键配置如下:
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_PCIE_FUNC_RKEP=m
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SIG is not set
CONFIG_PCIE_FUNC_RKEP=m 表示该驱动以 .ko 模块方式构建。未启用 CONFIG_MODVERSIONS 表示模块不携带符号 CRC;仍必须使 vermagic 与 uname -r 完全一致。
定位客户内核源码提交
客户内核版本中的 gREDACTED_COMMIT 对应提交为:
REDACTED_COMMIT
在 RK3588 SDK 的内核仓库中更新远程历史并确认该提交存在:
cd /home/user/workspace/RK3588/kernel-6.1
git fetch rk develop-6.12
git show -s --format='%H%n%ad%n%s' --date=iso-strict \
REDACTED_COMMIT
不要切换当前 SDK 主工作区。使用独立 worktree,避免影响正在使用的 SDK 分支:
cd /home/user/workspace/RK3588/kernel-6.1
git worktree add --detach /tmp/rk3572-kernel-6.12.69-REDACTED_COMMIT \
REDACTED_COMMIT
cp /tmp/rk3572-customer.config /tmp/rk3572-kernel-6.12.69-REDACTED_COMMIT/.config
复现 -dirty 版本后缀
-dirty 表示客户内核在编译时存在未提交源码修改。客户配置启用了 CONFIG_LOCALVERSION_AUTO=y,因此构建系统会把 Git 提交号和工作区状态写入模块 vermagic。
为复现客户板的版本字符串,只在临时 worktree 中为任意已跟踪源码文件加入一行无功能影响的注释,使其工作区处于 dirty 状态。不要在客户板或当前 SDK 主工作区做此修改。
完成后,目标 vermagic 应为:
6.12.69-gREDACTED_COMMIT-dirty SMP mod_unload aarch64
编译 pcie-rkep.ko
RK3588 SDK 使用的交叉编译器路径如下:
/home/user/workspace/RK3588/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
在临时 worktree 中执行:
cd /tmp/rk3572-kernel-6.12.69-REDACTED_COMMIT
make ARCH=arm64 \
CROSS_COMPILE=/home/user/workspace/RK3588/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- \
olddefconfig
make -j8 ARCH=arm64 \
CROSS_COMPILE=/home/user/workspace/RK3588/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- \
prepare modules_prepare
make -j8 ARCH=arm64 \
CROSS_COMPILE=/home/user/workspace/RK3588/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- \
KBUILD_MODPOST_WARN=1 \
drivers/misc/rockchip/pcie-rkep.ko
本次仅构建模块,未生成完整 vmlinux.o,所以 modpost 会提示未解析内核符号。由于客户配置未启用 CONFIG_MODVERSIONS,模块可以在运行内核加载时解析这些符号;因此必须执行下一节的板端加载验证。
检查模块版本:
modinfo drivers/misc/rockchip/pcie-rkep.ko | grep -E '^(name|vermagic):'
预期输出:
name: pcie_rkep
vermagic: 6.12.69-gREDACTED_COMMIT-dirty SMP mod_unload aarch64
生成模块路径:
/tmp/rk3572-kernel-6.12.69-REDACTED_COMMIT/drivers/misc/rockchip/pcie-rkep.ko
在客户板临时加载验证
先传到 /tmp,不会覆盖 rootfs:
adb push \
/tmp/rk3572-kernel-6.12.69-REDACTED_COMMIT/drivers/misc/rockchip/pcie-rkep.ko \
/tmp/pcie-rkep-customer.ko
adb shell insmod /tmp/pcie-rkep-customer.ko
验证模块、设备节点和 MSI:
adb shell 'grep "^pcie_rkep " /proc/modules'
adb shell 'ls -l /dev/pcie-rkep-*'
adb shell 'ls -1 /sys/bus/pci/devices/0000:01:00.0/msi_irqs'
adb shell "dmesg | grep -iE 'pcie-rkep.*msi|request msi'"
成功时应看到 pcie_rkep 已加载、/dev/pcie-rkep-0000:01:00.0 存在,以及驱动日志:
success to request msi irq
安装到客户 rootfs
临时验证成功后,才将模块持久安装到客户 rootfs:
adb push \
/tmp/rk3572-kernel-6.12.69-REDACTED_COMMIT/drivers/misc/rockchip/pcie-rkep.ko \
/tmp/pcie-rkep.ko
adb shell 'install -m 0644 /tmp/pcie-rkep.ko /usr/lib/modules/pcie-rkep.ko'
重新检查版本必须完全匹配:
adb shell 'uname -r; modinfo -F vermagic /usr/lib/modules/pcie-rkep.ko'
常见问题
Invalid module format
比较内核和模块的版本:
adb shell 'uname -r; modinfo -F vermagic /usr/lib/modules/pcie-rkep.ko'
两者必须完全相同。旧 rootfs 中曾出现过 6.12.69-gREDACTED_COMMIT 的模块,它与客户内核 6.12.69-gREDACTED_COMMIT-dirty 不同,因此无法加载。
没有 /dev/pcie-rkep-*
确认 PCIe 端点仍已枚举:
adb shell 'cat /sys/bus/pci/devices/0000:01:00.0/vendor /sys/bus/pci/devices/0000:01:00.0/device'
预期为:
0x1d87
0x182a
若端点存在但节点未创建,重新检查 insmod 返回值和 dmesg 中的 pcie-rkep 日志。