一. Makefile 配置

  1.1. make xxx_config

    1.1.1. 笔者实验时是make x210_sd_config

      a. x210_sd_config是Makefile下的一个目标

    1.2.1. x210_sd_config 相关代码分析

      a. @表示静默执行

      b. MKCONFIG是Makefile的一个变量,它所表示的是一个mkconfig脚本文件    

  1. MKCONFIG := $(SRCTREE)/mkconfig

      c. $(@:_config=)其结果是x210_sd,它来源于$(var:xx=yy)此句表示将变量var中以xx结尾的部分替换成yy。$@代表目标文件x210_sd_config.注意在$()的括号中的变量是不需要再加$的

      d. shell传参

        $1: x210_sd
        $2: arm
        $3: s5pc11x
        $4: x210
        $5: samsumg
        $6: s5pc110

        $# = 6

  1. x210_sd_config : unconfig
  2. @$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
  3. @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk

   

  1.2. mkconfig脚本分析

    1.2.1. 创建各种链接符号

      1.2.1.1. Create link to architecture specific headers

        a. 在include目录下创建asm文件,指向asm-arm。

  1. #
  2. # Create link to architecture specific headers
  3. #
  4. if [ "$SRCTREE" != "$OBJTREE" ] ; then
  5. mkdir -p ${OBJTREE}/include
  6. mkdir -p ${OBJTREE}/include2
  7. cd ${OBJTREE}/include2
  8. rm -f asm
  9. ln -s ${SRCTREE}/include/asm-$ asm
  10. LNPREFIX="../../include2/asm/"
  11. cd ../include
  12. rm -rf asm-$
  13. rm -f asm
  14. mkdir asm-$
  15. ln -s asm-$ asm
  16. else
  17. cd ./include
  18. rm -f asm
  19. ln -s asm-$ asm
  20. fi

      1.2.1.1. create link for s5pc11x SoC

        a. 在include目录下创建regs.h文件,指向include/s5pc110.h

        b. 在inlcude/asm-arm下创建一个arch文件,指向include/asm-arm/arch-s5pc11x

  1. # create link for s5pc11x SoC
  2. if [ "$3" = "s5pc11x" ] ; then
  3. rm -f regs.h
  4. ln -s $.h regs.h
  5. rm -f asm-$/arch
  6. ln -s arch-$ asm-$/arch
  7. fi

      1.2.1.2. proc文件链接

        a. 在include/asm-arm下创建一个proc文件,指向include/asm-arm/proc-armv

  1. if [ "$2" = "arm" ] ; then
  2. rm -f asm-$/proc
  3. ln -s ${LNPREFIX}proc-armv asm-$/proc
  4. fi

   

    1.2.2. 创建include/config.mk文件

      a. 编译的时候需要ARCH=arm、CPU=xx等这些变量来指导编译

  1. #
  2. # Create include file for Make
  3. #
  4. echo "ARCH = $2" > config.mk
  5. echo "CPU = $3" >> config.mk
  6. echo "BOARD = $4" >> config.mk
  7.  
  8. [ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
  9.  
  10. [ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk

    1.2.3. 创建config.h文件

      a. x210_sd.h文件会被用来生成一个config.mk文件,这个文件会被主Makefile引入,指导整个编译过程。这里面的这些宏定义会影响我们对uboot中大部分.c文件中一些条件编译的选择。从而实现最终的可移植性。

      b. #include <configs/x210_sd.h>里的宏用.c或.h里代码的选择,而mkconfig中创建的链接符号相当于文件的选择

  1. #
  2. # Create board specific header file
  3. #
  4. if [ "$APPEND" = "yes" ] # Append to existing config file
  5. then
  6. echo >> config.h
  7. else
  8. > config.h # Create new config file
  9. fi
  10. echo "/* Automatically generated - do not edit */" >>config.h
  11. echo "#include <configs/$1.h>" >>config.h

二. Makefile 分析

  2.1. 这部分主要和uboot软件版本相关

  1. VERSION =
  2. PATCHLEVEL =
  3. SUBLEVEL =
  4. EXTRAVERSION =
  5. U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
  6. VERSION_FILE = $(obj)include/version_autogenerated.h

  2.2. 这部分主要获取主机(用于开发的PC)的架构和OS

  1. HOSTARCH := $(shell uname -m | \
  2. sed -e s/i./i386/ \
  3. -e s/sun4u/sparc64/ \
  4. -e s/arm.*/arm/ \
  5. -e s/sa110/arm/ \
  6. -e s/powerpc/ppc/ \
  7. -e s/ppc64/ppc/ \
  8. -e s/macppc/ppc/)
  9.  
  10. HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
  11. sed -e 's/\(cygwin\).*/cygwin/')
  12.  
  13. export HOSTARCH HOSTOS

  2.3. 这部分注释说和静默编译有关,但我并不明白为什么有关,因为有没有他使用make -s都可以实现默编。

    PS:命令的回显

      makefile在执行命令的时候,通常会将命令显示在标准输出中,如果不想显示在标准输出中,可以使用下面的方法

        1.在每个命令的前面使用@字符串如下:

  1.  

          这样在执行命令的时候,就不会讲这个命令回显在标准输出中

        2.使用命令行参数

          在make执行的命令输入中,键入-s,–silent选项,既可,它表示所有的命令都不会回显在标准输出中。
        3.使用.SLIENT 
          给.SLIENT目标添加依赖,那么出现在依赖列表中的目标,重建的时候,将不会回显命令

  1. #########################################################################
  2. # Allow for silent builds
  3. ifeq (,$(findstring s,$(MAKEFLAGS)))
  4. XECHO = echo
  5. else
  6. XECHO = :
  7. endif
  8.  
  9. #########################################################################

  2.4. 两种编译方法  

    2.4.1. 原地编译

      a. 默认情况下是当前文件夹中的.c文件,编译出来的.o文件会放在同一文件夹下。这种方式叫原地编译。原地编译的好处就是处理起来简单。

      b. 原地编译有一些坏处:第一,污染了源文件目录。第二的缺陷就是一套源代码只能按照一种配置和编译方法进行处理,无法同时维护2个或2个以上的配置编译方式。

    2.4.2. 单独输出文件夹编译

      a. uboot支持单独输出文件夹方式的编译(linux kernel也支持,而且uboot的这种技术就是从linux kernel学习来的)。基本思路就是在编译时另外指定一个输出目录,将来所有的编译生成的.o文件或生成的其他文件全部丢到那个输出目录下去。源代码目录不做任何污染,这样输出目录就承载了本次配置编译的所有结果。

      b. 具体实现方法:

        如果需要指定具体的输出目录编译则有2种方式来指定输出目录。(具体参考Makefile 56-76行注释内容)
          第一种:make O=输出目录
          第二种:export BUILD_DIR=输出目录 然后再make
          如果两个都指定了(既有BUILD_DIR环境变量存在,又有O=xx),则O=xx具有更高优先级

    2.4.3. 实现代码如下:

      a. 代码中OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))意思是:如果“BUILD_DIR”变量值不为空,则将变量“BUILD_DIR”指定到OBJTREE,否则“CURDIR”指定到OBJTREE

  1. #########################################################################
  2. #
  3. # U-boot build supports producing a object files to the separate external
  4. # directory. Two use cases are supported:
  5. #
  6. # ) Add O= to the make command line
  7. # 'make O=/tmp/build all'
  8. #
  9. # ) Set environement variable BUILD_DIR to point to the desired location
  10. # 'export BUILD_DIR=/tmp/build'
  11. # 'make'
  12. #
  13. # The second approach can also be used with a MAKEALL script
  14. # 'export BUILD_DIR=/tmp/build'
  15. # './MAKEALL'
  16. #
  17. # Command line 'O=' setting overrides BUILD_DIR environent variable.
  18. #
  19. # When none of the above methods is used the local build is performed and
  20. # the object files are placed in the source directory.
  21. #
  22.  
  23. ifdef O
  24. ifeq ("$(origin O)", "command line")
  25. BUILD_DIR := $(O)
  26. endif
  27. endif
  28.  
  29. ifneq ($(BUILD_DIR),)
  30. saved-output := $(BUILD_DIR)
  31.  
  32. # Attempt to create a output directory.
  33. $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
  34.  
  35. # Verify if it was successful.
  36. BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
  37. $(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
  38. endif # ifneq ($(BUILD_DIR),)
  39.  
  40. OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
  41. SRCTREE := $(CURDIR)
  42. TOPDIR := $(SRCTREE)
  43. LNDIR := $(OBJTREE)
  44. export TOPDIR SRCTREE OBJTREE
  45.  
  46. MKCONFIG := $(SRCTREE)/mkconfig
  47. export MKCONFIG
  48.  
  49. ifneq ($(OBJTREE),$(SRCTREE))
  50. REMOTE_BUILD :=
  51. export REMOTE_BUILD
  52. endif
  53.  
  54. # $(obj) and (src) are defined in config.mk but here in main Makefile
  55. # we also need them before config.mk is included which is the case for
  56. # some targets like unconfig, clean, clobber, distclean, etc.
  57. ifneq ($(OBJTREE),$(SRCTREE))
  58. obj := $(OBJTREE)/
  59. src := $(SRCTREE)/
  60. else
  61. obj :=
  62. src :=
  63. endif
  64. export obj src
  65.  
  66. # Make sure CDPATH settings don't interfere
  67. unexport CDPATH

  2.5. 交叉编译链工具设置

    2.5.1. 判断config.mk是否存在

      a. 该文件是由make xxxx_config 配置时生成的

      b. ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))  

      c. 如果存在则进行后续的工具链配置

  1. ifeq ($(ARCH),powerpc)
  2. ARCH = ppc
  3. endif
  4.  
  5. ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
  6.  
  7. # load ARCH, BOARD, and CPU configuration
  8. include $(obj)include/config.mk
  9. export ARCH CPU BOARD VENDOR SOC
  10.  
  11. ifndef CROSS_COMPILE
  12. ifeq ($(HOSTARCH),$(ARCH))
  13. CROSS_COMPILE =
  14. else
  15. ifeq ($(ARCH),ppc)
  16. CROSS_COMPILE = ppc_8xx-
  17. endif
  18. ifeq ($(ARCH),arm)
  19. #CROSS_COMPILE = arm-linux-
  20. #CROSS_COMPILE = /usr/local/arm/4.4.-eabi-cortex-a8/usr/bin/arm-linux-
  21. #CROSS_COMPILE = /usr/local/arm/4.2.-eabi/usr/bin/arm-linux-
  22. CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
  23. endif
  24. ifeq ($(ARCH),i386)
  25. CROSS_COMPILE = i386-linux-
  26. endif
  27. ifeq ($(ARCH),mips)
  28. CROSS_COMPILE = mips_4KC-
  29. endif
  30. ifeq ($(ARCH),nios)
  31. CROSS_COMPILE = nios-elf-
  32. endif
  33. ifeq ($(ARCH),nios2)
  34. CROSS_COMPILE = nios2-elf-
  35. endif
  36. ifeq ($(ARCH),m68k)
  37. CROSS_COMPILE = m68k-elf-
  38. endif
  39. ifeq ($(ARCH),microblaze)
  40. CROSS_COMPILE = mb-
  41. endif
  42. ifeq ($(ARCH),blackfin)
  43. CROSS_COMPILE = bfin-uclinux-
  44. endif
  45. ifeq ($(ARCH),avr32)
  46. CROSS_COMPILE = avr32-linux-
  47. endif
  48. ifeq ($(ARCH),sh)
  49. CROSS_COMPILE = sh4-linux-
  50. endif
  51. ifeq ($(ARCH),sparc)
  52. CROSS_COMPILE = sparc-elf-
  53. endif # sparc
  54. endif # HOSTARCH,ARCH
  55. endif # CROSS_COMPILE
  56.  
  57. export CROSS_COMPILE

  2.5. OBJS和LIBS变量

    a. OBJS代表目标文件,本例中只会包含start.o。LIBS是库文件,主要包含以下文件夹lib_generic,cpu,fs,driver,commom等,下的一些.a库文件

  1. OBJS = cpu/$(CPU)/start.o
  2. ifeq ($(CPU),i386)
  3. OBJS += cpu/$(CPU)/start16.o
  4. OBJS += cpu/$(CPU)/reset.o
  5. endif
  6. ifeq ($(CPU),ppc4xx)
  7. OBJS += cpu/$(CPU)/resetvec.o
  8. endif
  9. ifeq ($(CPU),mpc85xx)
  10. OBJS += cpu/$(CPU)/resetvec.o
  11. endif
  12.  
  13. OBJS := $(addprefix $(obj),$(OBJS))
  14.  
  15. LIBS = lib_generic/libgeneric.a
  16. LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \
  17. "board/$(VENDOR)/common/lib$(VENDOR).a"; fi)
  18. LIBS += cpu/$(CPU)/lib$(CPU).a
  19. ifdef SOC
  20. LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
  21. endif
  22. ifeq ($(CPU),ixp)
  23. LIBS += cpu/ixp/npe/libnpe.a
  24. endif
  25. LIBS += lib_$(ARCH)/lib$(ARCH).a
  26. LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
  27. fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
  28. LIBS += net/libnet.a
  29. LIBS += disk/libdisk.a
  30. LIBS += drivers/bios_emulator/libatibiosemu.a
  31. LIBS += drivers/block/libblock.a
  32. LIBS += drivers/dma/libdma.a
  33. LIBS += drivers/hwmon/libhwmon.a
  34. LIBS += drivers/i2c/libi2c.a
  35. LIBS += drivers/input/libinput.a
  36. LIBS += drivers/misc/libmisc.a
  37. LIBS += drivers/mmc/libmmc.a
  38. LIBS += drivers/mtd/libmtd.a
  39. LIBS += drivers/mtd/nand/libnand.a
  40. LIBS += drivers/mtd/nand_legacy/libnand_legacy.a
  41. LIBS += drivers/mtd/onenand/libonenand.a
  42. LIBS += drivers/mtd/ubi/libubi.a
  43. LIBS += drivers/mtd/spi/libspi_flash.a
  44. LIBS += drivers/net/libnet.a
  45. LIBS += drivers/net/sk98lin/libsk98lin.a
  46. LIBS += drivers/pci/libpci.a
  47. LIBS += drivers/pcmcia/libpcmcia.a
  48. LIBS += drivers/spi/libspi.a
  49. ifeq ($(CPU),mpc83xx)
  50. LIBS += drivers/qe/qe.a
  51. endif
  52. ifeq ($(CPU),mpc85xx)
  53. LIBS += drivers/qe/qe.a
  54. endif
  55. LIBS += drivers/rtc/librtc.a
  56. LIBS += drivers/serial/libserial.a
  57. LIBS += drivers/usb/libusb.a
  58. LIBS += drivers/video/libvideo.a
  59. LIBS += common/libcommon.a
  60. LIBS += libfdt/libfdt.a
  61. LIBS += api/libapi.a
  62. LIBS += post/libpost.a
  63.  
  64. LIBS := $(addprefix $(obj),$(LIBS))
  65. .PHONY : $(LIBS) $(VERSION_FILE)
  66.  
  67. LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a
  68. LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
  69.  
  70. # Add GCC lib
  71. PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
  72.  
  73. # The "tools" are needed early, so put this first
  74. # Don't include stuff already done in $(LIBS)
  75. SUBDIRS = tools \
  76. examples \
  77. api_examples
  78.  
  79. .PHONY : $(SUBDIRS)
  80.  
  81. ifeq ($(CONFIG_NAND_U_BOOT),y)
  82. NAND_SPL = nand_spl
  83. U_BOOT_NAND = $(obj)u-boot-nand.bin
  84. endif
  85.  
  86. ifeq ($(CONFIG_ONENAND_U_BOOT),y)
  87. ONENAND_IPL = onenand_bl1
  88. U_BOOT_ONENAND = $(obj)u-boot-onenand.bin
  89. endif
  90.  
  91. __OBJS := $(subst $(obj),,$(OBJS))
  92. __LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))

  2.6. 其他的

    a. 其他的都是目标,这里不再分析了。

 

