您的位置:首页 > 运维架构 > Linux

Linux内核编译流程

2016-08-12 14:51 393 查看


Process of the Linux kernel building(Linux内核编译流程)


Introduction(简介)

I won’t tell you how to build and install a custom Linux kernel on your machine. If you need help with this, you can find many resourcesthat
will help you do it. Instead, we will learn what occurs when you execute
make
in the root directory of the Linux kernel
source code.

在本文中,我不会告诉你如何在你的机器上编译和安装你自定义的Linux内核。如果你需要这么做,你可以找多许多这样的资源来帮助你完成这样的工作。在这里,我们会学到当你在Linux内核代码根目录里面执行
make
命令时会发生什么。

When I started to study the source code of the Linux kernel, the makefile was the first file that I opened. And it was scary
:). The makefilecontained
1591
lines
of code when I wrote this part and the kernel was the 4.2.0-rc3 release.

当我开始学习Linux内核源码的时候, makefile 是我第一个打开的文件,而且它真的很恐怖。当我写这篇文档的时候,Linux内核是4.2.0-rc3版本,而那个 含有
1591
行代码。

This makefile is the top makefile in the Linux kernel source code and the kernel building starts here. Yes, it is big, but moreover, if you’ve read the sourc
4000
e code of the Linux kernel you may have noted that all directories containing source code has its own
makefile. Of course it is not possible to describe how each source file is compiled and linked, so we will only study the standard compilation case. You will not find here building of the kernel’s documentation, cleaning of the kernel source code, tags generation, cross-compilation related
stuff, etc… We will start from the
make
execution with the standard kernel configuration file and will finish with the
building of the bzImage.

这里说的makefile指的是Linux内核源码顶层的makefile,内核编译就是从这个makefile开始的。是的,它很庞大,但是,如果你读过内核源码就会发现每个目录下都有自己的makefile。当然描述每个文件的编译链接过程是不现实的,因此我们仅仅研究一个标准的编译例子。在这篇文档中你不会找到如何生成Linux内核文档,清理内核源码,ctags生成,交叉编译(等这些内容。我们会从以标准配置文件执行
make
命令开始,到生成bzImage结束。

It would be better if you’re already familiar with the make util, but I will try to describe every piece of code in this part anyway.

如果你熟悉make util更好,但我也会尝试详细描述代码的的方方面面。

So let’s start.

那么,让我们开始吧。


Preparation before the kernel compilation(编译前准备)

There are many things to prepare before the kernel compilation can be started. The main point here is to find and configure

the type of compilation, to parse command line arguments that are passed to
make
, etc… So let’s dive into the top
Makefile
of
Linux kernel.

在开始编译前,有很多准备工作要做。这些准备工作主要是寻找和配置编译类型、解析传递给
make
命令的命令行参数等。所以让我们深入研究Linux内核的顶层
Makefile


The top
Makefile
of Linux kernel is responsible for building two major products: vmlinux (the
resident kernel image) and the modules (any module files). The Makefile of the Linux kernel starts with the definition of
following variables:

Linux 内核顶层的Makefile负责编译两类主要的目标:vmlinux和modules。Makefile从定义下面这些变量开始:
<code class="language-Makefile hljs ini has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-setting" style="box-sizing: border-box;">VERSION = <span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span></span></span>
<span class="hljs-setting" style="box-sizing: border-box;">PATCHLEVEL = <span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span></span></span>
<span class="hljs-setting" style="box-sizing: border-box;">SUBLEVEL = <span class="hljs-value" style="box-sizing: border-box;"><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span></span></span>
<span class="hljs-setting" style="box-sizing: border-box;">EXTRAVERSION = <span class="hljs-value" style="box-sizing: border-box;">-rc3</span></span>
<span class="hljs-setting" style="box-sizing: border-box;">NAME = <span class="hljs-value" style="box-sizing: border-box;">Hurr durr I'ma sheep</span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>


These variables determine the current version of Linux kernel and are used in different places, for example in the forming of the
KERNELVERSION
variable
in the same
Makefile
:

这些变量定义了当前Linux内核的版本,它们被用在许多不同的地方,例如组成同一
Makefile
中的变量
KERNELVERSION

<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-constant" style="box-sizing: border-box;">KERNELVERSION</span> = <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">VERSION</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">PATCHLEVEL</span>),.<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">PATCHLEVEL</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">SUBLEVEL</span>),.<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">SUBLEVEL</span>)))<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">EXTRAVERSION</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


After this we can see a couple of
ifeq
conditions that check some of the parameters passed to
make
.
The Linux kernel
makefiles
provides a special
make
help
target that prints all available targets and some of the command line arguments that can be passed to
make
.
For example :
make V=1
=> verbose build. The first
ifeq
checks
whether the
V=n
option is passed to
make
:

在这之后,我们可以看到一些
ifeq
语句对用于检查传递给
make
命令的参数。Linux内核的
makefiles
提供了一个特殊的编译目标
make
help
用语打印出所有可能的编译目标和一些传递给
make
命令的命令行参数。例如,
make
V=1
=> verbose build. 第
1bb8b
一个
ifeq
检查是否
V=n
参数被传递给命令
make

<code class="language-Makefile hljs cmake has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">ifeq (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"$(origin V)"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"command line"</span>)
KBUILD_VERBOSE = $(V)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">endif</span>
ifndef KBUILD_VERBOSE
KBUILD_VERBOSE = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">endif</span>

ifeq ($(KBUILD_VERBOSE),<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)
quiet =
Q =
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
quiet=quiet_
Q = @
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">endif</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">export</span> quiet Q KBUILD_VERBOSE</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>


If this option is passed to
make
, we set the
KBUILD_VERBOSE
variable
to the value of
V
option. Otherwise we set the
KBUILD_VERBOSE
variable
to zero. After this we check the value of
KBUILD_VERBOSE
variable and set values of the
quiet
and
Q
variables
depending on the value of
KBUILD_VERBOSE
variable. The
@
symbols
suppress the output of command. And if it is present before a command the output will be something like this:
CC scripts/mod/empty.o
instead
of
Compiling .... scripts/mod/empty.o
. In the end we just export all of these variables.

如果该参数被传递给
make
,我们设置
KBUILD_VERBOSE
变量的值为参数
V
的值,否则我们设置变量
KBUILD_VERBOSE
的值为0。然后,根据
KBUILD_VERBOSE
的值设置变量
quiet
Q
的值。符号
@
阻止了命令的输出。如果该符号出现在命令的前面,那么该命令的输出将会是这样
CC
scripts/mod/empty.o
而不是
Compiling .... scripts/mod/empty.o
。最后,我们将export出这些变量。

