飞腾派
直播中

jf_39110170

1年用户 343经验值
擅长:可编程逻辑 嵌入式技术 EDA/IC设计
私信 关注
[经验]

【飞腾派4G版免费试用】2.手把手实战编译Linux内核

亲爱的工程师、学生和爱好者们,我来啦!非常感谢上一篇文章【飞腾派4G版免费试用】1.实战交叉编译环境搭建和手把手uboot编译下方的评论区网友:Jonny的赞赏和表扬,特此为热心网友再创作一篇,作为感谢!

继续分享一些我的心得体会。谢谢!在这个世界上,有一种痛叫做“编译Linux内核”。曾经,我试图通过编译自己的内核版本,以便更好地理解和优化我的系统。然而,我很快就发现,这就像试图用一盒乐高积木来建造一座城堡——看起来可能很容易,但实际上需要大量的耐心和精确的计划。

首先,让我们来了解一下这个神秘的文件系统。看起来就像是一个迷宫,有各种各样的文件和目录,感觉就像是在一个大型的魔法森林中迷路了。不过别担心,我们只需要关注几个关键的文件和目录,比如“set_env.sh”和“build_kernel.sh”。这两个就像是魔法森林中的指南针,帮助我们找到正确的路径。
image.png

“set_env.sh”这个文件就像是魔法森林中的环境设置魔法。它能够改变我们周围的魔法环境,让我们能够使用正确的魔法工具。这里面有一段代码是这样的:“export PATH=...”,这就像是告诉魔法森林,我们要使用的那些魔法工具在哪里。所以,大家记得要根据自己的实际情况调整这个路径哦,不然你的魔法可能就不灵了。

接下来是“build_kernel.sh”,这个就像是魔法森林中的魔法咒语。只要你念出这个咒语,森林就会按照你的指示做出反应,然后你就会看到一颗闪闪发光的内核树出现在你面前。这个内核树就是你的魔法成果,它包含了你的内核镜像和设备树。
image.png

那么,这个内核镜像和设备树是什么呢?它们就像是魔法森林中的魔法水晶球和魔法地图。内核镜像可以让你看到魔法森林的全貌,而设备树则可以告诉你魔法森林的布局和规则。所以,这两个东西都是非常重要的。
image.png

最后,让我们来看看这个编译结果。你看,内核镜像和设备树都出现了,这就是你的魔法成果。你可以把它们带回家,然后向你的朋友们炫耀你的魔法技巧。当然了,如果你的朋友也是程序员的话,他们可能会对你的魔法表示出一些好奇和疑惑,毕竟这个魔法看起来有点儿像是在敲代码、编译代码的过程。

好的,如果还是很“懵”,我会为您详细解释上述内容。

(1)内核源码目录内容

这个目录包含Linux内核的源代码。以下是各个部分的简要说明:

  • arch: 这是与架构相关的代码,例如ARM、x86、RISC-V等。
  • CREDITS: 包含了贡献者的名单和感谢信息。
  • include: 包含了许多头文件,这些文件为内核和内核模块提供公共接口。
  • lib: 包含了一些库文件,这些库文件为内核提供一些常用的功能。
  • modules.builtin: 内置模块的列表。
  • samples: 提供了一些内核样例。
  • tools: 一些用于开发或测试的工具。
  • 其他目录和文件都有它们特定的功能。

image.png

set_env.sh

这是一个环境配置脚本,其主要作用是为编译过程设置环境变量。

  • export PATH: 这行代码将新的路径添加到系统的PATH环境变量中,这样系统就可以找到交叉编译工具链的二进制文件。
  • export CROSS_COMPILE: 这是交叉编译的标志,它告诉编译器使用哪个工具链进行编译。
  • export ARCH: 指定目标架构,这里是ARM64。
    image.png

(2)使用方法

要配置环境,用户只需在终端中运行source set_env.sh。这会立即将环境变量导入当前终端会话中。

然后,用户可以运行./build_kernel.sh来开始编译过程。这个脚本会按照预定的步骤编译内核。
image.png

