目录
三、Linux内核的编译及内核版本切换(Linux5.15.0--->Linux4.4.0)
一、预备知识
1.1 Linux系统简介
我们日常使用的Windows系统是通过设备管理器来管理硬件的,而在Linux系统中遵循“一切皆文件”的原则。Linux所有的内容都是以文件形式保存并管理,我们对Linux中各种操作本质上都是对文件的操作。本小结将简单介绍Linux下各文件夹的相关功能。
Linux的文件系统通常采用层级式的树状目录结构。最上层称为根目录"/",然后在改目录下创建其他目录。我们进入根目录执行查看命令 "ls" 可看到如下内容:
1.2 Linux系统下各文件夹的作用
根目录下的每个文件各司其职,其功能作用也各不相同,这里简单介绍一下常用的核心文件的大致功能如下图所示:
二、pktgen模块的编译
在前文 [pktgen最基本的使用] 中,我们在使用pktgen时是通过直接使用“modprobe pktgen”加载pktgen内核模块的。这里存在的疑问主要有两点:
(1)为什么在先前文章 [Linux驱动编程] 中都是采用insmod命令加载内核模块,这里却采用 modprobe命令加载内核模块,两种加载方式是否有区别?
(2)为什么在先前文章 [Linux驱动编程] 中都是先对源代码进行编译,再加载模块,但是我们在使用pktgen时可以直接进行加载,而没有对源代码进行编译,它源代码存放在哪里以及它是如何编译生成ko文件的?
本小结将对上述两个问题进行解答。
2.1 insmod和modprobe的区别
首先,insmod和modprobe都用于实现模块的加载。两者的区别主要在于以下几方面:
2.1.1 模块依赖问题
modprobe可以解决模块间的依赖关系,insmod无法解决模块的依赖关系。现有两个模块A.ko和B.ko,其中A.ko依赖于B.ko,若想要加载A.ko,insmod和modprobe使用方法分别如下:
(1)若使用insmod命令,则必须使用 "insmod B.ko"先加载B模块,再使用 "insmod A.ko"加载模块。
(2)若使用modprobe命令,则先执行“depmod”命令,在/lib/modules/($uname -r)/目录下生成modules.dep等文件,表明模块A与模块B的依赖关系。然后直接使用“modprobe A”加载A模块,不需要再加载模块B。
2.1.2 加载路径区别
(1)modprobe默认去/lib/modules/$(uname -r)/中查找模块,即只能加载特定目录下的模块(需要将编译后的模块移动至/lib/modules/$(uname -r)/);
(2)insmod可以在任何目录下执行,即模块可以在任一目录下都能加载;
2.1.3 重复加载问题
对于一个模块,若已经加载过了,使用modprbe再次加载不会出现错误提示,而使用insmod再次加载会报错。具体场景如下图所示。
2.2 pktgen的源代码以及pktgen.ko的生成
2.2.1 pktgen.ko的存放路径
ubuntu系统安装时,会对系统中本身自带的一些模块进行编译,并且不会保留相关的内核源代码,我们可以在/lib/modules/$(uname -r)/kernel/net/core/目录下找到linux自带的pktgen.ko文件(系统默认存放位置),如下图所示。
由于Linux系统事先将内核模块文件保存在了 "lib/modules/$ (uname -r)" 路径下,这也是我们可以直接使用 "modprobe pktgen" 直接加载pktgen模块的原因。
2.2.2 pktgen等内核源码的获取
一般情况下,Linux内核源码一般存放在/usr/src目录下。但对于Ubuntu系统来说,默认安装的Ubuntu没有将源文件保留,因为对于大多数用户,不需要源代码包。因此,实际情况下,该目录下一般只包含“linux-headers”等内核头文件:
因此,如果我们想要修改或阅读linux内核源代码,需要自行下载Linux内核模块的源代码,主要有两个渠道:
方法一:利用指令 “sudo apt install linux-source”直接下载当前版本的内核源代码,该源代码会自动下载到/usr/src/目录下,如果需要编译的话可以对该源代码进行编译,无法切换内核版本。
方法二:从www.kernel.org上下载指定版本的内核源代码,该方法可以选择自己想要的指定内核版本,可以用于Linux内核版本切换。
三、Linux内核的编译及内核版本切换(Linux5.15.0--->Linux4.4.0)
本章在2.2.2小节的基础上,展示如何对Linux内核源码进行下载、编译以及如何切换linux的内核版本。
3.1 linux内核源码的编译
step1: 解压内核源码
我们初始默认的linux内核版本为 5.15.0-67,如下图所示:
我们从www.kernel.org选取 4.4.0 版本进行下载(Index of /pub/linux/kernel/v4.x/)并解压至/usr/src/目录,如下图所示:
此时,我们进入目录下查看 "/usr/src/net/core" 目录,发现pktgen等模块的源代码都已经可以找寻到了,如下图所示。
step2: 安装基本的工具软件
对内核进行编译,一些工具软件必不可缺,需要依次执行如下命令:
sudo apt-get install libncurses5-dev libssl-dev
sudo apt-get install build-essential openssl
sudo apt-get install zlibc minizip
sudo apt-get install libidn11-dev libidn11
step3: 配置内核
接下来可利用界面工具对内核进行简单配置,执行如下命令:
sudo make mrproper
sudo make clean
sudo make menuconfig
/*
mrproper为清除编译过程中产生的所有中间文件;
clean为清除上一次产生的编译中间文件;
menuconfig会出现选择的图形化界面;
*/
step4: 编译内核
sudo make
step5: 安装内核以及内核模块
sudo make modules_install //安装内核模块
sudo make install //安装内核
最后,安装成功界面如下图所示:
此时,再次查看 "/usr/src/net/core" 目录,发现pktgen等模块的源代码以及编译好的模块都已经可以找寻到了,如下图所示。
3.2 Linux内核版本切换
(1)重新启动虚拟机(在重启开机界面按住shift键不放手,选择高级选项)
(2)进入内核选择加载界面,选择自己编译的内核(Linux 4.4.0)
(3)利用"uname -r"查看启动后系统的内核版本
四、小结
本篇文章首先对Linux下的文件目录各功能进行介绍,其次对insmod和modprobe两个命令进行了对比,然后分析了Linux内核源码(如pktgen等模块源码)的下载与编译,最后讲解了如何进行Linux内核的切换。
【注】pktgen源码及Makefile下载:
若在/lib/modules/$(uname -r)目录下无法找到pktgen.ko,或想要尽快开发pktgen模块,可直接下载pktgen的源代码(pktgen.c源码github链接)。