The next
ifeq
statement checks that
O=/dir
option
was passed to the
make
. This option allows to locate all output files in the given
dir
:

接下来的
ifeq
检查是否
O=/dir
选项被传递给
make
命令。
这个选项使得编译所得的文件输出到指定的目录
dir
中:
<code class="language-Makefile hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">ifeq (<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>KBUILD_SRC),)

ifeq (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"$(origin O)"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"command line"</span>)
KBUILD_OUTPUT := <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>O)
endif

ifneq (<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>KBUILD_OUTPUT),)
saved-output := <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>KBUILD_OUTPUT)
KBUILD_OUTPUT := <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>shell mkdir -p <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>KBUILD_OUTPUT) && cd <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>KBUILD_OUTPUT) \
&& /bin/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">pwd</span>)
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>KBUILD_OUTPUT),, \
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">error</span> failed to create output directory <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"$(saved-output)"</span>))

sub-make: FORCE
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>Q)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>MAKE) -C <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>KBUILD_OUTPUT) KBUILD_SRC=<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>CURDIR) \
-f <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>CURDIR)/Makefile <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">filter</span>-out _all sub-make,<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>MAKECMDGOALS))

skip-makefile := <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
endif # ifneq (<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>KBUILD_OUTPUT),)
endif # ifeq (<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>KBUILD_SRC),)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul>


We check the
KBUILD_SRC
that represents the top directory of the kernel source code and whether it is empty (it is empty
when the makefile is executed for the first time). We then set the
KBUILD_OUTPUT
variable to the value passed with the
O
option
(if this option was passed). In the next step we check this
KBUILD_OUTPUT
variable and if it is set, we do following things:

* Store the value of
KBUILD_OUTPUT
in the temporary
saved-output
variable;

* Try to create the given output directory;

* Check that directory created, in other way print error message;

* If the custom output directory was created successfully, execute
make
again with the new directory (see the
-C
option).

我们检查代表Linux内核源码根目录的变量
KBUILD_SRC
的值是否为空(当第一次执行makefile的时候该值为空)。接着我们设置变量
KBUILD_OUTPUT
的值为通过选项
O
传递进来的值。接下来我们判断
KBUILD_OUTPUT
值,如果已设置,我们执行下面的操作:

* 将变量
KBUILD_OUTPUT
的值存储在临时变量
saved-output
中;

* 尝试创建指定的输出目录;

* 判断制定的输出目录是否已创建,否者输出错误信息;

* 如果指定的输出目录已创建,使用新的目录再次执行
make
命令,(参考
-C
选项)

The next
ifeq
statements check that the
C
or
M
options
passed to
make
:

下一个
ifeq
语句检查是否选项
C
或者
M
被传递给命令
make

<code class="language-Makefile hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">ife<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">q ("<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>origin C)</span><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">", "</span>command line<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">")
KBUILD_CHECKSRC = <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>C)
endif
ifndef KBUILD_CHECKSRC
KBUILD_CHECKSRC = 0
endif

ifeq ("</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>origin M)<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">", "</span>command line<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">")
KBUILD_EXTMOD := <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>M)
endif</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>


The
C
option tells the
makefile
that
we need to check all
c
source code with a tool provided by the
$CHECK
environment
variable, by default it is sparse. The second
M
option
provides build for the external modules (will not see this case in this part). We also check whether the
KBUILD_SRC
variable
is set, and if it isn’t, we set the
srctree
variable to
.
:

选项
C
告诉
makefile
我们需要使用环境变量
$CHECK
来检查所有的
c
代码,
默认的工具时 sparse. 第二个
M
选项
提供了对外部模块的编译 (本例中不会涉及到). 我们也会检查变量
KBUILD_SRC
的值是否已设置, 如果没有, 我们设置变量
srctree
为代表当前目录的
.
:
<code class="language-Makefile hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">ife<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">q (<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>KBUILD_SRC)</span>,)
srctree := .
endif

objtree := .
src     := <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>srctree)
obj     := <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>objtree)

export srctree objtree VPATH</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>


That tells
Makefile
that the kernel source tree will be in the current directory where
make
was
executed. We then set
objtree
and other variables to this directory and export them. The next step is to get value for
the
SUBARCH
variable that represents what the underlying architecture is:

这告诉
Makefile
make
命令执行时,内核代码树就在当前目录下。
然后我们设置
objtree
和其它变量的值为这个目录,并export它们。下一步是获取代表目标平台架构的变量
SUBARCH
:
<code class="language-Makefile hljs haml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
-<span class="ruby" style="box-sizing: border-box;">e s/sun4u/sparc64/ \
</span>                  -<span class="ruby" style="box-sizing: border-box;">e s/arm.*<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">/arm/</span> -e s/sa11<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>/arm/ \
</span>                  -<span class="ruby" style="box-sizing: border-box;">e s/s390x/s39<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>/ -e s/parisc64/parisc/ \
</span>                  -<span class="ruby" style="box-sizing: border-box;">e s/ppc.*<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">/powerpc/</span> -e s/mips.*<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">/mips/</span> \
</span>                  -<span class="ruby" style="box-sizing: border-box;">e s/sh[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">234</span>].*<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">/sh/</span> -e s/aarch64.*<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">/arm64/</span> )</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>


As you can see, it executes the uname util that prints information about machine, operating system and architecture. As it gets the output of
uname
,
it parses the ouput and assigns the result to the
SUBARCH
variable. Now that we have
SUBARCH
,
we set the
SRCARCH
variable that provides the directory of the certain architecture and
hfr-arch
that
provides the directory for the header files:

如你所见,通过执行命令
uname
打印出机器、操作系统和架构的信息。获取
uname
命令的输出后,解析其输出,并赋值给变量
SUBARCH
。有了
SUBARCH
之后,我们设置提供对应架构目录的变量
SRCARCH
和提供头文件目录的变量
hfr-arch
:
<code class="language-Makefile hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">ife<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">q (<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>ARCH)</span>,i386)
SRCARCH := x86
endif
ife<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">q (<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>ARCH)</span>,x86_64)
SRCARCH := x86
endif

hdr-arch  := <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>SRCARCH)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>


Note
ARCH
is an alias for
SUBARCH
.
In the next step we set the
KCONFIG_CONFIG
variable that represents path to the kernel configuration file and if it was
not set before, it is set to
.config
by default:

