ARM Uboot经历——makefile与uboot目录

时间:2022-08-27 04:45:43

makefile是个很复杂的东西,但是只要有耐心层层剥下,也能看到你想看到的东西。很遗憾的事,很多人都没有耐心去层层看,我也是。

对于makefile,我也仅仅从基础上了解了它在uboot中的原理和作用,其实你不一定要完全了解,但是你又不能完全不了解,这就是这个世界的矛盾。

makefile 第一步

最开始当然要看顶层目录下的makefile文件,当你执行make命令是就是默认这个makefile。一般在最开始,你需要告诉makefile你要生成哪种uboot,命令如下:

[cpp]  view plain copy
  1. make *****_config  
****就是你单板的名字。当你执行这个指令后,它的结果就是生成一个.config文件,具体形成的语句对应为:

[cpp]  view plain copy
  1. %_config::  unconfig  
  2.     @$(MKCONFIG) -A $(@:_config=)  
unconfig又定义为

[cpp]  view plain copy
  1. unconfig:  
  2.     @rm -f $(obj)include/config.h $(obj)include/config.mk \  
  3.         $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \  
  4.         $(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep  
变量MKCONFIG定义为

[cpp]  view plain copy
  1. MKCONFIG    := $(SRCTREE)/mkconfig  
通常SRCTREE就是空目录,因此就是根目录下的mkconfig文件。

而@:_config=表示将你输入的******_config替换为******,也就是将后面的去掉,因此命令实际上就成了

[cpp]  view plain copy
  1. $(SRCTREE)/mkconfig -A ******  

mkconfig的作用

有很多文章写mkconfig的过程,我就不乱讲了,我也讲不太清楚,或者只能简单讲清楚。

简单来说,mkconfig会根据你输入的参数,比如-A , ******(单板号)去查询根目录下的boards.cfg文件,这个文件很关键,比如内容如下:

[cpp]  view plain copy
  1. # Target                     ARCH        CPU         Board name          Vendor         SoC         Options  
  2. ###########################################################################################################  
  3.   
  4. integratorcp_cm1136          arm         arm1136     integrator          armltd         -           integratorcp:CM1136  
  5. imx31_phycore                arm         arm1136     -                   -              mx31  
  6. imx31_phycore_eet            arm         arm1136     imx31_phycore       -              mx31         imx31_phycore:IMX31_PHYCORE_EET  
  7. qong                         arm         arm1136     -                   davedenx       mx31  
  8. mx31ads                      arm         arm1136     -                   freescale      mx31  
  9. mx31pdk                      arm         arm1136     -                   freescale      mx31         mx31pdk:NAND_U_BOOT  
  10. tt01                         arm         arm1136     -                   hale           mx31  
  11. imx31_litekit                arm         arm1136     -                   logicpd        mx31  
  12. flea3                        arm         arm1136     -                   CarMediaLab    mx35  
  13. mx35pdk                      arm         arm1136     -                   freescale      mx35  
它会列举一些用得到的单板的名字,以及各种属性。

比如以tt01为例,当你输入make tt01_config的时候,mkconfig就会在borad.cfg里面找到这一行。

找到这一行之后,它的所有属性就出来了,比如你的ARCH=arm,CPU=arm1136等等,这些属性都会被mkconfig收集起来写入两个文件中,这两个文件就叫做include/config.mk和include/config.h

mkconfig中生成include/config.mk如下:

[cpp]  view plain copy
  1.  1 ARCH   = arm                                                                  
  2.   2 CPU    = arm1136  
  3.   3 BOARD  = tt01  
  4.   4 VENDOR = hale  
  5.   5 SOC    = mx31  
而生成的config.h文件如下:

[cpp]  view plain copy
  1. /* Automatically generated - do not edit */                                   
  2.   2 #define CONFIG_SYS_ARCH  "arm"  
  3.   3 #define CONFIG_SYS_CPU   "arm1136"  
  4.   4 #define CONFIG_SYS_BOARD "tt01"  
  5.   5 #define CONFIG_SYS_VENDOR "hale"  
  6.   6 #define CONFIG_SYS_SOC    "mx31"  
  7.   7 #define CONFIG_BOARDDIR board/hale/tt01  
  8.   8 #include <config_cmd_defaults.h>  
  9.   9 #include <config_defaults.h>  
  10.  10 #include <configs/tt01.h>  
  11.  11 #include <asm/config.h>  
  12.  12 #include <config_fallbacks.h>  
  13.  13 #include <config_uncmd_spl.h>  

make的第二步

当make的第一步完成后,第二步就更简单了,直接输入make命令,然后就会按照你的预订配置编译了。

虽然操作简单了,但是实现过程更复杂了,如果要简单的说,那就是会执行All下面的所有操作

[cpp]  view plain copy
  1. all:        $(ALL-y) $(SUBDIR_EXAMPLES)  
  2.   
  3.   
  4. $(obj)u-boot.dtb:   $(obj)u-boot  
  5.         $(MAKE) -C dts binary  
  6.         mv $(obj)dts/dt.dtb $@  
  7.   
  8.   
  9. $(obj)u-boot-dtb.bin:   $(obj)u-boot.bin $(obj)u-boot.dtb  
  10.         cat $^ >$@  
  11.   
  12.   
  13. $(obj)u-boot.hex:   $(obj)u-boot  
  14.         $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@  
  15.   
  16.   
  17. $(obj)u-boot.srec:  $(obj)u-boot  
  18.         $(OBJCOPY) -O srec $< $@  
  19.   
  20.   
  21. $(obj)u-boot.bin:   $(obj)u-boot  
  22.         $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@  
  23.         $(BOARD_SIZE_CHECK)  
  24.   
  25.   
  26. $(obj)u-boot.ldr:   $(obj)u-boot  
  27.         $(CREATE_LDR_ENV)  
  28.         $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)  
  29.         $(BOARD_SIZE_CHECK)  
  30.   
  31.   
  32. $(obj)u-boot.ldr.hex:   $(obj)u-boot.ldr  
  33.         $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary  
  34.   
  35.   
  36. $(obj)u-boot.ldr.srec:  $(obj)u-boot.ldr  
  37.         $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary  


我这里没有列全,但是的确是从这里开始运行,直至生成所有应该生成的文件。


makefile与uboot目录的关系

uboot的目录是非常庞大的,包含各种单板各种架构,如何得知哪个架构,进入哪个目录编译,这是makefile必须清楚地。反而言之,用户如果要新增文件,应该怎么增加,应该如何修改makefile,也需要了解。

makefile的参数非常关键,也就是上面介绍的boards.cfg里面的参数。

ARCH=type,对应的源目录为 arch/arm

CPU=arm1136,对应的源目录为arch/arm/arm/cpu1136

SOC=mx31,对应的源目录为arch/arm/arm/cpu1136/mx32

这里对应了三个最关键的源目录路径,在arch/arm目录下有arm公有的东西,比如初始化之类的。在arch/arm/cpu/***目录下就是每个cpu自己的东西了,用户可以将cpu特定的一些函数写在这个目录下。arch/arm/arm/cpu1136/mx32就是当前Soc的特殊函数了,比如定时器,DDR初始化之类的。

VENDOR=hale,对应的头文件目录为board\hale,这里面定义了这个公司的所有头文件。

BOARD=tt01,对应的头文件目录为board\hale\tt01,这里面定义了这个单板的所有头文件。

综上所述,基本和单板相关的文件定义结构就清楚了,但是其他的一些定义,比如flash,net之类的,这些有公共部分,也有私有部分,这个与makefile就关系不大了,这部分以后再详述。