(3)编译结果

  • 内核镜像: 编译后的内核二进制文件位于./arch/arm64/boot/Image。这是内核的主要部分,会被加载到内存中运行。
  • 设备树: 设备树是描述硬件配置的数据结构,它告诉内核如何配置硬件。编译后的设备树位于./arch/arm64/boot/dts/phytium/phytium-pi-board.dtb
  • 模块: 内核模块是扩展内核功能的代码片段。编译后的模块位于./modules/lib/modules/目录下,并以版本号作为后缀,例如4.19.246-phytium-embeded+

希望这可以帮助您更好地理解Linux内核的编译过程!

现在开始手把手实战:
首先,让我们想象一下,你的电脑是一个大厨师,而你要为它做一顿美味的“内核大餐”。

  1. 准备食材

image.png
首先,你需要一些“食材”。在内核编译中,这些“食材”就是源码。你看到的那些文件和目录,就是你要用来做内核的“食材清单”。其中有一些是普通的“食材”(比如arch, block, crypto等),还有一些是特殊的“秘方”(比如Kconfig, Makefile等)。
2. 环境配置

然后,你需要配置“厨房环境”。这就像是为大厨师准备工具一样。set_env.sh这个脚本就是来做这个事情的。它告诉“大厨师”要用哪个“菜刀”(交叉编译工具链),以及要烹饪哪种“料理”(ARM64架构、RISC-V架构或X86架构)。所以,这里面新增的PATH就是“大厨师”的“菜刀”的存放位置。

运行set_env.sh后,你就为“大厨师”设置好了烹饪环境。
image.png

  1. 开始烹饪

接下来,你可以开始让“大厨师”做菜了。这里的./build_kernel.sh就是“大厨师”的“烹饪指南”。它会告诉“大厨师”先做什么,再做什么,最后做什么。
4. 品尝成果

最后,“大厨师”会为你做出一道美味的“内核大餐”。这里的“内核镜像”就像是烹饪出来的主菜,而“设备树”就像是附带的配菜。至于那些module,那就是各种调料了。

总的来说,编译内核就像是为你的电脑定制一道美味的料理。虽然过程有点复杂,但只要你按照步骤来,就能做出一道完美的“内核大餐”了!
image.png

接下来我会为亲爱的工程师、学生和爱好者们详细解释每一部分。

#(1)内核源码目录内容
zero@pc:~/work/phytium-linux-kernel-master-Uboot-V1.0.0$ ls

这行命令是在一个Linux终端中执行的,用于列出phytium-linux-kernel-master-Uboot-V1.0.0目录下的内容。这个目录应该包含Linux内核的源代码。

#(2)使⽤⽅法
zero@pc:~/work/phytium-linux-kernel-master-Uboot-V1.0.0$ source set_env.sh

这行命令用于运行set_env.sh脚本,该脚本用于配置编译环境。source命令会在当前终端会话中执行脚本,这样环境变量就会立即生效。
image.png

zero@pc:~/work0/phytium-linux-kernel-master-Uboot-V1.0.0$ ./build_kernel.sh

这行命令用于运行build_kernel.sh脚本,该脚本用于编译内核。

#(3)编译结果
zero@pc:~/work/phytium-linux-kernel-master-Uboot-V1.0.0$ ls
./arch/arm64/boot/Image

这行命令用于列出目录内容,显示了编译后的内核镜像的位置。

zero@pc:~/work/phytium-linux-kernel-master-Uboot-V1.0.0$ ls
./arch/arm64/boot/dts/phytium/phytium-pi-board.dtb

这行命令再次用于列出目录内容,显示了编译后的设备树的位置。设备树是描述硬件配置的数据结构,它告诉内核如何配置硬件。

zero@pc:~/work/phytium-linux-kernel-master-Uboot-V1.0.0$ ls
./modules/lib/modules/
4.19.246-phytium-embeded+

这行命令列出了module模块的位置。
image.png

如果还没明白,下面是上述内容展开后的详细解释和注释:

列出内核源码目录下的文件和目录

zero@pc:~/work/phytium-linux-kernel-master-Uboot-V1.0.0$ ls

列出内核源码目录的内容

arch # 存放与架构相关的代码
CREDITS # 内核贡献者的名单和感谢信息
include # 包含公共头文件
lib # 包含一些库文件
modules.builtin # 内置模块的列表
samples # 内核样例
tools # 开发或测试工具
block # 存放块设备驱动的目录
crypto # 存放加密相关驱动的目录
init # 存放内核初始化的相关代码
LICENSES # 内核许可证文件
modules.order # 内核模块加载顺序的文件
scripts # 内核脚本目录
usr # 用户空间的目录
build_kernel.sh # 编译内核的脚本
Documentation # 内核文档目录
ipc # 进程间通信的目录
MAINTAINERS # 内核维护者列表的文件
Module.symvers # 符号版本信息文件
security # 安全相关的驱动目录
virt # 虚拟化相关的驱动目录
built-in.a # 内核编译后的静态库文件
drivers # 设备驱动的目录
Kbuild # 内核构建系统的主要文件
Makefile # 内核的构建规则文件
net # 网络相关的驱动目录
set_env.sh # 编译环境配置脚本
vmlinux # 内核的链接文件
certs # 证书目录,用于签名验证
firmware # 固件目录,存放一些硬件所需的固件
Kconfig # 内核配置菜单的文件
mm #多媒体相关的驱动目录
pack_module.sh # 打包模块的脚本
sound # 声音相关的驱动目录
vmlinux.o # 内核的入口点,链接后的结果文件
COPYING # 内核许可证文本文件
fs # 文件系统相关的驱动目录
kernel # 内核的核心代码目录
modules # 内核模块的代码目录
README # 内核的说明文件
System.map # 内核符号表文件,用于调试和符号解析

set_env.sh` 文件的内容:

# 设置环境变量,为交叉编译配置环境
export PATH=$PATH:"/opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin"  # 将交叉编译工具链的路径添加到PATH中,方便执行相关工具和命令
export CROSS_COMPILE=aarch64-linux-gnuexport ARCH=arm64  # 设置交叉编译的前缀为`aarch64-linux-gnuexport`,并设置目标架构为`arm64`

image.png

编译过程:

  1. 配置环境:通过运行source set_env.sh命令,用户可以导入set_env.sh中定义的环境变量,为交叉编译配置环境。
  2. 开始编译:运行./build_kernel.sh脚本开始编译内核。这个脚本会按照预定的步骤编译内核。
  3. 编译结果
  • 内核镜像:编译后的内核二进制文件位于./arch/arm64/boot/Image。这是内核的主要部分,会被加载到内存中运行。
  • 设备树:设备树是描述硬件配置的数据结构,它告诉内核如何配置硬件。编译后的设备树位于./arch/arm64/boot/dts/phytium/phytium-pi-board.dtb
  • 模块:内核模块是扩展内核功能的代码片段。编译后的模块位于./modules/lib/modules/目录下,并以版本号作为后缀,例如4.19.246-phytium-embeded+

编译完成后,我看到了我的内核镜像、设备树和内核模块。它们就像是城堡的最后成品,是我辛勤努力的成果。我感到无比的满足和自豪。虽然这个过程充满了挑战和困难,但每当我看到我的内核在我的机器上运行时,我就会感到所有的付出都是值得的。
image.png

总的来说,编译Linux内核就像是一场冒险之旅,充满了未知和挑战。但正是这些困难和挑战,让我更加深入地理解了Linux内核的工作原理,也让我更加深入地了解了编程的艺术。虽然我可能不是最好的城堡建造者,但我会继续努力,因为我热爱编程,热爱Linux,热爱这个充满挑战和乐趣的世界。
image.png

希望上面的经验能够帮助到您!
谢谢!

还没吃饭
2023年12月16日

更多回帖

发帖
×
20
完善资料,
赚取积分