变量
ARCH
是变量
SUBARCH
的别名。在下一步中,我们设置变量
KCONFIG_CONFIG
表示内核配置文件的路径。该变量如果在此之前没有设置,则设置为默认值
.config
:
<code class="language-Makefile hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">KCONFIG_CONFIG  ?= .config
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">export</span> KCONFIG_CONFIG</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


and the shell that will be used during kernel compilation:

并设置在内核编译过程中所用到的 shell:
<code class="language-Makefile hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">CONFIG_SHELL := $(shell <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> [ -x <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"$<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$BASH</span>"</span> ]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">then</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">echo</span> $<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$BASH</span>; \
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> [ -x /bin/bash ]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">then</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">echo</span> /bin/bash; \
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">echo</span> sh; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">fi</span> ; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">fi</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>


The next set of variables are related to the compilers used during Linux kernel compilation. We set the host compilers for the
c
and
c++
and
the flags to be used with them:

下面要设置的变量与Linux内核编译过程中的编译器相关。我们设置
c
c++
源码的主机端(host)编译器和编译flag:
<code class="language-Makefile hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">HOSTCC       <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> gcc
HOSTCXX      <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> g<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">++</span>
HOSTCFLAGS   <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-attribute" style="box-sizing: border-box;">-Wall</span> <span class="hljs-attribute" style="box-sizing: border-box;">-Wmissing</span><span class="hljs-attribute" style="box-sizing: border-box;">-prototypes</span> <span class="hljs-attribute" style="box-sizing: border-box;">-Wstrict</span><span class="hljs-attribute" style="box-sizing: border-box;">-prototypes</span> <span class="hljs-attribute" style="box-sizing: border-box;">-O2</span> <span class="hljs-attribute" style="box-sizing: border-box;">-fomit</span><span class="hljs-attribute" style="box-sizing: border-box;">-frame</span><span class="hljs-attribute" style="box-sizing: border-box;">-pointer</span> <span class="hljs-attribute" style="box-sizing: border-box;">-std</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>gnu89
HOSTCXXFLAGS <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-attribute" style="box-sizing: border-box;">-O2</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>


Next we get to the
CC
variable that represents compiler too, so why do we need the
HOST*
variables?
CC
is
the target compiler that will be used during kernel compilation, but
HOSTCC
will be used during compilation of the set
of the
host
programs (we will see it soon). After this we can see the definition of
KBUILD_MODULES
and
KBUILD_BUILTIN
variables
that are used to determine what to compile (kernel, modules or both):

我们接下来遇到的变量
CC
也和编译器相关,那么我们为啥需要
HOST*
变量呢?
CC
是内核编译过程中的目标编译器,而
HOSTCC
在编译过程中会编译一些主机程序(后面我们会看到它们)。在这之后,我们会看到变量
KBUILD_MODULES
KBUILD_BUILTIN
的定义,这些变量决定了需要编译那些目标,内核、模块还是两则都是。
<code class="language-Makefile hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">KBUILD_MODULES :=
KBUILD_BUILTIN := <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>

ife<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">q (<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>MAKECMDGOALS)</span>,modules)
KBUILD_BUILTIN := <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>CONFIG_MODVERSIONS),<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)
endif</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>


Here we can see definition of these variables and the value of
KBUILD_BUILTIN
variable will depend on the
CONFIG_MODVERSIONS
kernel
configuration parameter if we pass only
modules
to
make
.
The next step is to include the
kbuild
file.

这里我们看到,如果我们仅仅传递
modules
make
命令,这些变量的定义和
KBUILD_BUILTIN
的值依赖于
CONFIG_MODVERSIONS
内核配置参数。下一步是包含那些
kbuild
文件.
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span> scripts/<span class="hljs-constant" style="box-sizing: border-box;">Kbuild</span>.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


The Kbuild or
Kernel
Build System
is the special infrastructure to manage the build of the kernel and its modules. The
kbuild
files has
the same syntax that makefiles do. The scripts/Kbuild.include file provides some generic definitions for the
kbuild
system.
As we included this
kbuild
files we can see definition of the variables that are related to the different tools that will
be used during kernel and modules compilation (like linker, compilers, utils from the binutils, etc…):

Kbuild
或者
Kernel
Build System
是用来控制内核或者模块编译的特殊框架。
kbuild
文件和普通makefile有相同的语法。文件
scripts/Kbuild.include
提供了
kbuild
系统的一些公共定义。我们包含了该文件后,可以看到与内核和模块编译过程中所使用的各种工具相关的各种变量定义(如链接器linker、编译器compiler、
binutils中的各种工具等):
<code class="language-Makefile hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">AS      = $(CROSS_COMPILE)as
LD      = $(CROSS_COMPILE)ld
CC      = $(CROSS_COMPILE)gcc
CPP     = $(CC) -E
AR      = $(CROSS_COMPILE)ar
NM      = $(CROSS_COMPILE)nm
STRIP       = $(CROSS_COMPILE)strip
OBJCOPY     = $(CROSS_COMPILE)objcopy
OBJDUMP     = $(CROSS_COMPILE)objdump
AWK     = awk
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>


We then define two other variables:
USERINCLUDE
and
LINUXINCLUDE
.
They contain the paths of the directories with headersc z (public for users in the first case and for kernel in the second case):

接下来我们定义两个变量
USERINCLUDE
LINUXINCLUDE
。他们包含了头文件目录(第一个是用户公用头文件,第二个是内核使用的头文件)。
<code class="language-Makefile hljs haml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">USERINCLUDE    := \
-<span class="ruby" style="box-sizing: border-box;"><span class="hljs-constant" style="box-sizing: border-box;">I</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>srctree)/arch/<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>hdr-arch)/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span>/uapi \
</span>        -<span class="ruby" style="box-sizing: border-box;"><span class="hljs-constant" style="box-sizing: border-box;">Iarch</span>/<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>hdr-arch)/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span>/generated/uapi \
</span>        -<span class="ruby" style="box-sizing: border-box;"><span class="hljs-constant" style="box-sizing: border-box;">I</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>srctree)/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span>/uapi \
</span>        -<span class="ruby" style="box-sizing: border-box;"><span class="hljs-constant" style="box-sizing: border-box;">Iinclude</span>/generated/uapi \
</span>        -<span class="ruby" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>srctree)/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span>/linux/kconfig.h
</span>
LINUXINCLUDE    := \
-<span class="ruby" style="box-sizing: border-box;"><span class="hljs-constant" style="box-sizing: border-box;">I</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>srctree)/arch/<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>hdr-arch)/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span> \
</span>        ...</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>


