【引言】构建 Linux 内核

大家好,我
是系统解决方案部门的基础设施专家。
上一篇博文,我尝试使用了较大的字体,但结果过大了,所以我吸取了教训,这次会使用正常字体。
你知道内核是什么吗?
在计算机中,操作系统(OS)充当硬件和软件之间的桥梁。
操作系统并非由单一软件组件构成,而是由多个软件组件组成,其核心组件是内核。
这就是我对内核的全部了解;我只是隐约听说过它。
之后,在我忙于日常工作的同时,我静静地思考着这位神秘的“上校”,却
发现我的工作中处处都有他的踪迹。
“调整内核的交换分区设置以控制交换分区的使用。”
“使用 net.ipv4.tcp_max_syn_backlog 调整连接。”
“如果在编写 fstab 文件时出错,将会发生内核崩溃。”
作为一名业余基础设施工程师,我偶尔会在走廊里遇到这个人,并强烈地想要接近他,不知不觉中,我也开始有了和其他人一样的感觉。
了解内核是不是很酷?
那么,操作系统深处究竟隐藏着什么?那个令我无比渴望的地方究竟是什么?
为了解开这个谜团,我们的研究团队深入探索了操作系统的奥秘。
什么是构建?
顺便说一句,内核是开源的,这太棒了。
你可以查看代码。这真是太好了。
然而,由于它是用 C 语言编写的 (*),因此不能直接使用。
它需要先转换成二进制文件才能使用。
这称为构建或编译。
在构建过程中,您可以添加内核最初未包含的功能,或者相反,删除不必要的功能以减少内存消耗,甚至可以调整和修改源代码本身,以创建“我能想象到的最强大的内核”。
做到最好感觉很棒,不是吗?我相信所有Linux发行版都是秉持着这种理念创建的。当然,发行版是在其他各种情况下诞生的也有一些
(*)最近,采用以“所有权”概念而闻名的编程语言“Rust”作为内核开发的第二语言的趋势日益增长,因此我们未来可能会看到除 C 之外的软件包数量增加。
为了加深我们对内核的理解,让我们尝试构建一个内核。
这就回到了标题所说的:熟能生巧!
准备建造
构建方式有很多种,但这次我们 CentOS 7 上构建
在任何领域,从源代码安装并进行各种操作都是一条艰难的道路,其中也包括管理方面的问题,但它的优势在于可以安装自己偏好的版本,并降低过程中因特定发行版而出现问题的可能性,因此我们这次选择了这种方法。
此外,以下步骤使用 Vagrant 的 Bento Box 创建的虚拟环境中执行
首先,我们来下载内核源代码。
内核可从以下链接(或本网站的镜像站点)获取。
*本文使用长期版本:5.15.58。
Linux 内核档案库
https://www.kernel.org/
# 下载 tar 文件 [root@localhost]# cd /tmp [root@localhost tmp]# curl -O https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.58.tar.xz
# 解压 [root@localhost tmp]# tar xvf linux-5.15.58.tar.xz
解压后的目录包含许多相关文件。
有关其结构的详细信息,请参阅以下 URL:
https://linuxjf.osdn.jp/JFdocs/The-Linux-Kernel-15.html
接下来,我们将向环境中添加必要的元素。
必要的元素有很多,但最常见的如下:
- 编译器“GCC”
- 构建工具“make”
- 用于构建内核相关工具的库所需的头文件
- 其他图书馆
这些程序将使用以下命令安装:
# 安装一套用于源代码构建的工具 [root@localhost ~]# yum groupinstall "Development tools"
运行该命令后,将安装许多工具。
诸如“GCC”之类的重要工具包含在名为“开发工具”的软件包组中,并使用“groupinstall”选项一次性全部安装。
然而,这还不够,所以我们还需要安装一些软件包。
我们刚刚解压缩的目录(以下简称源目录) Documentation/process/changes.rst 列在
# 安装所需软件包 [root@localhost ~]# yum install clang squashfs-tools pcmciautils quota ppp nfs-utils procps-ng kernel-devel udev mcelog python-sphinx openssl-devel dwarves elfutils-libelf-devel ncurses-devel
"ncurses-devel" 用于控制台屏幕控制,之所以包含它,是因为在执行稍后将要执行的 "make menuconfig" 命令时需要它。
让我们更改构建设置
现在工具准备就绪,我们想开始调整内核设置,但有几种方法可以更改它们。
您可以直接编辑“.config”文件来更改,但这很麻烦,所以这次我们将使用一种名为“menuconfig”的设置方法,它允许您通过菜单选择来更改设置。
现在,进入源代码目录并运行必要的命令。
[root@localhost linux-5.15.58]# make menuconfig ~~~ *** 编译器版本过旧。 *** 您的 GCC 版本:4.8.5 *** 最低 GCC 版本:5.1.0
我被训了一顿。对不起。他们说
我的GCC版本太旧了。
我明白了,正在更新当前的 GCC烦人的因为这很困难,软件集合 我们将使用红帽公司提供的系统中的较新版本的 GCC。
# 安装软件包 [root@localhost linux-5.15.58]# yum install scl-utils centos-release-scl # 安装包含 gcc 的工具集 [root@localhost linux-5.15.58]# yum install devtoolset-8 # 配置当前 shell 使用 gcc8 [root@localhost linux-5.15.58]# source scl_source enable devtoolset-8 # 检查版本 [root@localhost linux-5.15.58]# gcc -v
现在看来我终于可以使用 menuconfig 了,让我们试试运行它。
[root@localhost linux-5.15.58]# make menuconfig
来了!
出现了一个类似设置窗口的东西。

