曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 11275|回复: 3
打印 上一主题 下一主题

[Kernel] 走一走 make menuconfig 流程

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2011-6-28 11:32:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Makefile 对应内核版本:2.6.35.13

在编译内核之前需要进行内核的配置,一般会用 make defconfig 或 make menuconfig 此类 make *config 命令进行配置。这里假设平台是 x86 。下面走一走这个流程。

在顶层 Makefile 的 452-464 行可以看到:
[code=Makefile]
# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
# KBUILD_DEFCONFIG may point out an alternative default configuration
# used for 'make defconfig'
include $(srctree)/arch/$(SRCARCH)/Makefile
export KBUILD_DEFCONFIG KBUILD_KCONFIG

config: scripts_basic outputmakefile FORCE
    $(Q)mkdir -p include/linux include/config
    $(Q)$(MAKE) $(build)=scripts/kconfig $@

%config: scripts_basic outputmakefile FORCE
    $(Q)mkdir -p include/linux include/config
    $(Q)$(MAKE) $(build)=scripts/kconfig $@
[/mw_shl_code]
这里看到了两个目标 config 和 %config ,其中 %config 表示匹配诸如 menuconfig,oldconfig 这样的目标。这两个目标的依赖都是 scripts_basic 和 outputmakefile,关于两个依赖的讨论可参考:http://www.groad.net/bbs/read.php?tid-3895.html

在解决了这两个依赖后,就会执行其下的命令。首先会建立 include/linux 和 include/config 两个目录,接着执行 $(Q)$(MAKE) $(build)=scripts/kconfig $@ 语句(假设这里执行的是 make menuconfig 命令),这条语句展开后实际是:
make -f scripts/Makefile.build obj=scripts/kconfig menuconfig

在  scripts/Makefile.build 文件里的第 42-44 行我们看到:
[code=Makefile]kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)[/mw_shl_code]
这里已经将 scripts/kconfig 目录下的 Makefile 包含了进来,这时注意到在 scripts/kconfig/Makefile 中的第 20-21 行发现了 menuconfig 的身影:
[code=Makefile]menuconfig: $(obj)/mconf
    $< $(Kconfig)[/mw_shl_code]
上面,menuconfig 这个目标依赖于 mconf 这个程序。这个程序的作用在第 156-157 行有注解:
mconf:  Used for the menuconfig target 。Utilizes the lxdialog package
mconf 是一个基于 lxdialog 包的且在构建 menuconfig 目标时需要使用的程序(生成基于 [color=#0000ff ]ncurses 图形界面)。

同样在 scripts/kconfig/Makefile 的 168 和 172 行看到:
[code=Makefile]mconf-objs     := mconf.o zconf.tab.o $(lxdialog)
hostprogs-y := conf qconf gconf kxgettext[/mw_shl_code]
mconf-objs 和 hostprogs-y 这两个变量会被传递到 Makefile.host 文件中进行相应的处理,后面会分析到。

还在 scripts/kconfig/Makefile 的 178-180 行看到:
[code=Makefile]ifeq ($(MAKECMDGOALS),menuconfig)
    hostprogs-y += mconf
endif[/mw_shl_code]
这里将 mconf 添加到 hostprogs-y 变量中,表示也要被编译为可执行文件,此时 hostprogs-y 的值为:conf gconf kxgettext  qconf mconf,表示这 5 个文件将要被编译。

再回到 Makefile.build 的 62-64 行:
[code=Makefile]ifneq ($(hostprogs-y)$(hostprogs-m),)
include scripts/Makefile.host
endif[/mw_shl_code]
这里将 Makefile.host 文件包含进来,在 Makefile.host 里会处理 mconf-objs 和 hostprogs-y 这些变量。下面看看 Makefile.host 文件:

在 33 行有:
[code=Makefile]__hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))[/mw_shl_code]
这里的 hostprogs-y 就是从 scripts/kconfig/Makefile 里传递过来的。这里只是对 hostprogs-y 里的文件名进行一下排序,排完后的顺序变为:conf gconf kxgettext mconf qconf 。

在 35-37 行有:
[code=Makefile]# C code
# Executables compiled from a single .c file
host-csingle    := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m)))[/mw_shl_code]
这里,先返回到 scripts/kconfig/Makefile 中,在 182-197 行中看到:
[code=Makefile]ifeq ($(MAKECMDGOALS),xconfig)
    qconf-target := 1
endif
ifeq ($(MAKECMDGOALS),gconfig)
    gconf-target := 1
endif


ifeq ($(qconf-target),1)
qconf-cxxobjs    := qconf.o
qconf-objs    := kconfig_load.o zconf.tab.o
endif