And the standard flags for the C compiler:

以及标准的C编译器编译flag:
<code class="language-Makefile hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">KBUILD_CFLAGS   <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">:=</span> <span class="hljs-attribute" style="box-sizing: border-box;">-Wall</span> <span class="hljs-attribute" style="box-sizing: border-box;">-Wundef</span> <span class="hljs-attribute" style="box-sizing: border-box;">-Wstrict</span><span class="hljs-attribute" style="box-sizing: border-box;">-prototypes</span> <span class="hljs-attribute" style="box-sizing: border-box;">-Wno</span><span class="hljs-attribute" style="box-sizing: border-box;">-trigraphs</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>
<span class="hljs-attribute" style="box-sizing: border-box;">-fno</span><span class="hljs-attribute" style="box-sizing: border-box;">-strict</span><span class="hljs-attribute" style="box-sizing: border-box;">-aliasing</span> <span class="hljs-attribute" style="box-sizing: border-box;">-fno</span><span class="hljs-attribute" style="box-sizing: border-box;">-common</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>
<span class="hljs-attribute" style="box-sizing: border-box;">-Werror</span><span class="hljs-attribute" style="box-sizing: border-box;">-implicit</span><span class="hljs-attribute" style="box-sizing: border-box;">-function</span><span class="hljs-attribute" style="box-sizing: border-box;">-declaration</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>
<span class="hljs-attribute" style="box-sizing: border-box;">-Wno</span><span class="hljs-attribute" style="box-sizing: border-box;">-format</span><span class="hljs-attribute" style="box-sizing: border-box;">-security</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>
<span class="hljs-attribute" style="box-sizing: border-box;">-std</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>gnu89</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>


It is the not last compiler flags, they can be updated by the other makefiles (for example kbuilds from
arch/
). After all
of these, all variables will be exported to be available in the other makefiles. The following two the
RCS_FIND_IGNORE
and
the
RCS_TAR_IGNORE
variables will contain files that will be ignored in the version control system:

这还不是最终的编译flags,它们可能在编译过程中被其它的makefiles修改(例如,
arch/
目录下的kbuilds)。在这之后,所有的变量都被导出。接下来的两个变量
RCS_FIND_IGNORE
RCS_TAR_IGNORE
包含了那些会被版本控制系统忽略的文件:
<code class="language-Makefile hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">export RCS_FIND_IGNORE <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">:=</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>( <span class="hljs-attribute" style="box-sizing: border-box;">-name</span> SCCS <span class="hljs-attribute" style="box-sizing: border-box;">-o</span> <span class="hljs-attribute" style="box-sizing: border-box;">-name</span> BitKeeper <span class="hljs-attribute" style="box-sizing: border-box;">-o</span> <span class="hljs-attribute" style="box-sizing: border-box;">-name</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>svn <span class="hljs-attribute" style="box-sizing: border-box;">-o</span>    <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>
<span class="hljs-attribute" style="box-sizing: border-box;">-name</span> CVS <span class="hljs-attribute" style="box-sizing: border-box;">-o</span> <span class="hljs-attribute" style="box-sizing: border-box;">-name</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>pc <span class="hljs-attribute" style="box-sizing: border-box;">-o</span> <span class="hljs-attribute" style="box-sizing: border-box;">-name</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>hg <span class="hljs-attribute" style="box-sizing: border-box;">-o</span> <span class="hljs-attribute" style="box-sizing: border-box;">-name</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>git <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>
<span class="hljs-attribute" style="box-sizing: border-box;">-prune</span> <span class="hljs-attribute" style="box-sizing: border-box;">-o</span>
export RCS_TAR_IGNORE <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">:=</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">--</span>exclude SCCS <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">--</span>exclude BitKeeper <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">--</span>exclude <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>svn <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>
<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">--</span>exclude CVS <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">--</span>exclude <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>pc <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">--</span>exclude <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>hg <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">--</span>exclude <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>git</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>


That’s all. We have finished with the all preparations, next point is the building of
vmlinux
.

就这样,我们完成了所有的准备工作,下面进入
vmlinux
的编译。


Directly to the kernel build(进入内核编译)

We have now finished all the preparations, and next step in the main makefile is related to the kernel build. Before this moment, nothing has been printed to the terminal by
make
.
But now the first steps of the compilation are started. We need to go to line 598 of the Linux kernel top makefile and
we will find the
vmlinux
target there:

我们已经完成全部的准备工作,下面进入到与内核编译相关的步骤。在此之前,终端上不会打印出
make
命令的任何输出。但从现在开始内核编译的第一步。我们跳转到内核源码顶层Makefile的第598行,我们会看到编译目标
vmlinux
的定义:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">all:</span> vmlinux
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span> arch/<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">SRCARCH</span>)/<span class="hljs-constant" style="box-sizing: border-box;">Makefile</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


Don’t worry that we have missed many lines in Makefile that are between
export RCS_FIND_IGNORE.....
and
all:
vmlinux.....
. This part of the makefile is responsible for the
make *.config
targets and as I wrote in the beginning
of this part we will see only building of the kernel in a general way.

别担心,我们跳过了从
export RCS_FIND_IGNORE.....
all:
vmlinux.....
之间的这么多行。Makefile这部分内容与
make *.config
相关,就像我在文件开头说的那样,我们仅研究一个通用的编译过程。

The
all:
target is the default when no target is given on the command line. You can see here that we include architecture
specific makefile there (in our case it will be arch/x86/Makefile). From this moment we will continue from this makefile.
As we can see
all
target depends on the
vmlinux
target
that defined a little lower in the top makefile:

all
目标是在没有通过命令行传递任何编译目标时的默认编译目标。你可以看到,此时,我们包含了跟架构相关的makefile(在本例中是指arch/x86/Makefile)。现在我们继续研究makefile。我们看到目标
all
依赖于目标
vmlinux
,
目标
vmlinux
定义在顶层makefile下面一点:
<code class="language-Makefile hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">vmlinux: scripts/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">link</span><span class="hljs-attribute" style="box-sizing: border-box;">-vmlinux</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>sh $(vmlinux<span class="hljs-attribute" style="box-sizing: border-box;">-deps</span>) FORCE</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


The
vmlinux
is the Linux kernel in a statically linked executable file format. The scripts/link-vmlinux.sh script
links and combines different compiled subsystems into vmlinux. The second target is the
vmlinux-deps
that defined as:

vmlinux
是Linux内核的一种静态链接可执行文件格式。脚本scripts/link-vmlinux.sh链接并将编译后得各子系统打包进vmlinux。

