Linux 内核头文件
在 Neardi Pi 3 上编译第三方驱动、外置内核模块时,一般需要安装与当前固件匹配的内核头文件。
这里先介绍比较稳妥的做法:在 x86 Ubuntu PC 的 Linux SDK 中生成头文件安装包,再复制到板子上安装和测试。
下载编译好的头文件
已经编译好的 Neardi Pi 3 内核头文件可以从下面的链接下载:
下载内核头文件,提取码:ldkj
下载和安装前,先在板子上查看当前内核版本和架构:
neardi@RK3576:~$ uname -a
选择的头文件需要同时匹配当前运行的内核版本和架构。Neardi Pi 3 使用 aarch64 架构,对应的 Debian 安装包文件名一般以 _arm64.deb 结尾。
例如,uname -a 显示内核版本为 6.1.118、架构为 aarch64,就选择 6.1.118 的 ARM64 头文件。不能只看架构相同,就安装其他内核版本的头文件。
安装下载的头文件
使用 dpkg 安装下载好的头文件包,文件名根据实际下载的版本替换:
neardi@RK3576:~$ sudo dpkg -i ./linux-headers-xxx_arm64.deb
例如:
neardi@RK3576:~$ sudo dpkg -i \
./linux-headers-6.1.118_6.1.118-3_arm64.deb
查看已经安装的 linux-headers 软件包:
neardi@RK3576:~$ dpkg -l | grep linux-headers
ii linux-headers-6.1.118 6.1.118-3 arm64 Linux kernel headers for 6.1.118 on arm64
linux-headers-6.1.118 就是刚安装的头文件包,一般安装在板子的 /usr/src/ 目录:
neardi@RK3576:~$ ls -ld /usr/src/linux-headers-*
在 SDK 中生成头文件
进入 Linux SDK 根目录,先选择 Neardi Pi 3 对应的配置:
neardi@ubuntu2204-pc:~/rk3576-linux-sdk$ ./build.sh lunch
根据当前 SDK 选择对应的 Neardi Pi 3 配置,然后执行:
neardi@ubuntu2204-pc:~/rk3576-linux-sdk$ ./build.sh linux-headers
脚本会准备内核源码,并把头文件安装包放到:
output/linux-headers/
可以用下面的命令查看生成结果:
neardi@ubuntu2204-pc:~/rk3576-linux-sdk$ find output/linux-headers -maxdepth 1 -name "*.deb" -print
SDK 可能会同时生成 amd64、armhf 和 arm64 三种安装包。Neardi Pi 3 是 AArch64 系统,板子上要安装文件名以 _arm64.deb 结尾的包:
实际生成的主要文件如下:
linux-headers-6.1-arm64_amd64.deb
linux-headers-6.1-arm64_arm64.deb
linux-headers-6.1-arm64_armhf.deb
linux-headers-aarch64.tar.gz
linux-headers-amd64.tar.gz
linux-headers-armhf.tar.gz
Neardi Pi 3 使用的是:
linux-headers-6.1-arm64_arm64.deb
其他架构的安装包、.tar.gz 文件以及 linux-kbuild-* 软链接都不用复制到板子。
neardi@ubuntu2204-pc:~/rk3576-linux-sdk$ scp \
output/linux-headers/linux-headers-6.1-arm64_arm64.deb \
neardi@<板子IP>:~/
在 Neardi Pi 3 上安装
先安装基本编译工具,再安装刚生成的头文件包:
neardi@RK3576:~$ sudo apt update
neardi@RK3576:~$ sudo apt install -y build-essential
neardi@RK3576:~$ sudo apt install ./linux-headers-6.1-arm64_arm64.deb
不同版本 SDK 生成的文件名可能不一样,安装时以实际生成的文件为准。
检查安装结果:
neardi@RK3576:~$ dpkg -l | grep linux-headers
neardi@RK3576:~$ ls -ld /usr/src/linux-headers-*
编译一个测试模块
新建 hello.c:
#include <linux/init.h>
#include <linux/module.h>
static int __init hello_init(void)
{
pr_info("neardi_headers_test: loaded\n");
return 0;
}
static void __exit hello_exit(void)
{
pr_info("neardi_headers_test: unloaded\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Neardi kernel headers test module");
新建 Makefile:
obj-m += hello.o
KDIR ?= /usr/src/linux-headers-6.1-arm64
all:
$(MAKE) -C $(KDIR) M=$(CURDIR) modules
clean:
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
编译并加载模块:
neardi@RK3576:~/headers-test$ make
neardi@RK3576:~/headers-test$ file hello.ko
neardi@RK3576:~/headers-test$ sudo insmod hello.ko
neardi@RK3576:~/headers-test$ dmesg | tail
neardi@RK3576:~/headers-test$ sudo rmmod hello
neardi@RK3576:~/headers-test$ dmesg | tail
正常情况下,内核日志中会看到:
neardi_headers_test: loaded
neardi_headers_test: unloaded
版本不匹配
头文件安装包需要和板子当前固件使用同一套 SDK、内核配置及源码版本。
可以对比正在运行的内核版本和模块信息:
neardi@RK3576:~$ uname -r
neardi@RK3576:~/headers-test$ modinfo hello.ko | grep vermagic
如果 insmod 提示 Invalid module format,通常是头文件或内核配置与当前固件不一致。请使用当前固件对应的 SDK 重新生成头文件并编译模块。
在 PI3 板子上编译源码(备选)
也可以把内核源码复制到 Neardi Pi 3,直接在板子上编译头文件安装包。下面的步骤已使用 Rockchip Linux 6.1 内核源码实测。
板端编译占用的存储空间更多,耗时也比在 SDK 中直接生成安装包长。条件允许时,还是建议优先使用前面的 SDK 编译方式。
安装编译依赖
neardi@RK3576:~$ sudo apt update
neardi@RK3576:~$ sudo apt install -y build-essential libncurses-dev \
bison flex libssl-dev libelf-dev cpio rsync bc fakeroot dpkg-dev
将内核源码复制到板子
从 Linux SDK 中复制匹配的内核源码:
neardi@ubuntu2204-pc:~/rk3576-linux-sdk$ scp -r kernel-6.1 \
neardi@<板子IP>:~/
内核源码需要和板子当前使用的 SDK、固件版本对应。
配置内核
neardi@RK3576:~$ cd kernel-6.1
neardi@RK3576:~/kernel-6.1$ make ARCH=arm64 rockchip_linux_defconfig
如果编译出来的外置模块需要加载到当前固件,内核源码、配置和版本都要与固件保持一致。默认配置可以生成安装包,但对于修��改过内核配置的固件,模块版本信息不一定匹配。
处理 DTC 头文件路径
实测使用的 Rockchip Linux 6.1 源码执行 bindeb-pkg 时,可能会报错:
fatal error: ../../uapi/linux/media-bus-format.h: No such file or directory
创建缺少的目录并复制头文件:
neardi@RK3576:~/kernel-6.1$ mkdir -p \
scripts/dtc/include-prefixes/uapi/linux
neardi@RK3576:~/kernel-6.1$ cp \
include/uapi/linux/media-bus-format.h \
scripts/dtc/include-prefixes/uapi/linux/media-bus-format.h
编译 Debian 安装包
neardi@RK3576:~/kernel-6.1$ make ARCH=arm64 bindeb-pkg -j4
这个命令还会编译内核和设备树,因此需要等待一段时间。如果板子可用内存不多,可以把 -j4 改成 -j2。
生成的安装包位于内核源码的上一级目录:
neardi@RK3576:~/kernel-6.1$ ls ../*.deb
本次实测生成了:
linux-headers-6.1.118_6.1.118-3_arm64.deb
linux-image-6.1.118_6.1.118-3_arm64.deb
linux-image-6.1.118-dbg_6.1.118-3_arm64.deb
linux-libc-dev_6.1.118-3_arm64.deb

安装头文件
如果只是为了编译外置内核模块,只安装 linux-headers 包即可:
neardi@RK3576:~/kernel-6.1$ sudo dpkg -i \
../linux-headers-6.1.118_6.1.118-3_arm64.deb
不要顺手安装 linux-image 和 linux-libc-dev,除非确实需要替换系统中的对应软件包。安装这里生成的 linux-libc-dev,可能会把 Ubuntu 自带版本降级。
检查安装结果:
neardi@RK3576:~$ dpkg -l | grep linux-headers
neardi@RK3576:~$ ls -ld /usr/src/linux-headers-*
安装完成后,可以使用前面的测试模块检查头文件能否正常编译模块,并确认模块的 vermagic 是否与当前运行内核一致。