ifeq ($(gconf-target),1)
gconf-objs    := gconf.o kconfig_load.o zconf.tab.o
endif[/mw_shl_code]
如果执行 make xconfig 或 make gconfig 时,qconf-target 和 gconf-target 才会为 1,此时 qconf-objs    := kconfig_load.o zconf.tab.o 和 gconf-objs    := gconf.o kconfig_load.o zconf.tab.o 。因为我们现在执行的是 make menuconfig ,所以,qconf-objs 和 gconf-objs 这两个变量的值为空。所以 host-csingle    := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m))) 的值为 gconf  qconf 。如果没有安装 GTK 或 QT 编译环境,编译 gconfig 和 qconfig 目标是会出错的,而且也无需编译出 gconf 和 qconf 这两个程序。

在 Makefile.host 的 39-41 行有:
[code=Makefile]# C executables linked based on several .o files
host-cmulti    := $(foreach m,$(__hostprogs),\
           $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
[/mw_shl_code]
由注释知道,host-cmulti 里的变量所代表的程序是基于 C 语言编译的(编译这些 host program 也可以用 C++ 来编译),所以 $(m)-cxxobjs) 的值为空(cxx 表示 C++);而且这些程序是依赖于多个 .o 文件链接二来的,所以这里的 host-cmulti 的值就是去掉 gconf 和 qconf 后其它 3 个变量:conf    kxgettext  mconf 。

再来看一下 conf    kxgettext  mconf  这 3 个文件分别的依赖的 .o 文件:
在 scripts/kconfig/Makefile 的 167,170 行看到:
[code=Makefile]conf-objs    := conf.o  zconf.tab.o
kxgettext-objs    := kxgettext.o zconf.tab.o[/mw_shl_code]
所以 conf 依赖 2 个 .o 文件: conf.o  zconf.tab.o 。
kxgettext 也依赖 2 个 .o 文件:kxgettext.o zconf.tab.o 。

在 168 行有:
[code=Makefile]mconf-objs     := mconf.o zconf.tab.o $(lxdialog)[/mw_shl_code]
而 lxdialog 变量定义在 164-165 行:
[code=Makefile]lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o[/mw_shl_code]
所以 mconf 依赖的 .o 文件为:
mconf.o zconf.tab.o lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o

综合起来知道 Makefile.host 中 44 行中 host-cobjs 变量的值为:
host-cobjs conf.o kxgettext.o lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o mconf.o zconf.tab.o

在 Makefile.host 中,我们不需要理会用 C++ 编译的情况,所以分析到这些相关的行时可以忽略。

在回到 Makefile.host 中,其中 78-86 行是为上面相关变量添加上相应的目录前缀,这里就是 scripts/kconfig/ 。

在 91-107 行是对编译时需要添加的一些编译参数。

从 109-168 这一片程序段用来编译 .c 文件以及链接 .o 文件到可执行文件。

在上面的相关工具及环境准备妥当后,会返回到 scripts/kconfig/Makefile 的第 21 行执行 $< $(Kconfig) 这条命令,这条命令就是用 mconf 程序读入与平台相关的 Kconfig 文件,比如对于 x86 平台的 Kconfig 文件就位于 arch/x86/Kconfig 。最后在用户处理完毕后,就会将配置结果保存到 .config 中。在各个平台对应的顶层 Kconfig 里,还会用 source 命令将各子目录的 Kconfig 文件包含进来,各子目录的 Kconfig 同样也可以包含它的子目录 Kconfig 文件,这样就形成了一个树形结构。

0

主题

2

帖子

6

积分

初学弟子

积分
6
沙发
发表于 2011-7-28 15:58:46 | 只看该作者
我最近也在研究 linux的make流程, 以后多交流,谢谢!

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
板凳
 楼主| 发表于 2011-7-28 11:01:46 | 只看该作者

回 1楼(zhangjun0718) 的帖子

内核 Makefile 本身很复杂,我写的帖子,只是自己跟踪的一个流程,不一定都说得对。写出来一来是自己做下笔记,二来是分享出来,抛砖引玉,若大家看后觉得有不对的地方也能帮忙指出,这就很感激了。

跟踪 Makefile 主要有一条主干线索 “目标” 和 “依赖”,首先看目标,然后逆向寻找“依赖”,最后看“目标”后面执行的指令。在跟踪过程中,也会使用 find ,grep 等工具查找相关变量。另外也会用 Makefile 中的一些内置函数如 error 来观察条件是否成立等等。

0

主题

2

帖子

6

积分

初学弟子

积分
6
地板
发表于 2011-7-28 00:23:08 | 只看该作者
请问楼主是用什么方法跟踪make menuconfig 流程的?谢谢!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-17 14:50 , Processed in 0.097197 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表