第二个目标
vmlinux-deps
的定义如下:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">vmlinux-deps <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span>= <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">KBUILD_LDS</span>) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">KBUILD_VMLINUX_INIT</span>) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">KBUILD_VMLINUX_MAIN</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


and consists from the set of the
built-in.o
from each top directory of the Linux kernel. Later, when we will go through
all directories in the Linux kernel, the
Kbuild
will compile all the
$(obj-y)
files.
It then calls
$(LD) -r
to merge these files into one
built-in.o
file.
For this moment we have no
vmlinux-deps
, so the
vmlinux
target
will not be executed now. For me
vmlinux-deps
contains following files:

它由LInux内核源码中各顶层目录中的
built-in.o
组成。后面当我们遍历Linux内核的所有目录时,
kbuild
会编译
$(obj-y)
中的源码,然后调用
$(LD)
-r
将这些文件打包成一个
built-in.o
。现在,我们还没有生成
vmlinux-deps
,所以
vmlinux
目标还不会进行编译。对于我来说,
vmlinux-deps
包含下面这些文件:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">arch/x86/kernel/vmlinux<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lds</span> arch/x86/kernel/head_64<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
arch/x86/kernel/head64<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>    arch/x86/kernel/head<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
init/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>             usr/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
arch/x86/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>         kernel/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
mm/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>               fs/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
ipc/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>              security/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
crypto/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>           block/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
lib/lib<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.a</span>                   arch/x86/lib/lib<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.a</span>
lib/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>              arch/x86/lib/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
drivers/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>          sound/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
firmware/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>         arch/x86/pci/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
arch/x86/power/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>   ar
367bf
ch/x86/video/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
net/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>


The next target that can be executed is following:

下一个可以编译的目标是:
<code class="language-Makefile hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sort</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>vmlinux-deps)): <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>vmlinux-dirs) ;
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>vmlinux-dirs): prepare scripts
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>Q)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>MAKE) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>build)=<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$@</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>


As we can see
vmlinux-dirs
depends on two targets:
prepare
and
scripts
.
prepare
is
defined in the top
Makefile
of the Linux kernel and executes three stages of preparations:

我们看到
vmlinux-dirs
依赖于两个目标
prepare
scripts
prepare
定义在顶层的
Makefile
中,分为3各执行阶段:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">prepare:</span> prepare<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">prepare0:</span> archprepare <span class="hljs-constant" style="box-sizing: border-box;">FORCE</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">MAKE</span>) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>build)=.
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">archprepare:</span> archheaders archscripts prepare1 scripts_basic

<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">prepare1:</span> prepare2 <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>version_h) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span>/generated/utsrelease.h \
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span>/config/auto.conf
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>cmd_crmodverdir)
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">prepare2:</span> prepare3 outputmakefile asm-generic</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>


The first
prepare0
expands to the
archprepare
that
expands to the
archheaders
and
archscripts
that
defined in the
x86_64
specificMakefile.

第一个
prepare0
archprepare
扩展得到。而
archprepare
又由定义在
x86_64
指定Makefile中的
archheaders
and
arch
scripts
扩展得。

Let’s look on it. The
x86_64
specific makefile starts from the definition of the variables that are related to the architecture-specific
configs (defconfig, etc…). After this it defines flags for the compiling of the 16-bit code,
calculating of the
BITS
variable that can be
32
for
i386
or
64
for
the
x86_64
flags for the assembly source code, flags for the linker and many many more (all definitions you can find in
thearch/x86/Makefile).

让我们看下这个文件。
x86_64
指定的makefile,以定义一些架构相关变量开始,之后是定义一些编译16-bit代码的flag,计算
BITS
变量,可以是
i386
架构的
32
或者
x86_64
架构的
64“,定义编译汇编代码的flags,以及链接用的flags等等。

The first target is
archheaders
in the makefile generates syscall table:

该makefile中的第一个目标
archheaders
生成系统调用表:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">archheaders:</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">MAKE</span>) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>build)=arch/x86/entry/syscalls all</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


And the second target is
archscripts
in this makefile is:

makefile中的第二个目标
archscripts
定义如下:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">archscripts:</span> scripts_basic
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">MAKE</span>) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>build)=arch/x86/tools relocs</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


We can see that it depends on the
scripts_basic
target from the top Makefile.
At the first we can see the
scripts_basic
target that executes make for the scripts/basic makefile:

我们可以看到,它依赖于定义在根Makefile中的
scripts_basic
,在目录scripts/basic中执行make命令生成目标
scripts_basic

<code class="language-Maklefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">scripts_basic:</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">MAKE</span>) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>build)=scripts/basic</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


The
scripts/basic/Makefile
contains targets for compilation of the two host programs:
fixdep
and
bin2
:

scripts/basic/Makefile
包含编译生成两个主机端程序
fixdep
bin2
的一些目标:
<code class="language-Makefile hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">hostprogs-y := fixdep
hostprogs-<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>CONFIG_BUILD_BIN2C)     += bin2c
always      := <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>hostprogs-y)

<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>addprefix <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>obj)/,<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">filter</span>-out fixdep,<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>always))): <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>obj)/fixdep</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>


First program is
fixdep
- optimizes list of dependencies generated by gcc that
tells make when to remake a source code file.

第一个程序
fixdep
,优化GCC生成的依赖关系表,可以告诉make何时需要重新对源代码文件进行make。

The second program is
bin2c
, which depends on the value of the
CONFIG_BUILD_BIN2C
kernel
configuration option and is a very little C program that allows to convert a binary on stdin to a C include on stdout.

第二个程序
bin2c
,它依赖于内核配置选项中
CONFIG_BUILD_BIN2C
的值,它是一个非常小得C程序,可以讲标准输入中的二进制转换成标准输出中的C头文件。

You can note here a strange notation:
hostprogs-y
, etc… This notation is used in the all
kbuild
files
and you can read more about it in thedocumentation. In our case
hostprogs-y
tells
kbuild
that
there is one host program named
fixdep
that will be built from
fixdep.c
that
is located in the same directory where the
Makefile
is.

你可能会注意到这里有一个奇怪的符号
hostprogs-y
。这个符号被用在所有的
kbuild
文件中,你可以在documentation中找到跟多的描述。在这里,
hostprogs-y
告诉
kbuild
这里将有一个主机端程序
fixdep
由跟
Makefile
同一目录的
fixdep.c
生成。

The first output after we execute
make
in our terminal will be result of this
kbuild
file:

