内核启动流程分析(三)makefile
目錄
- Linux內核Makefile作用
- Linux內核Makefile文件分類
- Makefile解析
- 子目錄的Makefile
- 架構下面的Makefile
- 頂層Makefile
- Make解析
- 總結
Linux內核Makefile作用
Linux內核Makefile文件分類
Makefile解析
詳細的解釋可以看/Documentation/kbuild/makefiles.txt
子目錄的Makefile
子目錄的makefile形式簡單,諸如下:
obj-$(CONFIG_DM9000) += dm9dev9000c.o然后?CONFIG_DM9000是在auto.conf中定義,他是由.config中定義為y(內核文件)或者m(編譯為.ko模塊),所以也就是形如
obj-y += xxx.o obj-m += xxx.o 如果沒有被定義則是 obj - +=xxx.o 不被處理架構下面的Makefile
arch/arm/Makefile我們執行命令make uImage并不在頂層的makefile,而是在架構下面的makefile,所以它一定會被頂層的makefile包含
zImage Image xipImage bootpImage uImage: vmlinux$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@頂層Makefile
搜索下arch,在頂層的Makefile中找到包含了架構下的Makefile
include $(srctree)/arch/$(ARCH)/Makefile export KBUILD_DEFCONFIG可以繼續搜發現同時定義了arm架構,這是在補丁文件修改的
#ARCH ?= $(SUBARCH) ARCH ?= arm CROSS_COMPILE ?= arm-linux-同時搜索下.config文件生成的auto.conf,也在頂層包含
ifeq ($(dot-config),1) # Read in config -include include/config/auto.confMake解析
總結:最終在各個目錄下生成built-in.o,根據arch/$(ARCH)/kernel/vmlinux.lds的鏈接腳本鏈接
uiamge依賴于vmlinux,uImage實際就是頭部信息加上一個真正的內核,也就是vmlinux就是真正的內核
zImage Image xipImage bootpImage uImage: vmlinux$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@可以發現在頂層makefile存在以下,也就是說這也是默認的目標文件
all: vmlinux繼續搜索目標vmlinux的依賴
# 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其中相關變量繼續搜索如下
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/$(ARCH)/kernel/vmlinux.lds # vmlinux-lds:鏈接腳本。 # vmlinux-init:一些初始化代碼。 # vmlinux-main:一些主要的代碼(與內核核心相關的)。vmlinux-init
#頂層 /makefile init-y := init/ init-y := $(patsubst %/, %/built-in.o, $(init-y)) # 相當于 init-y = init/built-in.o#架構 arch/arm/makefile head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o #這里MMUEXT 并沒有被定義,也就是最終就是 arch/arm/kernel/head.o arch/arm/kernel/init_task.opatsubst分析
格式:$(patsubst <pattern>,<replacement>,<text> ) 名稱:模式字符串替換函數——patsubst。 功能:查找<text>中的單詞(單詞以“空格”、“Tab”或“回車”“換行”分隔)是否符合模式<pattern>,如果匹配的話,則以<replacement>替換。- pattern=%/在這里應該是匹配所有的意思
- replacement=%/built-in.o
- text=init/
也就是說在init/下的所有文件名都被替換為+built-in.o,視頻講的是最后會被編譯為built-in.o,也就是相當于init-y = init/built-in.o
vmlinux-main
core-y?內核
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y) # core-y core-y := usr/ core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ core-y := $(patsubst %/, %/built-in.o, $(core-y))這里也用到了patsubst替換,也就是將上述目錄下的文件編譯為built-in.o,最終相當于
core-y = usr/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.olibs-y?庫
libs-y := lib/ # 在lib/中查找 替換為lib.a libs-y1 := $(patsubst %/, %/lib.a, $(libs-y)) # 在lib/中查找 替換為built-in.o libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y)) # 最終生成 built-in.o 和 lib.a libs-y := $(libs-y1) $(libs-y2)同樣的,也就是在最終生成built-in.o和 替換為lib.a
drivers-y?驅動
drivers-y := drivers/ sound/ #(依賴了這兩個目錄) drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))同樣的,也就是在最終生成built-in.o
net-y?網絡
net-y := net/ net-y := $(patsubst %/, %/built-in.o, $(net-y))同樣的替換,生成built-in.o
總結
從以上分析makefile可以兩大結果:第一個文件和鏈接腳本,以后分析內核流程可以根據第一個文件順藤摸瓜一路跟蹤下去,鏈接腳本決定了內核里的各個段是如何分布的,而每個段的文件順序就是上面文件順序。
總結
以上是生活随笔為你收集整理的内核启动流程分析(三)makefile的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内核启动流程分析(二)配置详解
- 下一篇: 内核启动流程分析(四)源码浅析