1. 程式人生 > 其它 >linux kernel makefile 分析 - 8

linux kernel makefile 分析 - 8

 

上一篇: https://www.cnblogs.com/zhangzhiwei122/p/16029589.html

背景說明

版本:

5.10.0 - 下面分析中 使用的行號,都是 參考 這個 版本的 Makefile 。

線上瀏覽: https://lxr.missinglinkelectronics.com/linux/Makefile

 

使用場景:

根據  https://www.cnblogs.com/zhangzhiwei122/p/16029312.html 中的分析,在make vmlinux 之前一定需要先  make xxconfig 生成一個 .config 檔案,

所以 從 第7篇  開始的場景 定義為如下:

在原始碼資料夾下面建立一個build 資料夾,然後使用 O=build 

mkdir build

# 生成 .config 檔案

make  ARCH=arm64  CROSS_COMPILE=aarch64-linux-gnu-  O=build   defconfig  

# 使用 .config 檔案 編譯 預設目標 __all -> all -> vmlinux

make  ARCH=arm64  CROSS_COMPILE=aarch64-linux-gnu-  O=build

 

descend & build-dirs & prepare

1176  vmlinux-deps 依賴 descend

1176$(sort $(vmlinux-deps) $(subdir-modorder)): descend ;

 

descend 依賴 build-dirs ;      build-dirs 依賴prepare

1802PHONY += descend $(build-dirs)
1803descend: $(build-dirs)
1804$(build-dirs): prepare
1805        $(Q)$(MAKE) $(build)=$@ \
1806        single-build=$(if $(filter-out $@/, $(filter $@/%, $(KBUILD_SINGLE_TARGETS))),1
) \ 1807 need-builtin=1 need-modorder=1

 

build-dirs 的內容和生成

648 ~ 653 定義了 core-y  drivers-y libs-y 

1105 又對 core-y 進行了補充

1107 行,將所有的 core-y  core-m  drivers-y drivers-m libs-y libs-m 中的,以 / 結尾的 (即目錄) 都 找出來,然後去掉 末尾的 / 符號,放到 vmlinux-dirs 裡面

1119 行,將 vmlinux-dirs  賦值給  build-dirs 。裡面 是  需要編譯 的 頂級資料夾名稱(不帶 / )

build-dirs= init  usr  drivers sound net  virt  lib kernel  certs  mm  fs  ipc  security  crypto   block    arch/arm64      arch/arm64/lib 

648# Objects we will link into vmlinux / subdirs we need to visit
 649core-y          := init/ usr/
 650drivers-y       := drivers/ sound/
 651drivers-$(CONFIG_SAMPLES) += samples/
 652drivers-y       += net/ virt/
 653libs-y          := lib/

1105core-y          += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/
1106
1107vmlinux-dirs    := $(patsubst %/,%,$(filter %/, \
1108                     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
1109                     $(libs-y) $(libs-m)))



1119build-dirs      := $(vmlinux-dirs)

 

build-dirs 生成規則

1804$(build-dirs): prepare
1805        $(Q)$(MAKE) $(build)=$@ \
1806        single-build=$(if $(filter-out $@/, $(filter $@/%, $(KBUILD_SINGLE_TARGETS))),1) \
1807        need-builtin=1 need-modorder=1

合併後為:

$(Q)$(MAKE) $(build)=$@ single-build=$(if $(filter-out $@/, $(filter $@/%, $(KBUILD_SINGLE_TARGETS))),1) need-builtin=1 need-modorder=1

舉例:

make $(build)=init  single-build=    need-builtin=1    need-modorder=1

關於 $(build)=xx  來編譯一個子目錄裡面內容  的用法,可以參考

https://blog.csdn.net/lgjjeff/article/details/90511225

 

build-dirs  裡面的目標完成,頂級 目錄資料夾下面的  built-in.o  lib.a 就都生成好了。可以連結進入  vmlinux 裡面了。

 

build-dirs 依賴 的prepare 生成

prepare 依賴 prepare0    prepare-objtools     prepare-resolve_btfids

1204  prepare0 依賴 archprepare ,

1205  prepare0 的生成規則,即使用 $(build)= 來編譯   script/mod 目錄和  ./  目錄

1200 裡面列出了 archprepare 依賴的子目標,這些子目標 大多 都可以直接找到 其 生成規則。不再詳細分析。

 

1199
1200archprepare: outputmakefile archheaders archscripts scripts include/config/kernel.release \
1201        asm-generic $(version_h) $(autoksyms_h) include/generated/utsrelease.h \
1202        include/generated/autoconf.h
1203
1204prepare0: archprepare
1205        $(Q)$(MAKE) $(build)=scripts/mod
1206        $(Q)$(MAKE) $(build)=.
1207
1208# All the preparing..
1209prepare: prepare0 prepare-objtool prepare-resolve_btfids

 

prepare-objtool

1080 ~ 1087  如果 CONFIG_STACK_VALIDATION  即需要 棧校驗  ,才有  objtool_target (為  tools/objtool 這個工具)

1080ifdef CONFIG_STACK_VALIDATION
1081  ifeq ($(has_libelf),1)
1082    objtool_target := tools/objtool FORCE
1083  else
1084    SKIP_STACK_VALIDATION := 1
1085    export SKIP_STACK_VALIDATION
1086  endif
1087endif

如果打開了  CONFIG_STACK_VALIDATION ,但是主機上面又沒有  libelf , 這是 prepare-objtool 才有 生成動作,生成動作也即是 報錯 Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev

1223prepare-objtool: $(objtool_target)
1224ifeq ($(SKIP_STACK_VALIDATION),1)
1225ifdef CONFIG_UNWINDER_ORC
1226        @echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
1227        @false
1228else
1229        @echo "warning: Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
1230endif
1231endif

prepare-resolve_btfids

這個和 上面的 prepare-objtool 類似。只是配置 變為  CONFIG_DEBUG_INFO_BTF

1089ifdef CONFIG_BPF
1090ifdef CONFIG_DEBUG_INFO_BTF
1091  ifeq ($(has_libelf),1)
1092    resolve_btfids_target := tools/bpf/resolve_btfids FORCE
1093  else
1094    ERROR_RESOLVE_BTFIDS := 1
1095  endif
1096endif # CONFIG_DEBUG_INFO_BTF
1097endif # CONFIG_BPF

如果打開了 CONFIG_BPF && CONFIG_DEBUG_INFO_BTF ,但是主機上面又沒有  libelf , 這是 prepare-resolve_btfids 才有 生成動作,動作即是報錯 resolve BTF IDs for CONFIG_DEBUG_INFO_BTF, please install libelf-dev  

1233prepare-resolve_btfids: $(resolve_btfids_target)
1234ifeq ($(ERROR_RESOLVE_BTFIDS),1)
1235        @echo "error: Cannot resolve BTF IDs for CONFIG_DEBUG_INFO_BTF, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
1236        @false
1237endif