uboot 主Makefile分析的更多相关文章

  1. uboot主Makefile分析(t配置和编译过程详解)

    1.编译uboot前需要三次make make distcleanmake x210_sd_configmake -j4 make distclean为清楚dist文件. make x210_sd_c ...

  2. uboot主Makefile分析

    VERSION = 1 PATCHLEVEL = 3 SUBLEVEL = 4 EXTRAVERSION = U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(S ...

  3. uboot 主Makefile 分析。

    本文以uboot_1.1.6 对应的CPU是S3C2440 为例 uboot_1.1.6 根目录下的主Makefile开头: VERSION = PATCHLEVEL = SUBLEVEL = EXT ...

  4. uboot总结:uboot配置和启动过程1(主Makefile分析)

    说明:文件位置:在uboot的目录下,文件名为:Makefile 从文件的头部开始分析 1.24-29行,配置uboot的版本信息. VERSION = PATCHLEVEL = SUBLEVEL = ...

  5. TQ210 —— S5PV210 uboot顶层Makefile分析

    转自:http://blog.csdn.net/wqx521/article/details/52469759 # (C) Copyright 2000-2008 # Wolfgang Denk, D ...

  6. u-boot子目录Makefile分析

    一.概述 u-boot的子目录Makefile是整个Makefile体系的重要组成部分,决定了对应子目录的编译过程. 二.分析 以cpu/arm920t/Makefile为例进行说明 (1)首先,调用 ...

  7. u-boot顶层Makefile分析

    1.u-boot制作命令 make forlinx_nand_ram256_config: make all; 2.顶层mkconfig分析,参考 U-BOOT顶层目录mkconfig分析 mkcon ...

  8. uboot 顶层makefile细节分析

    uboot的源文件众多,学习庞然大物首先找到脊椎--顶层的makfile,逐一破解.但是,uboot的makefile同样是一个庞然大物,所以也要找到它的主线.倘若过分专注部分细节,很难做到把握全局, ...

  9. tiny210——uboot移植Makefile文章分析

    这东西已经写,我们没有时间发布,如今,终于有时间稍微长送记录汇总uboot学习过程.具体了.以后忘了也能够再温习回来嘛有些特殊字符显示得乱掉了 Makefile追踪技巧: 技巧1:能够先从编译目标開始 ...

随机推荐

  1. 【NOIP2017提高组模拟12.10】幻魔皇

    题目 幻魔皇拉比艾尔很喜欢斐波那契树,他想找到神奇的节点对. 所谓斐波那契树,根是一个白色节点,每个白色节点都有一个黑色节点儿子,而每个黑色节点则有一个白色和一个黑色节点儿子.神奇的节点对则是指白色节 ...

  2. 对前端Jenkins自动化部署的研究

    1. 安装 安装 Nginx 1.1去官网下直接下载,解压缩 start nginx就可以使了,常用命令: start nginx # 启动 nginx -s reload # 修改配置后重新加载生效 ...

  3. 10.django的一些方法理解

    django get_object_or_404 get_object_or_404是django的django shortcuts的方法,用来查询数据,或者抛出一个DoesNotExist的异常 用 ...

  4. C#之扩展方法 default(T)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. 【javascript】生成二维码

    1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 < ...

  6. luogu 4725 【模板】多项式对数函数(多项式 ln)

    $G(x)=ln(A(x))$ $G'(x)=ln'(A(x))A'(x)=\frac{A'(x)}{A(x)}$     由于求导和积分是互逆的,所以对 $G$ 求积分,即 $G(x)=\int\f ...

  7. 设置获取data-*属性值

    html代码如下: <div id="getId" data-id="122" data-vice-id="11">获取id&l ...

  8. 人脸三维建模A Morphable Model For The Synthesis Of 3D Faces(三维人脸合成的变形模型)

    Abstract摘要 In this paper, a new technique for modeling textured 3D faces is introduced. 3D faces can ...

  9. 数据科学20个最好的Python库

    Python 在解决数据科学任务和挑战方面继续处于领先地位.去年,我们曾发表一篇博客文章 Top 15 Python Libraries for Data Science in 2017,概述了当时业 ...

  10. Linux安装配置redis 、启动redis、redis设置密码

    由于间隔时间较长.机器的环境不同等等原因,所以每次安装redis的时候总是不那么顺利,所以这次我要做个笔记 文章大部分内容源于https://blog.csdn.net/gisredevelopmen ...