正如屏幕顶部所示,这里简要介绍一下操作方法和屏幕说明:
- 选择“选择”以返回,使用 Tab 键在“选择”和“退出”之间切换。
- Y 键启用该功能,N 键禁用该功能,M 键将该功能模块化(仅在必要时调用的状态),空格键在这些状态之间切换。
- 已启用的功能用“<*>”标记,已禁用的功能用“<>”标记,模块化功能用“<M>”标记。
我终于进入了设置界面,想进行一些配置,但竟然有近两万个。这
数字太惊人了。
开源软件真是太棒了。
内容太多了,我暂时先略过。(希望以后能学到更多,并写到我的博客上。不,我一定会写的,我保证!)
相关文档已备好。我的培训才刚刚开始。
现在借口都说完了,选择“退出”离开“make menuconfig”界面。系统会询问
是否保存,保存并退出。你应该会在源代码目录的第一级找到一个名为“.config”的文件。打开这个文件
,你会发现它是内核构建配置文件。
正如我上面提到的,你也可以直接编辑这个文件,而无需使用“menuconfig”或其他工具。
让我们一起建造它
接下来就很简单了。
导航到源代码目录并尝试构建内核。
根据系统配置的不同,这可能需要相当长的时间,因此最好并行运行。
# 检查处理器数量 [root@localhost linux-5.15.58]# nproc
在我的虚拟环境中,结果是“2”。
# 使用 nproc 命令确认的处理器数量作为可选参数,并运行 make 命令以并行构建内核。[root@localhost linux-5.15.58]# make -j2
输入命令后,就会开始某种研磨过程。
这需要相当长的时间,所以我们趁这段时间吃点零食吧。
等了几个小时后,终于结束了。
过程中,我的电脑烫得跟夏天汽车引擎盖一样。我猜
这是在跑CPU基准测试吧?
如果您查看源代码目录,您会发现已创建了各种相关文件,例如“vmlinux”和“modules.builtin”。
至此,构建终于完成。
让我们安装已编译好的内核
既然有机会,我就试试安装一下。
在此之前,我做了一些研究,发现 Linux 源代码目录似乎通常放在“/usr/src/”目录下。(显然,LPIC 考试也会涉及这一点。咦?我才一级啊???)
于是我迅速移动了该目录。
这个目录的位置会因发行版而异,所以研究一下各种方案会很有意思。
# 更改目录 [root@localhost]# mv /tmp/linux-5.15.58 /usr/src/ # 创建符号链接 [root@localhost]# ln -s /usr/src/linux-5.15.58 /usr/src/linux
合规性检查完成!
现在,让我们继续安装内核。
# 安装模块文件 [root@localhost linux]# make modules_install # 首先检查当前内核版本 [root@localhost linux]# uname -r 3.10.0-1160.71.1.el7.x86_64 # 安装内核和初始化磁盘映像 [root@localhost linux]# make install
所以我们先尝试重启一次。
[root@localhost linux]# 重启
所以,当我再次启动 VirtualBox 时,
/sbin/mount.vboxsf:挂载失败,错误信息:没有这样的设备
是啊……
我起不来了……
我不知道为什么被人吼,但我知道肯定是有什么事儿被训了。
这种事现实生活中也会发生,对吧?
内核版本变更似乎导致 VirtualBox 管理的内核版本与实际使用的内核版本不一致,从而导致共享文件夹挂载失败。这是
虚拟环境的常见问题:“由于虚拟环境相关问题,测试无法继续进行。”
看来安装插件就能很好地解决这类问题。
真心感谢那些发明这项技术的先驱者们。
# 安装插件 vagrant plugin install vagrant-vbguest # 运行 vagrant vbguest # 完成后重新加载 vagrant reload
我们通过 SSH 登录查看版本。
[root@localhost ~]# uname -r 3.10.0-1160.71.1.el7.x86_64
嗯?
情况没有改变。
检查操作系统启动时可用的内核版本。
[root@localhost ~]# sudo awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg 0 : CentOS Linux (5.15.58) 7 (Core) 1 : CentOS Linux 7 Rescue f9788dcfa7cdc542bad786c12fab4a3c (3.10.0-1160.71.1.el7.x86_64) 2 : CentOS Linux (3.10.0-1160.71.1.el7.x86_64) 7 (Core) 3 : CentOS Linux (3.10.0-1160.66.1.el7.x86_64) 7 (Core) 4 : CentOS Linux (0-rescue-62851673ae88124499bf281ce5a57918)7(核心)
有
“0 : CentOS Linux (5.15.58) 7 (Core)” ← 就是这样;看来构建版本
没有自动切换。这也是 VirtualBox 的规格吗?(可疑)
现在,让我们使用“grub2-set-default”命令将默认启动列表编号“0”。
[root@localhost ~]# grub2-set-default 0
然后重启电脑,再尝试使用 SSH 连接。
[root@localhost ~]# uname -r 5.15.58
哇哦哦哦哦哦,
这是我这次制作的版本!
那挺好的!
想法
Linux 系统极其复杂。
我学到了很多东西,包括故障排除,因为我之前了解的实在太多了。
如果我要创建自己的 Linux 发行版,我
想我得自己安装内核和软件包,对吧?听起来
工作量很大,但也真的很有意思!
我觉得我的写作方式很随意,但
我很满意,因为我从中学习到了一些关于 Linux 的知识。
非常感谢!
28