我们执行
make
命令后的第一条输出就是由这个
kbuild
文件生成的:
<code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$ </span>make
<span class="hljs-constant" style="box-sizing: border-box;">HOSTCC</span>  scripts/basic/fixdep</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


As
script_basic
target was executed, the
archscripts
target
will execute
make
for the arch/x86/tools makefile
with the
relocs
target:

当目标
script_basic
执行完后,目标
archscripts
会在目录arch/x86/tools中执行
make
,编译目标
relocs
:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">MAKE</span>) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>build)=arch/x86/tools relocs</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


The
relocs_32.c
and the
relocs_64.c
will
be compiled that will contain relocation information and we will see it in the
make
output:

文件
relocs_32.c
relocs_64.c
将会被编译,它们包含有重定向信息,我们可以看到下面的
make
输出:
<code class="language-Makefile hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  HOSTCC  arch/x86/tools/relocs_32<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
HOSTCC  arch/x86/tools/relocs_64<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
HOSTCC  arch/x86/tools/relocs_common<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
HOSTLD  arch/x86/tools/relocs</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>


There is checking of the
version.h
after compiling of the
relocs.c
:

在编译
relocs.c
后,会检查文件
version.h

<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>version_h)<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>srctree)/<span class="hljs-constant" style="box-sizing: border-box;">Makefile</span> <span class="hljs-constant" style="box-sizing: border-box;">FORCE</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>call filechk,version.h)
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)rm -f <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>old_version_h)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>


We can see it in the output:

我们会看到这样的输出:
<code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-constant" style="box-sizing: border-box;">CHK</span>     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span>/config/kernel.release</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


and the building of the
generic
assembly headers with the
asm-generic
target
from the
arch/x86/include/generated/asm
that generated in the top Makefile of the Linux kernel.

并执行目标
asm-generic
,编译目录
arch/x86/include/generated/asm
中的
generic
汇编文件。它们是由Linux内核的根Makefile生成的。

After the
asm-generic
target the
archprepare
will
be done, so the
prepare0
target will be executed. As I wrote above:

asm-generic
目标之后,
archprepare
也将完成,目标
prepare0
将会被编译,像之前提到的那样:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">prepare0:</span> archprepare <span class="hljs-constant" style="box-sizing: border-box;">FORCE</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">MAKE</span>) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>build)=.</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


Note on the
build
. It defined in the scripts/Kbuild.include and
looks like this:

注意那个
build
,它定义在scripts/Kbuild.include文件中,看起来像这样:
<code class="language-Makefile hljs makefile has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-constant" style="box-sizing: border-box;">build</span> := -f <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(srctree)</span>/scripts/Makefile.build obj</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


Or in our case it is current source directory -
.
:

或者在本例中,它就是当前代码目录
.

<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">MAKE</span>) -f <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>srctree)/scripts/<span class="hljs-constant" style="box-sizing: border-box;">Makefile</span>.build obj=.</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


The scripts/Makefile.build tries to find the
Kbuild
file
by the given directory via the
obj
parameter, include this
Kbuild
files:

脚本scripts/Makefile.build 尝试寻找
obj
参数指定目录中的
Kbuild
文件,包含这些文件,并编译这些文件中的目标。
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>kbuild-file)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


and build targets from it.In our case
.
contains the Kbuild file
that generates the
kernel/bounds.s
and the
arch/x86/kernel/asm-offsets.s
.
After this the
prepare
target finished to work.

在本例中,当前目录
.
包含生成
kernel/bounds.s
arch/x86/kernel/asm-offsets.s
的Kbuild文件。在此之后,目标
prepare
就编译完成了。

The
vmlinux-dirs
also depends on the second target -
scripts
that
compiles following programs:
file2alias
,
mk_elfconfig
,
modpost
,
etc….. After scripts/host-programs compilation our
vmlinux-dirs
target can be executed.

vmlinux-dirs
也依赖与prepare的第二阶段,
scripts
编译生成了下面这些程序:
file2alias
,
mk_elfconfig
,
modpost
等。在scripts/host-programs编译完之后,目标
vmlinux-dirs
也可以开始执行了。

First of all let’s try to understand what does
vmlinux-dirs
contain. For my case it contains paths of the following kernel
directories:

首先,让我们试着去了解
vmlinux-dirs
中包含哪些内容。在本例中,它包含下面这些内核目录的路径:
<code class="hljs vbnet has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">init usr arch/x86 kernel mm fs ipc security crypto block
drivers sound firmware arch/x86/pci arch/x86/power
arch/x86/video net <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">lib</span> arch/x86/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">lib</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>


We can find definition of the
vmlinux-dirs
in the top Makefile of
the Linux kernel:

在Linux内核源码根目录的Makefile中,我们可以找到
vmlinux-dirs
的定义:
<code class="language-Makefile hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">vmlinux-dirs    := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
$(net-y) $(net-m) $(libs-y) $(libs-m)))

init-y      := init/
drivers-y   := drivers/ sound/ firmware/
net-y       := net/
libs-y      := lib/
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>


Here we remove the
/
symbol from the each directory with the help of the
patsubst
and
filter
functions
and put it to the
vmlinux-dirs
. So we have list of directories in the
vmlinux-dirs
and
the following code:

这里,我们通过函数
patsubst
filter
移除了每个目录名中的
/
,并将其赋值给了
vmlinux-dirs
,这样我们得到了包含文件夹列表的
vmlinux-dirs
变量和下面这段代码:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>vmlinux-dirs)<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span> prepare scripts
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">MAKE</span>) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>build)=<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$@</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


The
$@
represents
vmlinux-dirs
here
that means that it will go recursively over all directories from the
vmlinux-dirs
and its internal directories (depens
on configuration) and will execute
make
in there. We can see it in the output:

符号
$@
代表
vmlinux-dirs
,这里的含义是,递归的进入
vmlinux-dirs
中的每个目录及其子目录,并在里面执行
make
命令,我们可以看到这样的输出:
<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  CC      init/main.o
CHK     include/generated/compile.h
CC      init/version.o
CC      init/do_mounts.o
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
CC      arch/x86/crypto/glue_helper.o
AS      arch/x86/crypto/aes-x86_64-asm_64.o
CC      arch/x86/crypto/aes_glue.o
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
AS      arch/x86/entry/entry_64.o
AS      arch/x86/entry/thunk_64.o
CC      arch/x86/entry/syscall_64.o</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>


Source code in each directory will be compiled and linked to the
built-in.o
:

