参考资料:
编译驱动模块
直接使用【3】中的代码和 Makefile 配置,选择的方式是最后一条只编译 hello
这一个驱动模块
#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);
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_PATH) M=$(PWD) clean
endif
其中Makefile的代码在
clean
中变量有问题,根据上下文应该使用KERNELDIR
替换第9行的KERNEL_PATH
不然在执行
make clean
会报错,错误内容类似下面所给的:make -C M=/home/larcvz/projects/c++/drivers/hello clean make[1]: *** M=/home/larcvz/projects/c++/drivers/hello: No such file or directory. Stop. make: *** [Makefile:9: clean] Error 2
编译完成后加载驱动进行验证
加载驱动:
sudo insmod ./hello.ko
此时终端窗口是没有任何输出的,需要输入指令 dmesg | tail
,可以看到 hello_init
函数的输出内容:
卸载驱动:
sudo rmmod hello
再次输入 dmesg | tail
,可以看到 hello_exit
函数的输出内容:
提高内核代码阅读体验
本来打算使用 clangd 进行的但是总是出现各种报错,出错的原因在【2】中的内容中有提到,大致就是使用了 gcc 进行编译内核导致的,除非使用 clang 进行编译或是交叉编译。具体解决方法参照文中提到的 vscode extensions - Can not use clangd to read linux kernel code - Stack Overflow
【2】中的位置在:
clangd 无法理解 gcc 的参数,导致内核项目头上总是存在大量报错
这一段中找到
关于lsp需要的compile_command.json
,可以使用【1】中文章提到的bear
也可以使用后面评论提到的linux/scripts/clang-tools/gen_compile_commands.py
内核自带一个生成compile_command.json
的脚本,编译完执行自动生成
我自己最后选择了ccls。两个生产的compile_command.json
也有一些差别,我自己使用下来暂时遇到只有有些头文件使用脚本生成的并不能被识别依然会报错,比如compiler.h
的文件,脚本生成的里面是compiler-version.h
的没有这个导致跳转后还是报错了。用 bear
生成的就没有这个问题。
标签:clangd,clean,编译,内核,模块,驱动,wsl2,hello From: https://www.cnblogs.com/Larcvz/p/18186105由于内核比较大,无论是ccls还是clangd在生成索引时都会需要一定时间。