文章目录
- 一、分析make <board_name>_defconfig执行过程
- (一)
- 1. 1. 分析Makefile文件,分析Makefile文件的规则中目标为"<board_name>_defconfig",
- (二)
- (三)
- 二、分析make menuconfig执行过程
- 三、以GPIO驱动为例分析如何通过图形化界面方式实现驱动的编译
- (一)GPIO的驱动在u-boot源码的drivers/gpio目录下
- (二)打开drivers/gpio目录下的Makefile文件,找到以下内容
- 四、make all执行过程详解
- (一)通过执行make V=1 all命令,获取make all执行过程的详解介绍
- 五、
一、分析make <board_name>_defconfig执行过程
(一)
1. 1. 分析Makefile文件,分析Makefile文件的规则中目标为"<board_name>_defconfig",
打开u-boot源码目录下的Makefile,搜索“%config”字符串,得到以下结果
563 %config: scripts_basic outputmakefile FORCE
echo $(Q)
echo $(MAKE)
echo $(build)
564 $(Q)$(MAKE) $(build)=scripts/kconfig $@
解析以上命令:
$@ : 目标
$^ : 所有的依赖
$< : 第一个依赖
Q = @ ---> 取消命令在终端的回显
MAKE = make ---> make命令
build = -f ./scripts/Makefile.build obj
以下命令展开之后的结果:
@make -f ./scripts/Makefile.build obj=scripts/kconfig stm32mp15_trusted_defconfig
解析以上命令的含义:
make ---> 执行make命令
-f ./scripts/Makefile.build ---> 使用file文件作为Makefile文件
obj=scripts/kconfig ---> 执行make命令时,给obj变量赋值
stm32mp15_trusted_defconfig ---> make命令对应的目标
-
打开u-boot源码目录下的./scripts/Makefile.build,查找“config”目标,
没有找到对应的目标,通过include包含了其它目录下的Makefile文件,得到以下信息
55 kbuild-dir := $(if ( f i l t e r / (filter /%, (filter/(src)), ( s r c ) , (src), (src),(srctree)/$(src))
56 kbuild-file := $(if $(wildcard ( k b u i l d − d i r ) / K b u i l d ) , (kbuild-dir)/Kbuild), (kbuild−dir)/Kbuild),(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
57 include $(kbuild-file)以上命令展开之后的结果:include scripts/kconfig/Makefile
-
打开u-boot源码中的scripts/kconfig/Makefile文件,搜索“%_defconfig”字符串,
得到以下结果:
109 %_defconfig: $(obj)/conf
110 ( Q ) (Q) (Q)< ( s i l e n t ) − − d e f c o n f i g = a r c h / (silent) --defconfig=arch/ (silent)−−defconfig=arch/(SRCARCH)/configs/$@ $(Kconfig)解析以上命令,将命令前边的$(Q)删除,然后重新执行make stm32mp15_trusted_defconfig
命令,然后查看终端回显的结果,如下所示:
scripts/kconfig/conf --defconfig=arch/…/configs/stm32mp15_trusted_defconfig Kconfig解析以上命令:
scripts/kconfig/conf —> 使用file命令查看conf文件可知conf是一个
—> ELF格式的可执行文件。
—> conf程序通过命令行传参的方式,使用argc和argv获取对应的参数
–defconfig=arch/…/configs/stm32mp15_trusted_defconfig
—> config可执行程序的第一个参数
—> arch/…/configs/目录下存放的是板子的默认的配置文件
Kconfig
—> config可执行程序的第二个参数
—> u-boot源码目录下的Kconfig文件以上命令最终执行的效果:
conf程序解析arch/…/configs/目录下stm32mp15_trusted_defconfig
和u-boot源码目录下的Kconfig文件,最终在u-boot源码目录下生成.config配置文件,
.config文件给Makefile文件使用,Makefile文件根据.config文件中的信息最终
决定了u-boot源码中的哪些文件被编译,哪些文件不被编译。
- 注:
- file命令可以查看文件性质
(二)
(三)
二、分析make menuconfig执行过程
-
分析Makefile文件,分析Makefile文件的规则中目标为"menuconfig",
打开u-boot源码目录下的Makefile,搜索“%config”字符串,得到以下结果
563 %config: scripts_basic outputmakefile FORCE
echo $(Q)
echo $(MAKE)
echo $(build)
564 ( Q ) (Q) (Q)(MAKE) $(build)=scripts/kconfig $@解析以上命令:
$@ : 目标
$^ : 所有的依赖
$< : 第一个依赖Q = @ —> 取消命令在终端的回显
MAKE = make —> make命令
build = -f ./scripts/Makefile.build obj以下命令展开之后的结果:
@make -f ./scripts/Makefile.build obj=scripts/kconfig menuconfig解析以上命令的含义:
make —> 执行make命令
-f ./scripts/Makefile.build —> 使用file文件作为Makefile文件
obj=scripts/kconfig —> 执行make命令时,给obj变量赋值
menuconfig —> make命令对应的目标 -
打开u-boot源码目录下的./scripts/Makefile.build,查找“menuconfig”目标,
没有找到对应的目标,通过include包含了其它目录下的Makefile文件,得到以下信息
55 kbuild-dir := $(if ( f i l t e r / (filter /%, (filter/(src)), ( s r c ) , (src), (src),(srctree)/$(src))
56 kbuild-file := $(if $(wildcard ( k b u i l d − d i r ) / K b u i l d ) , (kbuild-dir)/Kbuild), (kbuild−dir)/Kbuild),(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
57 include $(kbuild-file)以上命令展开之后的结果:include scripts/kconfig/Makefile
-
打开u-boot源码中的scripts/kconfig/Makefile文件,搜索“menuconfig”字符串,
得到以下结果:
34 menuconfig: $(obj)/mconf
35 $< $(silent) $(Kconfig)以上命令展开之后的结果为,执行make menuconfig命令
scripts/kconfig/mconf Kconfig解析以上命令的作用:
scripts/kconfig/mconf —> 使用file命令查看mconf程序的属性可知,
—> mconf是一个ELF格式的可执行文件,
Kconfig —> mconf可执行程序的第一个参数
—> u-boot源码目录下的Kconfig文件mconf程序解析Kconfig文件中的信息,最终调用图形化界面的库, 生成图形化的配置界面。
-
打开u-boot源码目录下的Kconfig文件,解析Kconfig文件中的信息。
主菜单:类似于windows软件的菜单栏
可以包含子菜单和菜单选项
菜单:类似于windows软件中子菜单
可以包含下一级的菜单或菜单选项
菜单选项:菜单选项只能被选择或者不选择4.1 mainmenu 关键字
作用:修饰主菜单
格式:mainmenu “主菜单的名字”4.2 menu…endmenu 关键字
作用:修饰菜单
格式:
menu “菜单的名字”
// 1. 可以包含下一级的菜单
// 2. 包含一个菜单选项
endmenu4.3 bool 关键字
作用:修饰菜单选项,修饰的菜单选项有两种状态[*]或[ ]
格式:
bool “菜单选项的名字”4.4 default 关键字
作用:对应的菜单选项的默认的状态
格式:default y|n4.5 help关键字
作用:修饰帮助信息
格式:
help
帮助信息的字符串可以通过:shift + ? 获取菜单选项对应的帮助信息。
4.6 config关键字
作用:修饰配置选项的
格式:
config 配置选项的名字
|—> 1. 一般配置选项的名字的每个字符都要大写
|—> 2. 多个单词之间使用“_”隔开当config修饰的配置选项对应的菜单选项配置为[*]时,
此时“CONFIG_配置选项的名字 = y” 被写到.config文件中当config修饰的配置选项对应的菜单选项配置为[ ]时,
此时“# CONFIG_配置选项的名字 is not set” 被写到.config文件中因此通过make menuconfig进行图形化界面配置时,最终修改的是.config文件中的配置信息。
.config文件中的信息给Makefile文件使用,Makefile文件根据.config文件中的信息,
决定u-boot中的源码哪些被编译,哪些不被编译。Makefile文件编译u-boot的伪代码:
u-boot.stm32:u-boot.bin
u-boot.bin:u-boot.elf
objcopy -O binary u-boot.elf u-boot.binu-boot.elf:$(obj-y)
ld 命令,将.o文件链接生成.elf文件obj-y += 1.o
obj- ( C O N F I G ∗ ∗ ∗ ∗ ) + = ∗ ∗ ∗ ∗ 2. o o b j − (CONFIG_****) += ****2.o obj- (CONFIG∗∗∗∗)+=∗∗∗∗2.oobj−(CONFIG_) += 3.o
…
obj-$(CONFIG_) += ****n.o
|—> CONFIG对应的变量在.config文件中定义。.o:.c
gcc -c ****.c -o ****.o4.8 source关键字
作用:包含下一级目录下的Kconfig文件
格式:
source “Kconfig文件名及对应的路径”
三、以GPIO驱动为例分析如何通过图形化界面方式实现驱动的编译
(一)GPIO的驱动在u-boot源码的drivers/gpio目录下
(二)打开drivers/gpio目录下的Makefile文件,找到以下内容
1》GPIO的驱动在u-boot源码的drivers/gpio目录下
stm32_gpio.c
2》打开drivers/gpio目录下的Makefile文件,找到以下内容
54 obj-$(CONFIG_STM32_GPIO) += stm32_gpio.o
|---> 这个变量在.config文件中进行定义
|---> 如果这个变量被定义为y,则stm32_gpio.c就会被编译
3》打开drivers/gpio/目录下的Kconfig文件,得到以下内容
5 menu "GPIO Support"
......
359 config STM32_GPIO
360 bool "ST STM32 GPIO driver"
361 depends on DM_GPIO && (ARCH_STM32 || ARCH_STM32MP)
362 default y
363 help
364 Device model driver support for STM32 GPIO controller. It should be
365 usable on many stm32 families like stm32f4/f7/h7 and stm32mp1.
366 Tested on STM32F7.
......
498 endmenu
4》打开drivers/目录下的Kconfig文件,得到以下内容
1 menu “Device Drivers”
45 source “drivers/gpio/Kconfig”
151 endmenu
5》打开u-boot源码目录下的Kconfig文件,得到以下内容
476 source "drivers/Kconfig"
6》配置GPIO驱动对应的菜单选项配置为[*]或[ ] ,然后查看.config文件中的信息
Device Drivers ---->
GPIO Support ---->
[*] ST STM32 GPIO driver
|---> 配置为[*]或者[ ] 然后查看.config中CONFIG_STM32_GPIO变量定义
四、make all执行过程详解
(一)通过执行make V=1 all命令,获取make all执行过程的详解介绍
ld命令将各个目录下的.o文件先链接生成build-in.o文件
|
arm-linux-gnueabihf-ld.bfd -Ttext 0xC0100000 -o u-boot -T u-boot.lds
arch/arm/cpu/armv7/start.o --whole-archive arch/arm/cpu/built-in.o
arch/arm/cpu/armv7/built-in.o arch/arm/lib/built-in.o
arch/arm/mach-stm32mp/built-in.o board/st/common/built-in.o
board/st/stm32mp1/built-in.o cmd/built-in.o common/built-in.o
disk/built-in.o drivers/built-in.o drivers/dma/built-in.o
drivers/gpio/built-in.o drivers/i2c/built-in.o drivers/net/built-in.o
drivers/net/phy/built-in.o drivers/power/built-in.o
drivers/power/battery/built-in.o drivers/power/domain/built-in.o
drivers/power/fuel_gauge/built-in.o drivers/power/mfd/built-in.o
drivers/power/pmic/built-in.o drivers/power/regulator/built-in.o
drivers/serial/built-in.o drivers/spi/built-in.o
drivers/usb/cdns3/built-in.o drivers/usb/common/built-in.o
drivers/usb/dwc3/built-in.o drivers/usb/emul/built-in.o
drivers/usb/eth/built-in.o drivers/usb/gadget/built-in.o
drivers/usb/gadget/udc/built-in.o drivers/usb/host/built-in.o
drivers/usb/mtu3/built-in.o drivers/usb/musb-new/built-in.o
drivers/usb/musb/built-in.o drivers/usb/phy/built-in.o
drivers/usb/ulpi/built-in.o env/built-in.o fs/built-in.o
lib/built-in.o net/built-in.o --no-whole-archive
arch/arm/lib/eabi_compat.o arch/arm/lib/lib.a -Map u-boot.map; true
将各个目录下的build-in.o文件链接生成u-boot文件
|
arm-linux-gnueabihf-objcopy -O binary u-boot u-boot-nodtb.bin
objcopy命令格式化拷贝将u-boot(ELF格式文件)格式化拷贝生成u-boot-nodtb.bin
|
make -f ./scripts/Makefile.build obj=dts dtbs
make -f ./scripts/Makefile.build obj=arch/arm/dts dtbs
编译设备树文件,得到dts/dt.dtb
|
cat u-boot-nodtb.bin dts/dt.dtb > u-boot-dtb.bin
将dts/dt.dtb文件追加到u-boot-nodtb.bin文件结尾,得到u-boot-dtb.bin文件
|
cp u-boot-dtb.bin u-boot.bin
|
./tools/mkimage -T stm32image -a 0xC0100000 -e 0xC0100000 -d u-boot.bin u-boot.stm32 > u-boot.stm32.log && cat u-boot.stm32.log
mkimage : 可以通过man mkimage获取命令的帮助信息,生成镜像文件
-T stm32image :设置镜像文件的类型
-a 0xC0100000 :设置加载地址
-e 0xC0100000 :设置程序入口地址
-d u-boot.bin :镜像对应的数据文件
u-boot.stm32 :mkimage命令给u-boot.bin文件添加对应的数据头,得到u-boot.stm32镜像文件
u-boot.stm32.log :将mkimage命令执行的输出结果重定向到u-boot.stm32.log
&& cat u-boot.stm32.log :将u-boot.stm32.log 文件中的内容在终端进行回显。