每个目录中的源码都会被编译和链接生成
built-in.o
:
<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">$ find . -name built-in.o
./arch/x86/crypto/built-in.o
./arch/x86/crypto/sha-mb/built-in.o
./arch/x86/net/built-in.o
./init/built-in.o
./usr/built-in.o
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>


Ok, all buint-in.o(s) built, now we can back to the
vmlinux
target. As you remember, the
vmlinux
target
is in the top Makefile of the Linux kernel. Before the linking of the
vmlinux
it builds samples, Documentation,
etc… but I will not describe it here as I wrote in the beginning of this part.

好了,当这些buint-in.o(s)都生成后,我们可以回到目标
vmlinux
上来。你还记得,目标
vmlinux
是定义在顶层Makefile中的。在链接
vmlinux
之前,它会编译生成
samples和Documentation这些,但像我之前提到过的,我不会描述它们的编译过程。
<code class="language-Makefile hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
+$(call if_changed,link-vmlinux)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>


As you can see main purpose of it is a call of the scripts/link-vmlinux.sh script is linking of the all
built-in.o
(s)
to the one statically linked executable and creation of the System.map. In the end we will see following output:

你可以看到,代码主要是调用脚本scripts/link-vmlinux.sh,将所有的
built-in.o
(s)静态链接成一个可执行的文件,并生成System.map。最后我们可以看到这样的输出以及Linux源码根目录中的
vmlinux
System.map

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  LINK    vmlinux
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">LD</span>      vmlinux<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
MODPOST vmlinux<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
GEN     <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.version</span>
CHK     include/generated/compile<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.h</span>
UPD     include/generated/compile<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.h</span>
CC      init/version<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">LD</span>      init/built-<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
KSYM    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.tmp</span>_kallsyms1<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
KSYM    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.tmp</span>_kallsyms2<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">LD</span>      vmlinux
SORTEX  vmlinux
SYSMAP  System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.map</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>


and
vmlinux
and
System.map
in
the root of the Linux kernel source tree:
<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">$ ls vmlinux System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">map</span>
System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">map</span>  vmlinux</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


That’s all,
vmlinux
is ready. The next step is creation of the bzImage.

至此,
vmlinux
已经生成,下一步是生成
bzImage


Building bzImage(编译bzImage)

The
bzImage
file is the compressed Linux kernel image. We can get it by executing
make
bzImage
after
vmlinux
is built. That, or we can just execute
make
without
any argument and we will get
bzImage
anyway because it is default image:

bzImage
是压缩过的内核镜像。在生成
vmlinux
后,可以通过命令
make
bzImage
获得
bzImage
。或者干脆直接执行
make
命令不带任何参数,我们也能得到
bzImage
,因为它是arch/x86/kernel/Makefile的默认的编译目标:
<code class="language-Makefile hljs http has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">all</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">bzImage</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


in the arch/x86/kernel/Makefile. Let’s look on this target, it will help us to understand how this image builds. As
I already said the
bzImage
target defined in the arch/x86/kernel/Makefile and
looks like this:

让我们看看这个目标,这有助于我们理解这个镜像文件时如何生成的。之前我们提到,
bzImage
目标定义在文件arch/x86/kernel/Makefile中,看起来像这样:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">bzImage:</span> vmlinux
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">MAKE</span>) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>build)=<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>boot) <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">KBUILD_IMAGE</span>)
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)mkdir -p <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>objtree)/arch/<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">UTS_MACHINE</span>)/boot
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">Q</span>)ln -fsn ../../x86/boot/bzImage <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>objtree)/arch/<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">UTS_MACHINE</span>)/boot/<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$@</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>


We can see here, that first of all called
make
for the boot directory, in our case it is:

到这里,我们看到第一步是在boot目录下执行
make
,在本例中,boot目录是:
<code class="language-Makefile hljs fix has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">boot :</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;"> arch/x86/boot</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


The main goal now is to build the source code in the
arch/x86/boot
and
arch/x86/boot/compressed
directories,
build
setup.bin
and
vmlinux.bin
,
and build the
bzImage
from them in the end. First target in the arch/x86/boot/Makefile is
the
$(obj)/setup.elf
:

现在的主要目标是,编译目录
arch/x86/boot
arch/x86/boot/compressed
中的代码,生成
setup.bin
vmlinux.bin
,并且最终通过它们生成
bzImage


arch/x86/boot/Makefile中的第一个目标是
$(obj)/setup.elf
:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>obj)/setup.<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">elf:</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>src)/setup.ld <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">SETUP_OBJS</span>) <span class="hljs-constant" style="box-sizing: border-box;">FORCE</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>call if_changed,ld)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


We already have the
setup.ld
linker script in the
arch/x86/boot
directory
and the
SETUP_OBJS
variable that expands to the all source files from the
boot
directory.
We can see first output:

在目录
arch/x86/boot
中我们已经有了
setup.ld
,变量
SETUP_OBJS
展开后得到目录
boot
中的所有源文件。我们第一次看到这样输出:
<code class="language-Makefile hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  AS      arch/x86/boot/bioscall<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/cmdline<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
AS      arch/x86/boot/copy<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
HOSTCC  arch/x86/boot/mkcpustr
CPUSTR  arch/x86/boot/cpustr<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.h</span>
CC      arch/x86/boot/cpu<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/cpuflags<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/cpucheck<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/early_serial_console<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/edd<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>


The next source file is arch/x86/boot/header.S, but we can’t build it now because this target depends on the
following two header files:

下一个源文件是arch/x86/boot/header.S,但目前我们还不能编译它,因为它依赖于下面两个头文件:
<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>obj)/header.<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">o:</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>obj)/voffset.h <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>obj)/zoffset.h</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


The first is
voffset.h
generated by the
sed
script
that gets two addresses from the
vmlinux
with the
nm
util:

第一个头文件
voffset.h
sed
脚本通过
nm
工具获取的
vmlinux
的两个地址,它们是Linux内核的起始和结束地址:
<code class="language-C hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> VO__end 0xffffffff82ab0000</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> VO__text 0xffffffff81000000</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


They are start and end of the kernel. The second is
zoffset.h
depens on the
vmlinux
target
from the arch/x86/boot/compressed/Makefile:

第二个头文件
zoffset.h
依赖于arch/x86/boot/compressed/Makefile中的目标
vmlinux

<code class="language-Makefile hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>obj)/zoffset.<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">h:</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>obj)/compressed/vmlinux <span class="hljs-constant" style="box-sizing: border-box;">FORCE</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>call if_changed,zoffset)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


