为什么只用替换.config,不用重新编译内核源码
主要原因有以下几点:
1. 节省时间(效率问题)
- 完整编译内核:编译整个 RK3588 内核可能需要 20 分钟甚至 1 个小时(取决于你的电脑配置)。它会生成内核镜像、数千个内置驱动和设备树文件。
- 预处理(modules_prepare) :只需要几秒钟到一分钟。它只生成编译外部驱动所必须的头文件(
.h)和符号信息。
2. 你不需要更换板子上的"地基"
- 你的香橙派已经跑起来了,说明它内部已经有一个编译好的内核(Image)在运行。
- 你现在的目标是编写一个 外挂模块 (.ko)。只要你的模块和板子上正在运行的内核"对齐"了(即:基因一致),就可以直接插进去用,不需要重新造一个地基。
3. 什么是"对齐"?(核心原理)
编译外部驱动时,编译器其实只需要知道三件事:
.config:内核开启了哪些功能?(比如是否开启了 SPI、GPIO)- 头文件:寄存器定义、函数声明是什么?
Module.symvers:内核导出的函数(比如spi_sync)在内存中的"签名"是什么?
make modules_prepare 的作用就是根据你提供的 .config,把这三件事准备好。只要这三点和板子上的内核一致,编译出来的驱动就能运行。
4. 什么时候必须完整编译内核?
只有在以下情况,你才需要完整编译整个内核源码:
- 修改了内核核心代码:比如你改了进程调度逻辑、内存管理算法。
- 修改了必须"内置"的驱动 :有些驱动不能做成
.ko,必须编译进Image(比如根文件系统的磁盘驱动)。 - 需要生成新的
dtb(设备树二进制文件):虽然可以单独编设备树,但通常在大规模修改时会完整跑一遍。
5. 总结你的情况
你现在是在做外部驱动开发:
- 板子的内核已经定了(5.10.160)。
- 你只需要测你的
icm42688p_asy.ko。 - 所以,你只需要 "配置(.config)+ 预处理(prepare)" 即可。这不仅快,而且能保证你的驱动和板子内核完美契合。
一句话总结 :
完整编译内核是造"房子",编译驱动是造"门"。如果你家房子已经盖好了,你只需要量一下门口的尺寸(prepare),不需要把整栋楼拆了重盖。
为了确保你的驱动程序能够 100% 匹配香橙派的内核,请按照以下完整的指令集操作。
这些指令分为三个阶段:获取配置 、初始化内核环境 、重新编译驱动。
第一阶段:在香橙派(Orange Pi)上获取配置
如果你已经把 /boot/config-5.10.160-rockchip-rk3588 传到 Ubuntu 了,可以跳过这一步。
bash
# 在香橙派终端执行
cp /boot/config-5.10.160-rockchip-rk3588 ~/opi_config
# 使用 scp 将文件传送到 Ubuntu 虚拟机的家目录
scp ~/opi_config xiaodong@虚拟机IP:~/
# 本人指令
scp ~/opi_config xiaodong@192.168.142.128:/home/xiaodong/orangepi-build-next/kernel/orange-pi-5.10-rk35xx/
第二阶段:在 Ubuntu 上初始化内核源码环境
这一步是解决 Invalid module format 和为 Segmentation fault 调试提供标准环境的核心。
bash
# 1. 进入内核源码目录
cd /home/xiaodong/orangepi-build-next/kernel/orange-pi-5.10-rk35xx
# 2. 替换配置文件
# 注意:一定要把刚才从板子拿到的配置文件重命名为 .config 并放到源码根目录
cp ~/opi_config .config
# 3. 定义交叉编译器变量(这样下面的命令更简洁,请确保路径正确)
export ARCH=arm64
export CROSS_COMPILE=/home/xiaodong/orangepi-build-next/toolchains/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
# 4. 让内核源码同步该配置文件 (会自动根据 .config 调整环境)
make olddefconfig
# 5. 生成内核编译所需的脚本工具
make scripts
# 6. 准备编译外部模块所需的头文件和版本信息 (最关键的一步)
make modules_prepare
第三阶段:重新编译驱动程序
下面是本人开发过程过程中,进行驱动测试,可以用自己的驱动测试。
在执行这一步前,请务必确认你已经修改了 icm42688p_asy.c 里的内存溢出漏洞 (即 read_regs 缓冲区分配问题),否则即使编译成功,加载后依然会段错误。
bash
# 1. 进入驱动源码目录
cd /home/xiaodong/XWCode/04_Linux驱动程序/95_icm42688p_asy
# 2. 清理旧的编译文件
make clean
# 3. 开始编译
make
# 4. 验证生成的 .ko 文件版本信息
modinfo icm42688p_asy.ko | grep vermagic
验证结果: 此时看到的 vermagic 应该和你在香橙派上执行 uname -r 的结果,以及 modversions 关键字完全匹配。
第四阶段:在香橙派上加载(最后的临门一脚)
-
重启香橙派 (非常重要!之前的
Segmentation fault可能导致内核状态异常,必须重启清理内存)。 -
拷贝新的
.ko到香橙派。 -
加载驱动:
bashsudo insmod icm42688p_asy.ko
为什么这个流程是可靠的?
- olddefconfig :它会读取你提供的
.config,并自动填补缺失的默认值,确保CONFIG_MODVERSIONS=y和LOCALVERSION完全对齐。 - modules_prepare :它会生成
Module.symvers等文件,这些文件包含了内核所有导出函数的签名。如果驱动编译时没有这些信息,加载时就会崩溃。 - make clean:保证之前的旧 object 文件不会干扰新的编译。
注意: 如果在 make modules_prepare 时报错,请检查你的交叉编译器路径是否与我写的一致。如果不一致,请修改 CROSS_COMPILE 变量。