ubuntu20.04 下载 linux源码和编译简单测试模块
一、编译模块程序,不需要内核源码,只需要linux-header头文件。在/usr/src/目录下。前期淌坑。
$ uname -r
4.13.0-36-generic # 和下面的内核版本不一致,是由于在两个电脑上操作的
$ ls /usr/src/
linux-headers-4.13.0-36 linux-headers-4.13.0-36-generic
网上推荐的在ubuntu下载linux源码的指令是 sudo apt-get install linux-source。
但这个下载的默认是linux-source-5.4.0 - Linux kernel source for version 5.4.0 with Ubuntu patches. 放在了/usr/src/目录下。
查看ubuntu下,内核版本的指令是 uname -r。
uname -r
5.15.0-69-generic
查看 apt 下 linux-source的资源包, 发现还是有5.15.0的。可以现在对应版本的。
:~$ apt-cache search linux-source
linux-source - Linux kernel source with Ubuntu patches
linux-source-5.4.0 - Linux kernel source for version 5.4.0 with Ubuntu patches
linux-gkeop-source-5.4.0 - Linux kernel source for version 5.4.0 with Ubuntu patches
linux-hwe-5.11-source-5.11.0 - Linux kernel source for version 5.11.0 with Ubuntu patches
linux-hwe-5.13-source-5.13.0 - Linux kernel source for version 5.13.0 with Ubuntu patches
linux-hwe-5.15-source-5.15.0 - Linux kernel source for version 5.15.0 with Ubuntu patches
linux-hwe-5.8-source-5.8.0 - Linux kernel source for version 5.8.0 with Ubuntu patches
linux-intel-5.13-source-5.13.0 - Linux kernel source for version 5.13.0 with Ubuntu patches
下载 sudo apt-get install linux-hwe-5.15-source-5.15.0 后,就下面几个文件,肯定不是源码
dpkg -S linux-hwe-5.15-source-5.15.0
linux-hwe-5.15-source-5.15.0: /usr/share/doc/linux-hwe-5.15-source-5.15.0/copyright
linux-hwe-5.15-source-5.15.0: /usr/share/doc/linux-hwe-5.15-source-5.15.0/changelog.Debian.gz
linux-hwe-5.15-source-5.15.0: /usr/share/doc/linux-hwe-5.15-source-5.15.0
下面的大神 https://blog.csdn.net/weixin_62882080/article/details/124260136,说去www.kernel.org 网站去下载,我在Index of /pub/linux/kernel/v5.x/ 中找到了内核版本
然后放在 /usr/src目录下解压。
未解压前,/usr/src/ 目录下 已经有两个 linux-header-5.15.0的目录,一个是带有generic,说明是通用头文件。一个不带,是硬件体系架构不同而分类的头文件,里面其余部分是他们之间互补的信息,通过软连接进行关联。
linux-headers-5.15.0-69-generic linux-hwe-5.15-headers-5.15.0-69
我现在先不解压linux-5.15.69.tar.gz源码了。
发现不需要下载源码,也能编译模块。 只需要头文件即可。
编译模块
仿照下面大神的代码。在自己的电脑上编译了一下。在Ubuntu 18.04环境下编写一个简单的内核模块_ubuntu分文件编写简单的内核通讯实现加减法_江下枫的博客-CSDN博客
linux内核编译过程的最终总结版_魏波.的博客-CSDN博客
ubuntu20.04实操编译linux内核步骤 - 掘金
.c 文件和 Makefile文件如下。
注意:Makefile中 all: 目标后的 make 要单独占一行,同时 !!!!make 前面是 tab 不要填充空格!!!!
testKernel.c
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
static int __init lkp_init(void)
{
printk("<1>Hello, World! from the kernel space...\n");
return 0;
}
static void __exit lkp_cleanup(void)
{
printk("<1>Good Bye, World! leaving kernel space...\n");
}
module_init(lkp_init); // 注册模块
module_exit(lkp_cleanup); // 注销模块
MODULE_LICENSE("GPL"); //告诉内核该模块具有GNU公共许可证
Makefile
# Makefile 4.0
obj-m := testKernel.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
# 当make的目标为all时,-C ( K D I R ) 指明跳转到内核源码目录下读取那里的 M a k e f i l e ; M=(PWD) 表明然后返回到当前目录继续读入、执行当前的Makefile。
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
~/module_test$ make
make -C /usr/src/linux-headers-5.15.0-69-generic M=/home/hello/module_test modules
make[1]: Entering directory '/usr/src/linux-headers-5.15.0-69-generic'
CC [M] /home/hello/module_test/testKernel.o
MODPOST /home/hello/module_test/Module.symvers
CC [M] /home/hello/module_test/testKernel.mod.o
LD [M] /home/hello/module_test/testKernel.ko
BTF [M] /home/hello/module_test/testKernel.ko
Skipping BTF generation for /home/hello/module_test/testKernel.ko due to unavailability of vmlinux
make[1]: Leaving directory '/usr/src/linux-headers-5.15.0-69-generic'
$:~/module_test$ ls
Makefile modules.order Module.symvers testKernel.c testKernel.ko testKernel.mod testKernel.mod.c testKernel.mod.o testKernel.o
/var/log$ cat syslog | grep Hello
Apr 4 10:05:22 hello-pc kernel: [ 7149.186501] <1>Hello, World! from the kernel space...
给模块 增加输入参数
给模块增加如下代码
static char * whom = "world";
static int howmany = 1;
module_param(howmany, int , S_IRUGO|S_IWUSR);
module_param(whom, charp, S_IRUGO|S_IWUSR);
全文如下
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/moduleparam.h>
static char * whom = "world"; // 新增部分
static int howmany = 1;
module_param(howmany, int , S_IRUGO|S_IWUSR);
module_param(whom, charp, S_IRUGO|S_IWUSR); // 新增部分
static int __init lkp_init(void)
{
printk("<1>Hello, World! from the kernel space...\n");
return 0;
}
static void __exit lkp_cleanup(void)
{
int i = 0;
for( i = 0; i < howmany; ++i){ // 新增部分
printk("<1>Good Bye, %s leaving kernel space...\n", whom);
}
}
module_init(lkp_init);// 注册模块
module_exit(lkp_cleanup);// 注销模块
MODULE_LICENSE("GPL"); //告诉内核该模块具有GNU公共许可证
重新 make 编译。查看模块参数的修改。
$ make 编译模块
make -C /usr/src/linux-headers-4.13.0-36-generic M=/home/hello/Desktop/test modules
make[1]: Entering directory '/usr/src/linux-headers-4.13.0-36-generic'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory '/usr/src/linux-headers-4.13.0-36-generic'
$ sudo insmod testKernel.ko 安装模块
$ dmesg 输出模块安装打印消息
[ 2937.264770] <1>Hello, World! from the kernel space...
$ ls /sys/module/testKernel/parameters/ #查看模块内部定义的参数
howmany whom
$ cat /sys/module/testKernel/parameters/
cat: /sys/module/testKernel/parameters/: Is a directory
$ cat /sys/module/testKernel/parameters/howmany #查看模块内部定义的参数
1
$ sudo vim /sys/module/testKernel/parameters/howmany # 程序中 S_IRUGO 可读|S_IWUSR 可写
$ cat /sys/module/testKernel/parameters/howmany
2
$ cat /sys/module/testKernel/parameters/whom
world
$ sudo vim /sys/module/testKernel/parameters/whom
$ cat /sys/module/testKernel/parameters/whom
blue sky
$ sudo rmmod testKernel # 修改参数后,卸载模块,再打印输出,可以看到输出有变化
$ tail /var/log/syslog
Apr 4 21:22:26 kinetic kernel: [ 2937.264770] <1>Hello, World! from the kernel space...
Apr 4 21:24:44 kinetic kernel: [ 3075.783088] <1>Good Bye, blue sky
Apr 4 21:24:44 kinetic kernel: [ 3075.783088] leaving kernel space...
Apr 4 21:24:44 kinetic kernel: [ 3075.783089] <1>Good Bye, blue sky
Apr 4 21:24:44 -kinetic kernel: [ 3075.783089] leaving kernel space...
$ sudo insmod testKernel.ko howmany=2 whom="blue sky" # 装载模块时,输入参数
$ sudo rmmod testKernel
$ tail /var/log/syslog
Apr 4 21:50:07 kinetic kernel: [ 4598.867197] <1>Hello, World! from the kernel space...
Apr 4 21:50:14 kinetic kernel: [ 4605.716341] <1>Good Bye, blue leaving kernel space...
Apr 4 21:50:14 kinetic kernel: [ 4605.716342] <1>Good Bye, blue leaving kernel space...