linux内核的Makefile文件分类:
1.顶层的Makefile2..config 所有的Makefile都是由.config来决定使用那些文件。
3.arch下的Makefile
4.script下的Makefile
5.kbuild Makefile 各级子目录下的Makefile。
在linux-2.6.22.6\Documentation\kbuild目录下的makefiles.txt对内核的Makefile讲的比较清楚,可以细看。
在子目录下,如果有a.c b.c 两个模块要编译成模块可以这么做
obj-m += ab.o
ab-objs := a.o b.o
我们要分析Makefile从顶层的Makefile往下分析:
我们在编译内核的时候make uImage命令,那么uImage 的目标是位于哪里呢,我们的架构是arch/arm架构的,在这个目录下的Makefile可以找到他。
那我们在make uImage的时候,顶层目录下并没有找到uImage,那它是怎么做到make uImage的呢?
根据我们对Makefile的了解,那arch/arm架构的的Makefile可以被包含到顶层目录下的Makefile下,在顶层的Makefile下查找include我们可以找到:
# 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/$(ARCH)/Makefile
可以看出它是被包含到顶层的Makefile了。
对于.config 会生成autoconf.h、auto.conf,他是不是也被包含进顶层的Makefile了呢,查一下auto.conf。
# Read in config
-include include/config/auto.conf
可以看到也是包含进来了。
zImage Image xipImage bootpImage uImage: vmlinux
uImage的依赖是vmlinux,我们在架构下的Makefile下并没有找到vmlinux的依赖,在顶层的Makefile下找到了vmlinux的依赖:
# vmlinux image - including updated kernel symbols
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
那vmlinux-lds、vmlinux-main、vmlinux-init这些分别是什么呢,我们可以在顶层的Makefile下查查:
vmlinux-init := $(head-y) $(init-y)
#Default value
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o //在架构下的Makefile定义的。
init-y := init/
init-y := $(patsubst %/, %/built-in.o, $(init-y)) //在顶层的Makefile下定义的。
$(patsubst %.c,%.o,x.c.c bar.c)
把字串“x.c.c bar.c”中以.c结尾的单词替换成以.o结尾的字符。函数的返回结果是“x.c.o bar.o”
展开为:init-y := init/build-in.o
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
core-y := usr/
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
core-y := $(patsubst %/, %/built-in.o, $(core-y))
展开为:core-y :=usr/build-in.o kernel/build-in.o mm/build-in.o fs/build-in.o security/build-in.o crypto/build-in.o block/build-in.o
libs-y := lib/
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)
展开为libs-y := lib/build-in.o lib/lib.a
drivers-y := drivers/ sound/
drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
展开为drivers-y := drivers/build-in.o sound/build-in.o
net-y := net/
net-y := $(patsubst %/, %/built-in.o, $(net-y))
vmlinux-all := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
前面分析的一堆原材料是怎么被链接到一起的呢?
# vmlinux image - including updated kernel symbols
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
ifdef CONFIG_HEADERS_CHECK
$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
endif
$(call if_changed_rule,vmlinux__)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
$(Q)rm -f .old_version
这要分析Makefile的话比较庞大了,只是想了解它的话我们编译一下内核看结果。
要是我们之前编译过内核的话我们先rm vmlinux,然后make uImage V=1 //v=1的作用是把命令更详细的列出
arm-linux-ld -EL -p --no-undefined -X -o vmlinux -T arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o arch/arm/kernel/init_task.o init/built-in.o --start-group usr/built-in.o arch/arm/kernel/built-in.o arch/arm/mm/built-in.o arch/arm/common/built-in.o
arch/arm/mach-s3c2410/built-in.o arch/arm/mach-s3c2400/built-in.o arch/arm/mach-s3c2412/built-in.o arch/arm/mach-s3c2440/built-in.o arch/arm/mach-s3c2442/built-in.o arch/arm/mach-s3c2443/built-in.o arch/arm/nwfpe/built-in.o arch/arm/plat-s3c24xx/built-in.o
kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o block/built-in.o arch/arm/lib/lib.a lib/lib.a arch/arm/lib/built-in.o lib/built-in.o drivers/built-in.o sound/built-in.o net/built-in.o --end-group
.tmp_kallsyms2.o
截取一段,我们可以看到这些跟我们之前分析的很对应,待会我们在看下他的链接脚本。
从上面的分析中我们可以得到一些比较中要的信息:
1.第一个文件:arch/arm/kenel/head.s
2.链接脚本:arch/arm/kernl/vmlinux.lds
不过在内核目录下找不到vmlinux.lds,该文件为vmlinux.lds.S生成。我们可以打来vmlinux.lds看看他的一些内容。
具体的不做分析了,内核大概的Makefile就这样有个基本的认识了。
SECTIONS
{
. = (0xc0000000) + 0x00008000;
.text.head : {
_stext = .;
_sinittext = .;
*(.text.head) //所有文件的段
}
.init : { /* Init code and data */
*(.init.text)
_einittext = .;
__proc_info_begin = .;
*(.proc.info.init)
__proc_info_end = .;
__arch_info_begin = .;
*(.arch.info.init)
__arch_info_end = .;
__tagtable_begin = .;
*(.taglist.init)
__tagtable_end = .;
. = ALIGN(16);
__setup_start = .;
。。。。。。。。。。。。
。。。。。。。。。。。
。。。。。。。。。。。。