嵌入式linux之頂層makefile解析
內(nèi)核頂層目錄make過程
簡易描述一下整個編譯過程
執(zhí)行make XXX_defconfige,最終目的會生成.config,.config里面回有很多配置項,
主要用來選擇架構(gòu)和加入哪些模塊進(jìn)行編譯
執(zhí)行make
首先,主要目標(biāo)先生成vmlinux,在利用vmlinux生成Image ,zImage 、uImage等鏡像燒寫文件
all: vmlinux
依賴項vmlinux
繼續(xù)研究vmlinux
vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE
依賴項scripts/link-vmlinux.sh和vmlinux-deps
先說一下vmlinux-deps
vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT)$(KBUILD_VMLINUX_MAIN)
依次解開得:
KBUILD_VMLINUX_INIT= $(head-y) $(init-y)
KBUILD_VMLINUX_MAIN = $(core-y) $(libs-y) $(drivers-y) $(net-y)
KBUILD_LDS= arch/arm/kernel/vmlinux.lds
繼續(xù)深入解開可得:
head-y = arch/arm/kernel/head.o
init-y ?= init/built-in.o
drivers-y = drivers/built-in.o sound/built-in.o firmware/built-in.o
net-y ?= net/built-in.o
libs-y = arch/arm/lib/lib.a lib/lib.a arch/arm/lib/built-in.o lib/built-in.o
????????????core-y = usr/built-in.o arch/arm/vfp/built-in.o
????????????arch/arm/vdso/built-in.o arch/arm/kernel/built-in.o
????????????arch/arm/mm/built-in.o arch/arm/common/built-in.o
????????????arch/arm/probes/built-in.o ?arch/arm/net/built-in.o
????????????arch/arm/crypto/built-in.o arch/arm/firmware/built-in.o
????????????arch/arm/mach-imx/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
最終可得:
vmlinux-deps = ?arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o
????????????????????????????init/built-in.o usr/built-in.o
????????????????????????????arch/arm/vfp/built-in.o arch/arm/vdso/built-in.o
????????????????????????????arch/arm/kernel/built-in.o arch/arm/mm/built-in.o
????????????????????????????arch/arm/common/built-in.o arch/arm/probes/built-in.o
????????????????????????????arch/arm/net/built-in.o arch/arm/crypto/built-in.o
????????????????????????????arch/arm/firmware/built-in.o arch/arm/mach-imx/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 firmware/built-in.o
????????????????????????????net/built-in.o
在各個目錄下面獲取built-in.o文件,其實還有些生成了.a,然后利用arch/arm/kernel/vmlinux.lds和scripts/link-vmlinux.sh 這個腳本來鏈接出 vmlinux打包生成vmlinux
那么這些built-in.o是如何生成得呢
頂層makefile中有如下代碼:
$(sort $(vmlinux-deps)): $(vmlinux-dirs) ;
意思是把vmlinux-deps按照字母排序,也就是把上面得built-in.o 得目錄進(jìn)行排序,而這些built-in.o得依賴項是 $(vmlinux-dirs)
追蹤代碼可得
vmlinux-dirs ? ?:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
? ? ? ? ? ? ?$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
? ? ? ? ? ? ?$(net-y) $(net-m) $(libs-y) $(libs-m) $(virt-y)))
解開可得
vmlinux-dirs = init usr arch/arm/vfp
????????????????????????arch/arm/vdso arch/arm/kernel arch/arm/mm
????????????????????????arch/arm/common arch/arm/probes arch/arm/net
????????????????????????arch/arm/crypto arch/arm/firmware arch/arm/mach-imx
????????????????????????kernel mm fs
????????????????????????ipc security crypto
????????????????????????block drivers sound
????????????????????????firmware net arch/arm/lib
????????????????????????lib
另外還有
$(vmlinux-dirs): prepare scripts
? ? $(Q)$(MAKE) $(build)=$@
上下得目標(biāo)進(jìn)行合并,最后通過 $(Q)$(MAKE) $(build)=$@這條命令來生成vmlinux-dirs所敞開得這些目錄里面得built-in.o
分析命令
$(Q)$(MAKE) $(build)=$@
命令敞開
@ make -f ./scripts/Makefile.build obj=$@
根據(jù)目標(biāo)繼續(xù)敞開
@ make -f ./scripts/Makefile.build obj=init
@ make -f ./scripts/Makefile.build obj=usr
@ make -f ./scripts/Makefile.build obj=arch/arm/vfp
@ make -f ./scripts/Makefile.build obj=arch/arm/vdso
@ make -f ./scripts/Makefile.build obj=arch/arm/kernel
@ make -f ./scripts/Makefile.build obj=arch/arm/mm
@ make -f ./scripts/Makefile.build obj=arch/arm/common
@ make -f ./scripts/Makefile.build obj=arch/arm/probes
@ make -f ./scripts/Makefile.build obj=arch/arm/net
@ make -f ./scripts/Makefile.build obj=arch/arm/crypto
@ make -f ./scripts/Makefile.build obj=arch/arm/firmware
@ make -f ./scripts/Makefile.build obj=arch/arm/mach-imx
@ make -f ./scripts/Makefile.build obj=kernel
@ make -f ./scripts/Makefile.build obj=mm
@ make -f ./scripts/Makefile.build obj=fs
@ make -f ./scripts/Makefile.build obj=ipc
@ make -f ./scripts/Makefile.build obj=security
@ make -f ./scripts/Makefile.build obj=crypto
@ make -f ./scripts/Makefile.build obj=block
@ make -f ./scripts/Makefile.build obj=drivers
@ make -f ./scripts/Makefile.build obj=sound
@ make -f ./scripts/Makefile.build obj=firmware
@ make -f ./scripts/Makefile.build obj=net
@ make -f ./scripts/Makefile.build obj=arch/arm/lib
@ make -f ./scripts/Makefile.build obj=lib
直接說一下結(jié)果,這條命令得意思就是說make 到每個obj所指向得目錄里面去編譯/scripts/Makefile,而scripts/Makefile會把
每個目錄里面得makefile給include進(jìn)去,而每個目錄里面得makefile會把目錄下面得所有文件用如下得形式進(jìn)行一個定義,例如
obj-$(CONFIG_GPIO_MOXART) ? += gpio-moxart.o
obj-$(CONFIG_GPIO_MPC5200) ?+= gpio-mpc5200.o
obj-$(CONFIG_GPIO_MPC8XXX) ?+= gpio-mpc8xxx.o
obj-$(CONFIG_GPIO_MSIC) ? ? += gpio-msic.o
obj-$(CONFIG_GPIO_MVEBU) ? ? ? ?+= gpio-mvebu.o
obj-$(CONFIG_GPIO_MXC) ? ? ?+= gpio-mxc.o
obj-$(CONFIG_GPIO_MXS) ? ? ?+= gpio-mxs.o
obj-$(CONFIG_GPIO_OCTEONy) ? += gpio-octeon.o
其中$()里面得配置項就行.config里面得定義選項,當(dāng)被復(fù)制成y得時候,就相當(dāng)于是obj-y,這時候模塊會被加入編譯
例如obj-$(CONFIG_GPIO_MXC) ? ? ?+= gpio-mxc.o,CONFIG_GPIO_MXC被定義成y,則
obj-y ? ? ?+= gpio-mxc.o,對應(yīng)得gpio-mxc.o會被加入編譯,最終生成built-in.o
然后頂層目錄在去把這些built-in.o 鏈接成vmlinux
后面得鏡像文件Image ,zImage 、uImage都是用vmlinux生成得
頂層makefile 代碼如下
BOOT_TARGETS = zImage Image xipImage bootpImage uImage
$(BOOT_TARGETS): vmlinux ? ?目標(biāo):依賴項
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
解開命令得
@ make -f ./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/boot/zImage
@ make -f ./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/boot/Image
@ make -f ./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/boot/xipImage
@ make -f ./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/boot/bootpImage
@ make -f ./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/boot/uImage
也是利用./scripts/Makefile.build這個腳本去鏈接生成