为什么要编译内核
因为驱动运行在内核态,如果我们需要debug驱动的代码的话,就需要下内核断点,而内核断点需要带调试信息的kernel,所以我们需要自己编译内核。
因为在ubuntu 20.04下,自带的kernel开启了内核驱动签名的保护机制,导致我们编译的驱动并不能加载到kernel中,所以需要更改内核的相关配置参数,关闭kernel的驱动签名机制
Step1:下载内核
内核的下载地址:https://www.kernel.org/
最好选择当前系统内核的同大版本的内核,比如20.04的内核是5.15.xx,最好选择5.15下面的内核,大版本不同的内核可能会出现错误
这里选用5.15.63的内核
下载内核后执行:unxz -v linux-5.15.63.tar.xz
在解压完成之后,就可以在目录下看到linux的源代码:
Step2:安装构建内核的依赖
执行如下的语句,安装内核的依赖:sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison
在linux官方文档下也提供了编译linux所需要安装的工具包:https://docs.kernel.org/process/changes.html#changes
Step3:关闭内核驱动签名
执行make menuconfig
可以设置内核的一些配置,我们自己编译的内核重点要关注两个配置:
- 开启内核的调试模式,也就是让kernel带上debug信息
- 关闭内核的驱动签名保护
执行成功后,可以看到如下的界面:
首先开启内核调试,选择kernel hacking -> Compile-time checks and compiler options -> Compile the kernel with debug info,开启这个配置
之后我们需要关闭内核驱动签名,但是这个选项在menuconfig里面没法变更,我们需要在.config文件中手动配置
用vim打开.config文件,并将里面的CONFIG_MODULE_SIG
选项更改为n
Step4:编译kernel
当把所有的kernel配置更改完了以后,就可以执行make命令构建kernel,kernel构建的时间比较长,而且编译过程中可能会遇到一些包缺失的情况,一般都可以通过apt安装对应的包即可解决问题
执行如下命令:make -j8
开始kernel的编译
当编译结束后,需要安装内核驱动到对应的目录,执行make module_install
将内核驱动安装到系统的位置
最后一步执行make install
将安装内核到系统中,并且将内核切换为当前编译的内核,重新启动,执行uname -r
即可看到内核的版本
Step5:验证驱动签名关闭
按照第一篇的内容构建一个hello world的驱动模块,但是按照之前的makefile无法成功构建模块(可能是因为之前是arch系统),使用如下的makefile:
KVERSION = $(shell uname -r)
KERN_DIR = /lib/modules/$(KVERSION)/build
all:
CONFIG_MODULE_SIG=n make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m += helloworld.o
即可成功编译出helloworld.ko
文件,之后执行insmod
和rmmod
均未发现报错,且dmesg成功输出: