Chinaunix首页 | 论坛 | 博客
  • 博客访问: 974237
  • 博文数量: 109
  • 博客积分: 1751
  • 博客等级: 上尉
  • 技术积分: 1817
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-31 22:37
文章分类

全部博文(109)

文章存档

2014年(9)

2013年(21)

2012年(48)

2011年(31)

分类: LINUX

2011-09-27 14:34:04

Kernel的Makefile其实常常见到,不过也就是用用,没有机会仔细分析。这里简单分析下顶层Makefile,也算是对我们经常执行的make命令的执行过程有所了解。

Makefile以2.6.29为例,版本之间差异应该不会太大。

Line 1 ~ Line 6
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 29
kernel的版本号及名称

Line 7 ~ Line 136
L7:     # *DOCUMENTATION*
            ......
            ......
L136:  endif # ifeq ($(KBUILD_SRC),)
这一段对make命令的几个参数进行了处理:
V=:    verbose,打印更详细的log
C=:    check source
M=:   build modules
SUBDIRS=:  build modules
O=:     output directory 指定另外的编译输出目录
KBUILD_SRC=: 未知 # KBUILD_SRC is not intended to be used by the regular user (for now)

Line 138 ~ Line 159
L138:      ifeq ($(skip-makefile),)
                ......
                ......
L159:      export srctree objtree VPATH TOPDIR
这一段给srctree objtree VPATH TOPDIR几个变量赋值,具体的值也和之前的几个参数相关。

Line 169 ~ Line 221
L169:      SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
                ......
                ......
L221:      ifeq ($(ARCH),m68knommu)
                     hdr-arch  := m68k
               endif
这一段设定了交叉编译的几个变量,ARCH指定了目标编译平台,可以在command line中赋值,也可以直接在Makefile中直接修改。CROSS_COMPILE指定交叉编译器的路径,可以在command line中赋值,也可以直接修改Makefile,或者写入根目录的某个文件中,在Makefile中读取,如:
CROSS_COMPILE   := $(shell if [ -f .cross_compile ]; then \
cat .cross_compile; \
fi)

Line 223
KCONFIG_CONFIG ?= .config
指定config文件,默认为当前目录的.config,这里用的是?=,这也就意味着可以在command line中指定其他的config文件。

Line 225 ~ Line 233
指定本地编译器即编译参数

Line 235 ~ Line 263
export KBUILD_MODULES KBUILD_BUILTIN
export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
这一段判定是否需要编译modules。判定原则是make/make all/make modules*/需要编译模块,其他则不用。

Line 265 ~ Line 303
export quiet Q KBUILD_VERBOSE
根据参数判定是否输出详细build信息,V=1要求打印详细信息,make -s进入silent mode

Line 306
# Look for make include files relative to root of kernel src
MAKEFLAGS += --include-dir=$(srctree)
# We need some generic definitions (do not try to remake the file).
$(srctree)/scripts/Kbuild.include: ;
include $(srctree)/scripts/Kbuild.include

Line 315 ~ Line 366
L315:      AS = $(CROSS_COMPILE)as
                ......
                ......
L366:      export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
这一段根据CROSS_COMPILE指定编译用的CC, AS, LD.., 以及编译参数。

Line 371
export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions
为module编译指定路径。由M=指定。

Line 408 ~ Line 460
这一段通过分析command line,判断make的目标是config还是build,或者是mixed-target,即先config再build。
在这一段中,有以下几个中间变量:config-targets, mixed-targets, dot-config。config-targets表示编译目标中包括config,mixed-targets表示有多个编译目标,dot-config表示是否需要包含config文件,凡config及build行为都需要包含config文件,其他则不用。
对于config,makefile相关执行语句为:
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 $@
具体的原因还要分析。。

Line 465
ifeq ($(KBUILD_EXTMOD),)
# Additional helpers built in scripts/
# Carefully list dependencies so we do not try to build scripts twice
# in parallel
PHONY += scripts
scripts: scripts_basic include/config/auto.conf
$(Q)$(MAKE) $(build)=$(@)

# Objects we will link into vmlinux / subdirs we need to visit
init-y := init/
drivers-y := drivers/ sound/ firmware/
net-y := net/
libs-y := lib/
core-y := usr/
endif # KBUILD_EXTMOD
init, drivers, sound, firmware, net, lib, usr等必须的子目录。

Line 481 ~ Line 600
这一段对各种FLAG进行配置。

接下来进入实际的build部分,默认最终生成的image是vmlinux。
对于vmlinux的生成,makefile有注释说明:
# Build vmlinux
# ---------------------------------------------------------------------------
# vmlinux is built from the objects selected by $(vmlinux-init) and
# $(vmlinux-main). Most are built-in.o files from top-level directories
# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
# Ordering when linking is important, and $(vmlinux-init) must be first.
#
# vmlinux
#   ^
#   |
#   +-< $(vmlinux-init)
#   |   +--< init/version.o + more
#   |
#   +--< $(vmlinux-main)
#   |    +--< driver/built-in.o mm/built-in.o + more
#   |
#   +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
注释说明vmlinuz主要由vmlinux-init和vmlinux-main组成。
vmlinux依赖关系如下:
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
部分变量展开为:
vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-all  := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds  := arch/$(SRCARCH)/kernel/vmlinux.lds
export KBUILD_VMLINUX_OBJS := $(vmlinux-all)
而后可依次展开,直到所有的build-in的obj都编译完成,然后根据lds进行link,但是link的过程再哪里?

vmlinux之后是modules,firmware,kernel headers等其他的target。不再细述。

未解决的问题:
1,mix target的问题 ,当有两个target的时候,下面的语句是如何实现 handle them one by one的?
ifeq ($(mixed-targets),1)
# ===========================================================================
# We're called with mixed targets (*config and build targets).
# Handle them one by one.

%:: FORCE
$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@

else

2, config target是如何进行编译的,如上面所提到的针对config的代码:
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 $@

3, .tmp_vmlinux1, .tmp_vmlinux2, .tmp_vmlinux3在makefile中没有被明显的使用,他们是如何被依赖的?








阅读(6284) | 评论(0) | 转发(0) |
0

上一篇:side effect

下一篇:Makefile自动变量

给主人留下些什么吧!~~