跳到主要内容

7.2.5 内核头文件

如果你需要在开发板上编译内核模块或类似的代码,你需要安装 Linux 内核头文件。这些头文件包含 Linux 内核的各种常量定义、宏定义、函数接口定义和数据结构定义,是完成内核模块代码编译所必须的依赖代码。

安装​

你可以通过以下命令安装内核头文件。

sudo apt install hobot-kernel-headers

命令运行成功后,内核头文件会被安装到/usr/src目录下

root@ubuntu:~# ls /usr/src/linux-headers-*
arch certs Documentation firmware include ipc kernel Makefile Module.symvers samples security System.map usr
block crypto drivers fs init Kconfig lib mm net scripts sound tools virt

使用示例​

我们用一个简单的 Hello World 内核模块的开发介绍如何使用内核头文件。步骤概要如下:

  • 准备程序代码
  • 编写 Makefile,完成驱动模块的编译
  • (可选)对驱动模块进行签名(仅旧版本需要)
  • 测试加载、卸载模块
  • (可选)配置开机自动加载

编写 Hello World 程序​

打开你熟悉的编辑器(比如 VIM),创建文件 hello.c,输入下面的内容:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("xxx.xxx");
MODULE_DESCRIPTION("Hello World");

static int __init hello_init(void)
{
printk(KERN_ERR "Hello, World!\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_EMERG "Goodbye, World!\n");
}

module_init(hello_init);
module_exit(hello_exit);

模块加载时打印Hello, World!, 模块卸载时打印Goodbye, World!。

编写 Makefile​

打开你熟悉的编辑器(比如 VIM),创建文件 Makefile,输入下面的内容:

ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
PWD=$(shell pwd)
KDIR := /usr/src/linux-headers-$(shell uname -r)

all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.ko *.o *.mod.o *.mod.c *.symvers modul* .*.ko.cmd .*.o.cmd .tmp_versions
endif
  • PWD指定源码路径,即 hello.c 的路径。
  • KDIR指定内核源码路径。
  • KERNELRELEASE是在内核源码的顶层 Makefile 里定义的变量。

保存Makefile后,执行make命令完成模块的编译,生成hello.ko文件。

root@ubuntu:~# make
make -C /usr/src/linux-headers-6.1.83 M=/root modules
make[1]: Entering directory '/usr/src/linux-headers-6.1.83'
CC [M] /root/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /root/hello.mod.o
LD [M] /root/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-6.1.83'

模块签名​

注意
  • RDK X5: 没有启用内核模块签名机制,驱动模块可以直接加载
  • RDK X3: 自系统版本 3.0.1 开始已取消内核模块签名机制,驱动模块可以直接加载
  • RDK X3 旧版本 (3.0.1 之前): 需要使用hobot-sign-file命令对驱动模块进行签名后才能加载

对于当前版本的 RDK X5 和 RDK X3,编译好的驱动模块可以直接加载使用,无需额外的签名步骤。

如果你使用的是 RDK X3 旧版本(3.0.1 之前),需要对模块进行签名:

root@ubuntu:~# hobot-sign-file hello.ko
Sign Kernel Module File Done.

未签名的模块在旧版本系统上加载时会报错:

insmod: ERROR: could not insert module hello.ko: Required key not available

加载模块​

加载 ko:insmod hello.ko

root@ubuntu:~# insmod hello.ko
[ 3104.480703] Hello, World!

卸载 ko:rmmod hello

root@ubuntu:~# rmmod hello
[ 3136.909409] Goodbye, World!

查看 ko 是否加载:lsmod | grep hello

root@ubuntu:~# lsmod | grep hello
hello 16384 0

执行命令dmesg查看内核打印信息如下:

[ 3104.480361] hello: loading out-of-tree module taints kernel.
[ 3104.480703] Hello, World!
[ 3136.909409] Goodbye, World!

配置开机自动加载​

如果想要自定义的驱动模块在开机时自动加载,请按照以下步骤进行配置:

拷贝hello.ko到 /lib/modules/{Kernel Version} 目录,命令如下:

sudo cp -f hello.ko /lib/modules/`uname -r`

执行depmod命令更新模块的依赖关系:

sudo depmod

最后在 /lib/modules-load.d 目录下新建一个conf扩展名的配置文件,例如 hello.conf,在配置文件里添加需要自动加载的模块名(模块名不需要.ko 扩展名),例如需要自动加载hello.ko,就写一行hello,如果有多个模块需要加载,一个配置文件可以添加多个自加载模块,一行一个模块名,可以通过以下命令简便的完成配置文件的新建和配置:

sudo echo hello > /lib/modules-load.d/hello.conf