前言:
本帖是学习韦东山老师linux kernel教程,粗略总结的课堂笔记及自己感悟。如想深入了解linux kernel,请绕路。
本文简单介绍下linux makefile文件结构。
内核源码文档:\Documentation\kbuild
精华帖:Linux内核Makefile文件(翻译自内核手册) - 冷烟花 - 博客园
相关帖子:
1- 内核makefile结构
下面文字摘自内核源码的说明文档:Documentation\kbuild\makefiles.txt,有兴趣可以阅读下。
The Makefiles have five parts:
Makefile the top Makefile.
.config the kernel configuration file.
arch/$(ARCH)/Makefile the arch Makefile.
scripts/Makefile.* common rules etc. for all kbuild Makefiles.
kbuild Makefiles there are about 500 of these.
2- 子目录makefile
子目录makefile被上层makefile调用,上层makefile决定子路径下makefie是否要被执行;子路径makfile控制代码是被编进内核还是被编译为ko。
以\linux-2.6.22.6\drivers\net\ixgb网卡驱动为例。
如果linux-2.6.22.6\drivers\net\Makefile中的CONFIG_IXGB被定义为y或m,则进入到ixgb路径执行ixgb路径下的Makefile。
#linux-2.6.22.6\drivers\net\Makefile
obj-$(CONFIG_IXGB) += ixgb/
linux-2.6.22.6\drivers\net\ixgb\Makefile根据CONFIG_IXGB被定义为y还是m,将该路径下ixgb_main.c ixgb_hw.c ixgb_ee.c ixgb_ethtool.c ixgb_param.c编译进内核还是编译成ixgb.ko
#linux-2.6.22.6\drivers\net\ixgb\Makefile
obj-$(CONFIG_IXGB) += ixgb.o
ixgb-objs := ixgb_main.o ixgb_hw.o ixgb_ee.o ixgb_ethtool.o ixgb_param.o
3- 架构相关makefile
架构相关makefile主要用于编译和架构相关代码。我们以linux-2.6.22.6\arch\arm\Makefile为例。
linux-2.6.22.6\arch\arm\Makefile被顶层\linux-2.6.22.6\Makefile包含.
#\linux-2.6.22.6\Makefile
include $(srctree)/arch/$(ARCH)/Makefile
4- 顶层makefile
顶层目录makefile是编译的入口,包含架构相关makefile、make menuconfig生成的auto.conf
#\linux-2.6.22.6\Makefile
include $(srctree)/arch/$(ARCH)/Makefile
include include/config/auto.conf
5- 以make uImage分析makefile
uImage定义在linux-2.6.22.6\arch\arm\Makefile
#linux-2.6.22.6\arch\arm\Makefile
zImage Image xipImage bootpImage uImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
uImage依赖vmlinux,vmlinux定义在顶层makefile。vmlinux的依赖第一个文件为连接脚本,之后为初始化代码、main、kallsyms文件。
#\linux-2.6.22.6\Makefile
all: vmlinux
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
kallsyms.o := .tmp_kallsyms$(last_kallsyms).o
继续分解vmlinux依赖的init、main文件。经过处理,以init-y为例,会将init路径下文件编译成init/built-in.o,其他文件类似。
#\linux-2.6.22.6\Makefile
init-y := $(patsubst %/, %/built-in.o, $(init-y))
core-y := $(patsubst %/, %/built-in.o, $(core-y))
drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
net-y := $(patsubst %/, %/built-in.o, $(net-y))
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)
#linux-2.6.22.6\arch\arm\Makefile
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
#\linux-2.6.22.6\Makefile
init-y := init/
core-y := usr/
libs-y := lib/
drivers-y := drivers/ sound/
net-y := net/
上述文件被链接脚本arch/$(ARCH)/kernel/vmlinux.lds连接成uImage文件,文件连接规则不去深究,直接使用make uImage v=1打印编译过程如下:
注意:先删除已经编出的vmlinux,否者无法显示编译完成过程!
# rm -rf vmlinux
# make uImage 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
可以看到连接脚本的连接顺序。
第一个文件为:arch/arm/kernel/head.o
链接脚本为:arch/$(ARCH)/kernel/vmlinux.lds
解析来分析内核代码从第一个文件head.o和链接脚本vmlinux.lds入手。