1. 文章说明
- 内核版本号为:4.11.4,针对x86平台,存不存在.config文件无所谓。
- 需要读者有基础Makefile知识
- 分析输入make firmware_install命令时的情形,只分析主要流程,其它的像变量赋值等部分只分析会影响流程执行的内容。
- 不会讲解Makefile文件中出现的函数,如果不懂,可以bing。
2. 主Makefile流程分析
目标firmware_install定义在源码根目录下Makefile中的line 1120行
1119 PHONY += firmware_install
1120 firmware_install:
1121 @mkdir -p $(objtree)/firmware
1122 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_install
由于只输入了make firmware_install,因此KBUILD_SRC为空,会解析line 118 ~ line 158的语句。
这部分中,line 137 ~ line 157的语句无效。原因是编译时只输入了make firmware,导致line 122行条件为假,因此KBUILD_OUTPUT为空值,line 137行的语句为假,所以line 137 ~ line 157的语句无效。因此,line 156行的skip-makefile为空值,因此line 161行的条件为真,所以line 161 ~ line 1698的语句有效。
srctree的值定义于源码根目录Makefile的line 205 ~ line 215,因为KBUILD_SRC的值为空,因此line 207 srctree的值为“.”。
变量objtree赋值的位置在同一Makefile中的下列行
216 objtree := .
综上所述,目标firmware_install形式如下:
1119 PHONY += firmware_install
1120 firmware_install:
1121 @mkdir -p ./firmware
1122 $(Q)$(MAKE) -f ./scripts/Makefile.fwinst obj=firmware __fw_install
主Makefile L1121行的命令是创建文件夹,L1122行是生成文件./scripts/Makefile中的目标__fw_install。
3. __fw_install生成过程分析
./scripts/Makefile中有如下内容
50 __fw_install: $(installed-fw)
43 $(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/%
44 $(call cmd,install)
40 quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@)
41 cmd_install = mkdir -p $(@D); $(INSTALL) -m0644 $< $@
38 installed-fw := $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-all))
其中line 43行 $(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/%
使用了Makefile规则中的静态模式,而obj的值是由源码根目录下主Makefile中的下述>行指定的
1122 $(Q)$(MAKE) -f ./scripts/Makefile.fwinst obj=firmware __fw_install
即是在目标firmware_install的生成命令中调用make时以类似于传参的方式指定的。
3.1 INSTALL_FW_PATH的来源
INSTALL_FW_PATH定义于源码根目录下的主Makefile中的下列行
1116 INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib/firmware
1117 export INSTALL_FW_PATH
对于INSTALL_MOD_PATH,源码根目录下主Makefile中有如下说明
845 # Like INSTALL_MOD_PATH, it isn't defined in the Makefile, but can be passed as
846 # an argument if needed. Otherwise it defaults to the kernel install path
当输入make firmware_install命令时的,未指定INSTALL_MOD_PATH,所以其值为空,则INSTALL_FW_PATH值如下
1116 INSTALL_FW_PATH=/lib/firmware
3.2 fw-shipped-all的来源
文件scripts/Makefile.fwinst中有如下内容
9 src := $(obj)
16 include $(src)/Makefile
obj的值在前面介绍过了,是“firmware”,所以scripts/Makefile.fwinst文件的16行内容如下
16 include firmware/Makefile
而fw-shipped-all定义于文件firmware/Makefile的如下行
139 fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-)
而$(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-)定义于文件firmware/Makefile中,同时文件中也定义了它们的生成命令及目标规则,例如
212 $(obj)/%.fw: $(obj)/%.HEX $(ihex2fw_dep)
213 $(call cmd,ihex2fw)
144 quiet_cmd_ihex2fw = IHEX2FW $@
145 cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@
146
由于内容较多但比较简单,这里就不一一列举了。
综上所述,文件./scripts/Makefile中目标__fw_install生成规则如下
50 __fw_install: $(installed-fw)
43 $(installed-fw): /lib/firmware/%: $(obj)/%
44 $(call cmd,install)
40 quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@)
41 cmd_install = mkdir -p $(@D); $(INSTALL) -m0644 $< $@
38 installed-fw := $(addprefix /lib/firmware/,$(fw-shipped-all))