[深入理解linux内核]-内核编译机制分析

系列 内容
深入理解linux内核 内核编译机制分析

环境:

平台 内核版本 安卓版本
RK3399 Linux4.4 Android7.1

Linux 内核从源码到安装使用大致可分三个阶段,配置,编译,安装。配置的过程主要由 Kconfig 提供的图形界面完成,也有部分工作由 Kbuild 完成。编译的实现机制主要是Kbuild系统,由make命令完成内核编译。内核的安装也是由Kbuild提供的安装脚本再由 make 命令执行安装。

1、Kconfig

Kconfig 文件用于 Linux 内核的配置。各目录中的 Kconfig 一起构成了一个分布式的内核配置数据库,每个 Kconfig 分别描述了所属目录源文档相关的内核配置菜单,就是我们使用命令 make %config(如 menuconfig)后产生的配置菜单,此菜单包含多层,每个层次都是由各个目录中的 Kconfig 产生的。然后根据用户的需求来选择如何编译内核,再将配置结果存到.config 中,然后执行 Makefile 时就会根据.config 的结果来实现内核的编译。

1.1、Kconfig语法分析

配置文件描述了菜单选项,每行都是以一关键字开头(除了帮助信息)。以下列出主要关键字:

关键字 内容
config config 是构成 Kconfig 的最基本单元,其中定义了配置项的详细信息。
menu/endmenu menu 的作用,可以理解成一个目录,可以把一部分相关配置项包含到一个menu 中,这样有利于配置的分类显示,menu 中也可以嵌套包含 menu
menuconfig menuconfig 有点类似 menu,但区别就在于 menu 后面多了一个 config,这个menu 是可以配置的,前面比 menu 类型多了一个方框,通过空格可以修改这个配置项的选中状态。若选中进入该菜单项时和普通的 menu 是一样的。
if/endif if/endif 搭配使用,说明配置项是位于 ifendif 中。if/endif 中的部分就是MODULES 子目录显示的内容。如果选中了 MODULE,那么 ifendif 中的内容可以显示。如果没有定义,就只能进入一个空目录。
choice/endchoice choice 的作用,定义了一组选择项,从中选择一个。该配置项的类型只能是bool 或者 tristate
comment 定义了在配置过程中显示给用户的注释,其中唯一可选的属性是依赖关系depends on
source source 用来读取指定的配置文件,通过 source 就可以将各目录下的 Kconfig文件层层嵌套进来,类似 C 语言中的 include

2、Kbuild

Kbuild,即 Kernel build,用于编译 Linux 内核文件。Kbuildmakefile 进行了功能上的扩充,使其在编译内核文件时更加高效,简洁。

Linux 内核 2.6 开始,Linux 内核的编译采用 Kbuild 系统,这同过去的编译系统有很大的不同,尤其对于Linux 内核模块的编译。在新的系统下,Linux 编译系统会两次扫描 LinuxMakefile:首先编译系统会读取 Linux 内核顶层的 Makefile,然后根据读到的内容第二次读取KbuildMakefile 来编译 Linux 内核。

内核 Makefile 一共包括五部分:

文件 内容
顶层 Makefile 顶层 Makefile 文件定义两个主要的目标:vmlinux (内核映像)和所有的模块。顶层 Makefile 文件根据内核配置,通过递归编译内核代码树子目录建立这两个文件。
.config 配置完成后生成.config 文件,Kbuild 中的 Makefile 会读取该文件的配置,比如各目录中的 Makefile 会查看某一个项配置的是 y 还是 n
arch/$(ARCH)/Makefile 顶层 Makefile 文件引用了一个名为 arch/$(ARCH)/Makefile 的文件,这个文件提供了与平台相关的一些信息。
scripts/Makefile.* scripts/Makefile.* 包含了所有的定义和规则,与Makefile 文件一起编译出内核映像。
各目录中的Makefile 文件 每一个子目录有一个 Makefile 文件,子目录 Makefile 文件根据上级目录Makefile 文件命令启动编译。这些 Makefile 使用.config 文件配置数据构建各种文件列表,并使用这些文件列表编译内嵌或模块目标文件。

3、Makefile

3.1、顶层Makefile分析

顶层 Makefile 在编译时是入口点,从整体上组织所有的 Makefile文件,并定
义终极目标,在这里还定义了与平台无关的很多核心变量与一些很重要的 make 目标。顶层 Makefile 位于内核源码的根目录,下面我们分析顶层 Makefile 的主要工作。

顶层 Makefile 定义并向环境中输出了许多变量,为各个子目录下的Makefile传递一些信息。有些变量,比如 vmlinux-dirs ,不仅在顶层 Makefile 中定义并且赋初值,而且在 arch/*/Makefile 还作了扩充。

变量 内容
内核版本 版 本 信 息 定 义 了 当 前 内 核 的 版 本 , VERSION=3PATCHLEVEL=5SUBLEVEL=4EXATAVERSION=,它们共同构成内核的发行版本号为 3.5.4
CPU 体系结构 ARCH 定义目标 CPU 的体系结构,比如 ARCH:=arm 等。
源码路径 很多 scripts/Makefile.* 规则被很多不同目录下的 Makefile 所共享,所以要针对不同的路径操作不同的文件,就需要定义当前的相对路径。
递归目录定义 init-y, core-y, libs-y, drivers-y, net-y
编译选项 CPP, CC, AS, LD, ARKBUILD_CFLAGSLDFLAGS_vmlinux 等编译参数。

3.2、平台相关Makefile分析

arch/$(ARCH)/Makefile 定义了所有与平台相关的部分,主要对顶层 Makefile 中定义的一些变量作与平台相关的扩展。 Linux 最大的特点是支持跨平台,这种跨平台,不像是 JAVA那样运行于一个底层虚拟平台上,而是定义很多与平台相关的 Makefile 负责的。

3.3、各目录下Makefile

内核中的 Makefile 文件都是采用 Kbuild 架构,一般情况下,建议我们采用Makefile 作为管理当前目录代码的 makefile 文件名,但是有时候也可以使用Kbuild ,但当两者同时存在于同一个目录下时,Kbuild 将会被优先使用。 分布在各个子目录下的 Makefile ,它们并不符合 GNU Makefile 的语法,为了区别于通常意义上的 Makefile,所以被称为 Kbuild Makefile

发布了251 篇原创文章 · 获赞 93 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_33487044/article/details/104083470