kbuild实现分析
x.yin@hotmail.com
Jun 1, 2009
目目目录
目目目录录录
1 前前前言言言
2 概概概述述述
3 kbuild简简简介介介
3.1
3.2
kconfig .
3.1.1
3.1.2
3.1.3
kbuild .
3.2.1
3.2.2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
kconfig的结构 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
kconfig language . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
kconfig的解析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
kbuild组成 .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
kbuild文件功能说明 . . . . . . . . . . . . . . . . . . . . . . . . . . .
4 kbuid中中中用用用到到到的的的主主主要要要make知知知识识识
4.1 Makefile概述 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Makefile的执行过程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 规则 .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.1 伪目标.PHONY . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.2 多规则目标 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.3 静态模式(Static Pattern rules) . . . . . . . . . . . . . . . . . . . . . .
::规则 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.4
4.4 命令和变量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.1 命令回显 .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.2 命令的执行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.3 定义命令包(Defining Canned Command Sequences) . . . . . . . . . .
4.4.4 变量的替换引用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4.5 目标指定变量和模式指定变量 . . . . . . . . . . . . . . . . . . . . .
call函数 .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5
5 kbuild targets实实实现现现分分分析析析
kbuild targets和命令行概述 . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1
5.2 %config target的实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3 mixed-target的实现 .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.4 编译输出和源代码目录的分离 . . . . . . . . . . . . . . . . . . . . . . . . .
5.5 make和make all .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.6
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
vmlinux所涉及的变量 . . . . . . . . . . . . . . . . . . . . . . . . . .
vmlinux的规则链 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
vmlinux的链接 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.7.1 modules变量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.7.2 modules规则链 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
vmlinux目标实现 .
5.6.1
5.6.2
5.6.3
5.7 modules target实现 .
目录
4
4
5
5
5
6
6
6
6
7
9
9
10
12
12
14
14
15
16
16
17
18
18
19
19
21
21
25
25
26
27
28
28
28
32
33
33
34
1
目录
目录
5.8 EXTMOD target实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.8.1 EXTMOD命令行 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.8.2 EXTMOD编译的前提条件 . . . . . . . . . . . . . . . . . . . . . . .
5.8.3 EXTMOD目标的实现 . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Single target的命令行 . . . . . . . . . . . . . . . . . . . . . . . . . .
Single target的实现 . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.9 Single target实现 .
5.9.1
5.9.2
6 kbuild Makefile的的的实实实现现现分分分析析析
6.1 Built-in object goals - obj-y . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2 模块目标(Loadable modules goal- obj-m) . . . . . . . . . . . . . . . . . . . .
6.2.1 make modules执行过程 . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.2 External module执行过程 . . . . . . . . . . . . . . . . . . . . . . . .
Single object模块编译 . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.3
6.2.4 Composite object模块编译 . . . . . . . . . . . . . . . . . . . . . . .
6.2.5 Makefilemod.post实现分析 . . . . . . . . . . . . . . . . . . . . . . .
6.3 Descending down in directories . . . . . . . . . . . . . . . . . . . . . . . . . .
6.4 Library file goals
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.4.1 一个lib.a的例子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
lib.a的实现分析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.4.2
6.5 Hostprog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
hostprog分类 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.5.1
6.5.2 单个.c编译的hostprog . . . . . . . . . . . . . . . . . . . . . . . . . .
6.5.3 多个.o链接而成的hostprog . . . . . . . . . . . . . . . . . . . . . . .
objs中包含-cxxxobjs . . . . . . . . . . . . . . . . . . . . .
6.5.4
objs中包含share libarary . . . . . . . . . . . . . . . . . . . . . . . . .
6.5.5
hostprog的执行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.5.6
hostprog的Descending down . . . . . . . . . . . . . . . . . . . . . . .
6.5.7
hostprog-y和hostprog-m . . . . . . . . . . . . . . . . . . . . . . . . .
6.5.8
6.6 Makefile.clean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.6.1
clean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.6.2 Makefile.clean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.6.3 mrproper
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.6.4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.6.5 EXTMOD clean . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.7 Architecure Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.7.1 平台相关的变量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.7.2 平台相关的目标 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.7.3 其他辅助变量和目标 . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.8.1 make modules_install . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.8.2 make M=dir modules_install . . . . . . . . . . . . . . . . . . . . . . .
.
distclean .
6.8 modules_install
.
.
35
35
36
36
38
38
38
39
40
43
43
44
44
45
45
46
47
47
48
48
49
49
50
50
52
52
53
53
53
53
54
55
56
56
57
57
58
59
60
60
61
2
目录
61
62
62
63
63
64
64
64
68
68
68
70
73
73
73
77
79
79
79
80
85
86
87
87
87
87
91
91
91
92
目录
6.9
6.8.3 Makefile.modinst . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
kbuild.include . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
echo_cmd和cmd . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.9.1
6.9.2
if_changed* .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
if_changed* .
6.9.3
7 kbuild相相相关关关专专专题题题
7.1 Dependency tracing .
7.2 Moduleversion .
7.3
7.4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.1
kbuild dependency tracing . . . . . . . . . . . . . . . . . . . . . . . .
7.1.2 普通的dependency tracing . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2.1 编译单个.o中的Moduleversion . . . . . . . . . . . . . . . . . . . . .
7.2.2 编译模块.ko中的Moduleversion . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
kallsyms .
kallsyms简介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3.1
7.3.2
scripts/kallsym . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
kernel image和kallsyms的链接 . . . . . . . . . . . . . . . . . . . . .
7.3.3
kallsyms应用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3.4
i386 bzImage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
bzImage概述 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.4.1
arch/i386/boot/setup.bin . . . . . . . . . . . . . . . . . . . . . . . . .
7.4.2
7.4.3
arch/i386/boot/vmlinux.bin . . . . . . . . . . . . . . . . . . . . . . . .
bzImage的链接 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.4.4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.5.1 Relocatable kernel简介 . . . . . . . . . . . . . . . . . . . . . . . . . .
7.5.2 相关配置选项 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.5.3 实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
7.5 Relocatable kernel
8 kbuild总总总结结结
8.1
8.2
kbuild中的设计思想 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
kbuild同2.4相比的改进 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9 后后后记记记
3
2 概述
1 前前前言言言
人们在很多电影和小说中常常会见到这样的角色:一个受人轻视的落魄小人物,起
初别人只是丢给他几个琐碎的任务, 不经意间,他却成了掌控整个局势的显赫人物。最
著名的莫过于圣经里的约瑟( joseph ), 就连名噪一时的“肖申克的救赎”( The Shawshank
Redemption )中的男主角 Andy Dufresne 身上都闪耀着 joseph 的影子(当然还有摩西)。
make 在一个复杂项目中扮演的角色,也大体类似,从简单琐碎被人忽视开始,到控制
项目中的每个细节结束。 kbuild 之于 kernel 也正是如此。
当 kbuild 本身也成为一个复杂的系统 (big monster) 时,分析和了解 kbuild 也就有了
更多的现实意义。不同的用户对 kbuild 的需求不同, 相应地对 kbuild 需要了解的程度也
就不同。
• 对于普通用户(编个 kernel image 之类)而言,kbuild只是意味着一些 targets(make
menuconfig; make) , make help 足以帮助他们搞定一切,他们不需要了解除此之外
的任何东西,就像吃个鸡蛋并不需要了解蛋是如何长出来的。
• 对于普通的开发者( kernel feature, driver )或者平台 porting 的开发者而言, kbuild 也
只是意味着一些实现友好的接口,他们需要对某些实现细节(如何使用 obj-y,obj-
m )略知一二,但是并不需要关心为什么这么做( why ),只需要知道怎么去做( how
to do it )。Documentaton/kbuild/文档可以满足以上绝大部分人的需求。
• 然而,对于那些好奇心特别重,想知道 Linux 世界为什么如此奇妙的人来说,或
者对于那些真正需要自己设计 building system 想从 kbuild 借鉴点什么的人来说,
基本上没有比 RTFSC(Read The Fucking Source Code) 更好的选择。
关于 user 和 kbuild 的关系,详见[4, makefile.txt, Section2 ,who does what ]
2 概概概述述述
本文主要侧重于 kbuild 的实现分析,希望能从一个 building system 设计者的角度来
更好地了解 kbuild 的实现和背后的设计思想。本文的主要内容大致可分为5大部分:
• Part1 . chapter1, kbuild 的架构和各个部分的简介。
• Part2 . chapter2, kbuild 常用到的 makefile 基础知识,了解这部分有助于我们对
kbuild 具体实现的分析, 事实上完整通读并理解了 make info page 的人完全可以忽
略这一部分。
• Part3 . kbuild 主要功能的分析。我们知道,一份代码运行的时候更多得是以立体
的方式表现出来的, 而平面的逐行的注释很难清楚地解释其全部功能,因此,我们
采用得是从功能的角度来解释其实现,这一部分分为两章:
– Chapter3 . 主要分析 kbuild 提供的各类 targets 实现,基本上不涉及 kbuild 规
则的实现
– chapter4 . 将以源代码树下的具体 Makefile 为分析对象,详细分析 kbuild 的
各种规则文件.
• Part4 .
chapter5, kbuild 专题。单纯讲述 kbuild 而不涉及到一些专题是不可能
的,如依赖关系生成,模块版本支持( CONFIG_MODULEVERSION ), kallsyms,
bzImage, relocatable kernel 等,这些都和 kbuild 紧密联系在一起. 这些主题同时也
会涉及到一些工具程序: fixdep, modpost, kallsyms, relocs 等。
• Part5 . chapter6 , 一些 kbuild 设计思想的总结以及自2.4系列以来的改进。
本文所分析的 kbuild kernel 版本为 2.6.23.1 , GNU make 版本为 3.81 .
4
3 KBUILD简介
Part1
3 kbuild简简简介介介
我们知道,对于一个复杂的大型项目来说,build的过程大致可分为三个阶段:
图 1: The steps of a typical build process
• 配置阶段。即首先必须确定要编译的平台,目标( targets )和各种 feature 。
• 编译阶段。系统根据提供的编译工具( build tools ),建立依赖关系图( dependency
graphy ),确定正确的目标执行顺序, 然后执行需要更新的命令, 最后构建相应的目
标。
• Deploy 阶段。对于kernel而言有可能涉及到模块及头文件的安装。而对于很多嵌
入式系统而言,则涉及到 rootfs 或整个 flash image 的构建。
同样, kernel building system 也有相同的三个阶段。
图 2: 编译kernel的典型步骤
kconfig 对应的就是 configuration 阶段,当 .config 生成后, kbuild 会依据 .config
编译指定的目标,最后需要安装模块或头文件,或 kernel image 时,可以通过 make
[modinstd | headerinst |install] 实现。
3.1 kconfig
3.1.1 kconfig的的的结结结构构构
每个平台下都有一个 Kconfig, Kconfig 又通过 source 构建出一个 Kconfig 树。当
make %config 时, scripts/kconfig 中的工具程序 conf/mconf/qconf 负责对 Kconfig 的解
析。
arch/i386/Kconfig
5
3.2 kbuild
3 KBUILD简介
mainmenu "Linux Kernel Configuration"
config X86_32
bool
default y
help
This is Linux's home port. Linux was originally native to the Intel
386, and runs on all the later x86 processors including the Intel
486, 586, Pentiums, and various instruction-set-compatible chips by
AMD, Cyrix, and others.
... ...
source "init/Kconfig"
menu "Processor type and features"
source "kernel/time/Kconfig"
... ...
config KTIME_SCALAR
bool
default y
Kconfig文件说明:
scripts/kconfig/*
kconfig
arch/$(ARCH)/defconfig
kconfig解析程序
各个内核源代码目录中配置文件
arch缺省配置文件
3.1.2 kconfig language
参见kernel文档:Documentation/kbuild/kconfig-language.txt
3.1.3 kconfig的的的解解解析析析
conf/mconf/gconf/qconf ,引入了 gperf, flex, bison 等对 kconfig 进行词法和语法分
析,替代了 2.4 中的 shell, perl 脚本程序。这些分析程序与 kbuild 主题关系不大,也就
不必赘述。
3.2 kbuild
3.2.1 kbuild组组组成成成
kbuid的Makefile主要有5个部分:
• 顶层Makefile:负责对各类target的分类并调用相应的规则Makefile来生成目标
• 包含用户配置选项的.config
• 具体平台相关的Makefile:arch/$(ARCH)/Makefile
• 各类规则文件:scripts/Makefile.*
6
3.2 kbuild
3 KBUILD简介
• kernel目录树下的具体Makefile:Makefiles
顶层 Makefile 和 Makefile.build, Makefile.modpos, Makefile.clean 等都是相互独立的,
每个 Makefile 都包含很多文件,图3是 Makefile 的结构图,而图4则是使用频率最高的也
是最典型的规则 Makefile.build 结构图。
图 3: Makefile结构
图 4: scripts/Makefile.build结构
3.2.2 kbuild文文文件件件功功功能能能说说说明明明
文件说明
• 顶层Makefile:
Description
Name
Makefile 顶层Makefile,主要提供各类targets的接口,一般并不涉及实现
kbuild
顶层kbuild,生成asm-offset.h并检查缺失的系统调用
• 平台相关Makefile:
Name
arch/$(ARCH)/Makefile 具体架构的Makefile
Description
7