The
$(obj)/compressed/vmlinux
target depends on the
vmlinux-objs-y
that
compiles source code files from the arch/x86/boot/compresseddirectory and generates
vmlinux.bin
,
vmlinux.bin.bz2
,
and compiles programm -
mkpiggy
. We can see this in the output:

目标
$(obj)/compressed/vmlinux
依赖于
vmlinux-objs-y
,编译arch/x86/boot/compressed中的代码,生成
vmlinux.bin
,
vmlinux.bin.bz2
以及程序
mkpiggy
,我们可以看到下面这些输出:
<code class="language-Makefile hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">LDS</span>     arch/x86/boot/compressed/vmlinux<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lds</span>
AS      arch/x86/boot/compressed/head_64<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/compressed/misc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/compressed/string<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/compressed/cmdline<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
OBJCOPY arch/x86/boot/compressed/vmlinux<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.bin</span>
BZIP2   arch/x86/boot/compressed/vmlinux<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.bin</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.bz</span>2
HOSTCC  arch/x86/boot/compressed/mkpiggy</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>


Where
vmlinux.bin
is the
vmlinux
file
with debuging information and comments stripped and the
vmlinux.bin.bz2
compressed
vmlinux.bin.all
+
u32
size
of
vmlinux.bin.all
. The
vmlinux.bin.all
is
vmlinux.bin
+ vmlinux.relocs
, where
vmlinux.relocs
is the
vmlinux
that
was handled by the
relocs
program (see above). As we got these files, the
piggy.S
assembly
files will be generated with the
mkpiggy
program and compiled:

这里的
vmlinux.bin
vmlinux
文件去除调试信息和注释后生成的。通过程序
relocs
处理
vmlinux
后得到
vmlinux.relocs
vmlinux.bin.all
= vmlinux.bin + vmlinux.relocs
vmlinux.bin.bz2
vmlinux.bin.all
压缩后得到的。生成这些文件后,
mkpiggy
程序会生成汇编文件
piggy.S
并编译:
<code class="language-Makefile hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  MKPIGGY arch/x86/boot/compressed/piggy<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.S</span>
AS      arch/x86/boot/compressed/piggy<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


This assembly files will contain the computed offset from the compressed kernel. After this we can see that
zoffset
generated:

这个汇编文件中包含了计算得到的压缩后的内核偏移量。之后我们可以看到生成了目标
zoffset

<code class="language-Makefile hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  ZOFFSET arch/x86/boot/zoffset<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.h</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


As the
zoffset.h
and the
voffset.h
are
generated, compilation of the source code files from the arch/x86/boot can be continued:

当文件
zoffset.h
voffset.h
生成后,编译可以继续进行:
<code class="language-Makefile hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  AS      arch/x86/boot/header<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/main<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/mca<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/memory<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/pm<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
AS      arch/x86/boot/pmjump<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/printf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/regs<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/string<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/tty<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/video<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/video-mode<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/video-vga<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/video-vesa<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span>
CC      arch/x86/boot/video-bios<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>


As all source code files will be compiled, they will be linked to the
setup.elf
:

所有文件都被编译后,它们将会被链接到
setup.elf
文件中去:
<code class="language-Makefile hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">LD</span>      arch/x86/boot/setup<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.elf</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


or(或者):
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">ld</span> -m elf_x86_64   -T arch/x86/boot/setup<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ld</span> arch/x86/boot/a20<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/bioscall<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/cmdline<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/copy<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/cpu<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/cpuflags<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/cpucheck<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/early_serial_console<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/edd<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/header<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/main<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/mca<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/memory<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/pm<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/pmjump<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/printf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/regs<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/string<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/tty<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/video<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/video-mode<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/version<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/video-vga<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/video-vesa<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> arch/x86/boot/video-bios<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.o</span> -o arch/x86/boot/setup<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.elf</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


The last two things is the creation of the
setup.bin
that will contain compiled code from the
arch/x86/boot/*
directory:

最后两项工作是生成包含
arch/x86/boot/*
编译后代码的
setup.bin

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">objcopy  -O binary arch/x86/boot/setup<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.elf</span> arch/x86/boot/setup<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.bin</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


and the creation of the
vmlinux.bin
from the
vmlinux
:

和从
vmlinux
生成
vmlinux.bin

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">objcopy  <span class="hljs-attribute" style="box-sizing: border-box;">-O</span> binary <span class="hljs-attribute" style="box-sizing: border-box;">-R</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>note <span class="hljs-attribute" style="box-sizing: border-box;">-R</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>comment <span class="hljs-attribute" style="box-sizing: border-box;">-S</span> arch/x86/boot/compressed/vmlinux arch/x86/boot/vmlinux<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>bin</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


In the end we compile host program: arch/x86/boot/tools/build.c that will create our
bzImage
from
the
setup.bin
and the
vmlinux.bin
:

接着,我们会编译一个主机端程序arch/x86/boot/tools/build.c 它会通过
setup.bin
vmlinux.bin
生成
bzImage

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">arch/x86/boot/tools/build arch/x86/boot/setup<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.bin</span> arch/x86/boot/vmlinux<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.bin</span> arch/x86/boot/zoffset<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.h</span> arch/x86/boot/bzImage</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


Actually the
bzImage
is the concatenated
setup.bin
and
the
vmlinux.bin
. In the end we will see the output which is familiar to all who once built the Linux kernel from source:

实际上,
bzImage
setup.bin
vmlinux.bin
的结合体。最后,我们会看到很熟悉的输出,如果你曾从代码开始编译过内核。
<code class="hljs vbnet has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Setup <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">is</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16268</span> bytes (padded <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">to</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16384</span> bytes).
System <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">is</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4704</span> kB
CRC <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">94</span>a88f9a
Kernel: arch/x86/boot/bzImage <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">is</span> ready  (<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#5)</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>


That’s all.

编译过程至此结束。


Conclusion(总结)

It is the end of this part and here we saw all steps from the execution of the
make
command to the generation of the
bzImage
.
I know, the Linux kernel makefiles and process of the Linux kernel building may seem confusing at first glance, but it is not so hard. Hope this part will help you understand the process of building the Linux kernel.

至此,本文描述了从开始执行
make
命令到生成
bzImage
整个流程。我知道Linux内核makefile和编译步骤咋一看很令人困惑,但其实也没那么难。希望本文能够帮助你理解编译Linux内核的编译流程。


Links(链接)

GNU make util
Linux kernel top Makefile
cross-compilation
Ctags
sparse
bzImage
uname
shell
Kbuild
binutils
gcc
Documentation
System.map
Relocation

转自:http://blog.csdn.net/sunao2002002/article/details/48874653
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: