zeerd's blog         Search     Categories     Tags     Feed

闲来生雅趣,无事乐逍遥。对窗相望雪,一盏茶香飘。

在 Ubuntu 下独立编译内核模块

#Kernel @Program


Contents:

参考了 《 Linux驱动实践:带你一步一步编译内核驱动程序 》 和 《 Makefile独立编译ko文件 》 两篇文章。

hello.c也是直接抄的,懒得重写了。

首先建立一个新的目录。

在其中添加一个叫做hello.c 的文件。内容如下:

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

// 当驱动被加载的时候,执行此函数
static int __init hello_init(void)
{
    printk(KERN_ALERT "welcome, hello\n");
    return 0;
}

// 当驱动被卸载的时候,执行此函数
static void __exit hello_exit(void)
{
    printk(KERN_ALERT "bye, hello\n");
}

// 版权声明
MODULE_LICENSE("GPL");

// 以下两个函数属于 Linux 的驱动框架,只要把驱动两个函数地址注册进去即可。
module_init(hello_init);
module_exit(hello_exit);

然后创建Makefile文件,内容如下:

BUILD_KERNEL=$(shell uname -r)
KSRC := /lib/modules/$(BUILD_KERNEL)/build

obj-m += hello.o

default:
	$(MAKE) -C $(KSRC) M=$(shell pwd) modules

clean:
	$(MAKE) -C $(KSRC) M=$(shell pwd) clean

之后敲make就可以了。

然后就是执行sudo insmod hello.kosudo rmmod hello并观察dmesg的输出。

这里需要注意的是,如果你是直接使用apt命令安装的linux-headers-x.x.x-x-generic, 那么原则上是一定会好用的。

如果不好用,请优先考虑执行一遍sudo apt upgrade,看看是否当前版本的代码有问题或者干脆安装时出现了遗漏。

我就是发现本地/lib/modules/下的最新的代码是82版本的,但是kernel79版本。于是,我遇到了如下问题:

执行sudo insmod hello.ko之后,提示insmod: ERROR: could not insert module ./mymod.ko: Invalid module format

执行dmesg可以看到[ 5180.365546] module: x86/modules: Skipping invalid relocation target, existing value is nonzero for type 1, loc 00000000df2a29e3, val ffffffffc14970b6

sudo apt upgrade之后,问题消失。

以上,在5.15.0-82-generic #91~20.04.1-Ubuntu验证成功。