GNU ARM汇编--(十七)u-boot的makefile和mkconfig解读

发布者:DreamBig123最新更新时间:2015-10-14 来源: eefocus关键字:ARM汇编  u-boot  makefile  mkconfig 手机看文章 扫描二维码
随时随地手机看文章
       自己写的bootloader可以引导kernel了,我以为曾经神秘的u-boot代码将变得毫无挑战,然事实表明u-boot作为优秀的开源代码,阅读起来还是很有挑战的,值得一读!

        阅读碰到的头等问题:Makefile和shell脚本看不懂...

        说起来做linux也很久了,Makefile和shell脚本都接触过,但真的都是略懂而已.因为公司的Makefile和shell简单的一眼望的对穿,很初级的写法,简单的应用.再随便在网上下个老外的开源代码,那个Makefile和shell复杂啊.一不留神想起来了qt的qmake根据工程文件生成的Makefile也是很简单,但qmake是人家老外写的.不说其他语言了,只看Makefile和shell,中外的差距就在那了.

        这次准备移植u-boot到tq2440上,选用的u-boot版本是u-boot-2012.07.

        下面是我对u-boot配置和编译的makefile mkconfig config.mk等文件的解读,有些解读我是在源档上添加文字注释的,有些是另外写的,解读难免有误,若有读者发现了,希望能够指出,在下感激不尽!

        在编译u-boot的过程,就是make xxx_config和make两步

        以make smdk2410_config为例:

        当以smdk2410_config为目标时,makefile中前面一些变量的定义和其他文件的引用也是有的,这个在原档中添加了有关注释:

        在makefile中有:

        

[cpp] view plaincopy
 
  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  
  5.   
  6. %_config::  unconfig  
  7.     echo $@  
  8.     $(MKCONFIG) -A $(@:_config=)  

 

        %是个通配符,make xxx_config都是这个目标.目标的依赖是unconfig,unconfig的命令是删除一些文件,而这些文件正是从make xxx_config过程中产生的.unconfig就是清理配置的.

        我们来看@$(MKCONFIG) -A $(@:_config=)
        其实执行的是mkconfig -A smdk2410
        我们可以在该行上面添加一行:echo $@
        则会输出smdk2410_config,因为$@就是指目标
        $(@:_config=)是变量的替换引用
        格式为“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是:替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。
所以smdk2410_config末尾的_config去除了.

        下面就是执行mkconfig脚本了,mkconfig -A smdk2410

        给出添加注释的mkconfig文件:

 

[cpp] view plaincopy
 
  1. #!/bin/sh -e  
  2.   
  3. # Script to create header files and links to configure  
  4. # U-Boot for a specific board.  
  5. #  
  6. # Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]  
  7. #  
  8. # (C) 2002-2010 DENX Software Engineering, Wolfgang Denk   
  9. #  
  10.   
  11. APPEND=no   # Default: Create new config file  
  12. BOARD_NAME=""   # Name to print in make output  
  13. TARGETS=""  
  14.   
  15. arch=""  
  16. cpu=""  
  17. board=""  
  18. vendor=""  
  19. soc=""  
  20. options=""  
  21.   
  22. echo $#  
  23. if [ $# -eq 2 -a ( "$1" = "-A" ) ] ; then  
  24.     # Automatic mode  
  25.     line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {  
  26.         echo "make: *** No rule to make target `$2_config'.  Stop." >&2  
  27.         exit 1  
  28.     }  
  29.   
  30.     set ${line}  
  31.     echo ${line}  
  32.     echo $#  
  33.     # add default board name if needed  
  34.     [ $# = 3 ] && set ${line} ${1}  
  35. #####################################  
  36. #我们执行脚本的命令是mkconfig -A smdk2410,$#表示的是参数的个数,$1表示的是第一个参数  
  37. #line 就是在boards.cfg文件中smdk2410的那行,而-i表示忽略大小写  
  38. #在boards.cfg文件中,有  
  39. #Target                     ARCH        CPU         Board name          Vendor          SoC         Options  
  40. #smdk2410                     arm         arm920t     -                   samsung        s3c24x0  
  41. #  set ${line}  
  42. #  set也可用于在脚本内部给出其运行参数,所以这个时候参数就变为"smdk2410 arm arm920t - samsung s3c24x0"  
  43. #这个时候参数个数就变成6个了  
  44. ######################################  
  45. elif [ "${MAKEFLAGS+set}${MAKELEVEL+set}" = "setset" ] ; then  
  46.     # only warn when using a config target in the Makefile  
  47.     cat <<-EOF  
  48.   
  49.     warning: Please migrate to boards.cfg.  Failure to do so will  
  50.              mean removal of your board in the next release.  
  51.   
  52.     EOF  
  53.     sleep 5  
  54. fi  
  55.   
  56. echo $1  
  57. while [ $# -gt 0 ] ; do  
  58.     case "$1" in  
  59.     --) shift ; break ;;  
  60.     -a) shift ; APPEND=yes ;;  
  61.     -n) shift ; BOARD_NAME="${1%_config}" ; shift ;;  
  62.     -t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;  
  63.     *)  break ;;  
  64.     esac  
  65. done  
  66. ################################################  
  67. #因为$1的值为smdk2410,所以case找不到对应的  
  68. #################################################  
  69.   
  70. [ $# -lt 4 ] && exit 1  
  71. [ $# -gt 7 ] && exit 1  
  72. ##################################################  
  73. #对参数个数做检查,小于4个或大于7个就退出  
  74. ##################################################  
  75.   
  76. # Strip all options and/or _config suffixes  
  77. CONFIG_NAME="${1%_config}"  
  78. ####################  
  79. #CONFIG_NAME的值为smdk2410  
  80. #########################  
  81. echo config_  
  82. echo ${CONFIG_NAME}  
  83.   
  84. [ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"  
  85. echo board  
  86. echo ${BOARD_NAME}  
  87. ###########################################  
  88. #如果BOARD_NAME在之前已经被设定了,就不做任何动作;如果为空,就设定为smdk2410.这里设定为smdk2410  
  89. ############################################  
  90.   
  91. arch="$2"  
  92. cpu="$3"  
  93. if [ "$4" = "-" ] ; then  
  94.     board=${BOARD_NAME}  
  95. else  
  96.     board="$4"  
  97. fi  
  98. ######################################################  
  99. #设定arch变量的值为arm  
  100. #cpu变量的值为arm920t  
  101. #因为第四个变量为"-",所以board变量的值为smdk2410  
  102. #######################################################  
  103.   
  104.   
  105. [ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"  
  106. [ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"  
  107. #############################################################  
  108. #设定verdor变量的值为samsung  
  109. #设定soc变量的值为s3c24x0  
  110. #############################################################  
  111. [ $# -gt 6 ] && [ "$7" != "-" ] && {  
  112.     # check if we have a board config name in the options field  
  113.     # the options field mave have a board config name and a list  
  114.     # of options, both separated by a colon (':'); the options are  
  115.     # separated by commas (',').  
  116.     #  
  117.     # Check for board name  
  118.     tmp="${7%:*}"  
  119.     if [ "$tmp" ] ; then  
  120.         CONFIG_NAME="$tmp"  
  121.     fi  
  122.     # Check if we only have a colon...  
  123.     if [ "${tmp}" != "$7" ] ; then  
  124.         options=${7#*:}  
  125.         TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}"  
  126.     fi  
  127. }  
  128. #################################################  
  129. #因为我们的变量个数就是6个,这一段不执行  
  130. #################################################  
  131. echo ${ARCH}  
  132. echo ${arch}  
  133. if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then  
  134.     echo "Failed: $ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2  
  135.     exit 1  
  136. fi  
  137. ####################################################  
  138. #ARCH是在顶层makefile中定义的,在此刻还是为空的。  
  139. #如果ARCH已经有值了,那么就检测ARCH和arch是否匹配了.  
  140. ####################################################  
  141.   
  142. if [ "$options" ] ; then  
  143.     echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"  
  144. else  
  145.     echo "Configuring for ${BOARD_NAME} board..."  
  146. fi  
  147. ###########################################################################  
  148. #我们没有定义options变量,所以输出Configuring for smdk2410 board...  
  149. ###########################################################################  
  150.   
  151.   
  152. #  
  153. # Create link to architecture specific headers  
  154. #  
  155. echo ${SRCTREE}  
  156. echo ${OBJTREE}  
  157. if [ "$SRCTREE" != "$OBJTREE" ] ; then  
  158.     mkdir -p ${OBJTREE}/include  
  159.     mkdir -p ${OBJTREE}/include2  
  160.     cd ${OBJTREE}/include2  
  161.     rm -f asm  
  162.     ln -s ${SRCTREE}/arch/${arch}/include/asm asm  
  163.     LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/  
  164.     cd ../include  
  165.     mkdir -p asm  
  166. else  
  167.     cd ./include  
  168.     rm -f asm  
  169.     ln -s ../arch/${arch}/include/asm asm  
  170. fi  
  171. #############################################################################  
  172. #在makefile中我们已经知道SRCTREE和OBJTREE都是当前目录,所以这里执行else  
  173. #进入./include目录,删除asm链接,并重新建立链接asm,指向arch/arm/include/asm  
  174. #############################################################################  
  175.   
  176. rm -f asm/arch  
  177. #########################################################################  
  178. #删除include目录下的asm下的arch链接文件  
  179. ########################################################################  
  180.   
  181. ss=  
  182. echo ${ss}  
  183. if [ -z "${ss}" ] ; then  
  184.     echo "null"  
  185. else  
  186.     echo "not null"  
  187. fi  
  188.   
  189. echo ${LNPREFIX}  
  190. if [ -z "${soc}" ] ; then  
  191.     ln -s ${LNPREFIX}arch-${cpu} asm/arch  
  192. else  
  193.     ln -s ${LNPREFIX}arch-${soc} asm/arch  
  194. fi  
  195. ##########################################################  
  196. #-z用来检测字符串是否为空,为空返回真  
  197. #这里我们的soc不为空,执行else  
  198. #将asm/arch链向arch-s3c24x0,看一下arch-s3c24x0目录,里面都是s3c24x0相关的头文件  
  199. ##########################################################  
  200.   
  201. if [ "${arch}" = "arm" ] ; then  
  202.     rm -f asm/proc  
  203.     ln -s ${LNPREFIX}proc-armv asm/proc  
  204. fi  
  205. ###########################################################  
  206. #删除asm/proc链接文件  
  207. #将asm/proc链向proc-armv目录,该目录下是四个头文件:domain.hprocessor.hptrace.hsystem.h  
  208. #############################################################  
  209.   
  210. #  
  211. # Create include file for Make  
  212. #  
  213. echo "ARCH   = ${arch}"  >  config.mk  
  214. echo "CPU    = ${cpu}"   >> config.mk  
  215. echo "BOARD  = ${board}" >> config.mk  
  216.   
  217. [ "${vendor}" ] && echo "VENDOR = ${vendor}" >> config.mk  
  218.   
  219. [ "${soc}"    ] && echo "SOC    = ${soc}"    >> config.mk  
  220. ######################################################################  
  221. #上面几句的作用在注释中描述的很清楚  
  222. #include/config.mk的文件如下:  
  223. #ARCH   = arm  
  224. #CPU    = arm920t  
  225. #BOARD  = smdk2410  
  226. #VENDOR = samsung  
  227. #SOC    = s3c24x0  
  228. ######################################################################  
  229.   
  230. # Assign board directory to BOARDIR variable  
  231. if [ -z "${vendor}" ] ; then  
  232.     BOARDDIR=${board}  
  233. else  
  234.     BOARDDIR=${vendor}/${board}  
  235. fi  
  236. echo ${BOARDDIR}  
  237. #######################################################################  
  238. #因为vendor变量不为空,所以执行else  
  239. #BOARDDIR的值为samsung/s3c24x0  
  240. ########################################################################  
  241. #  
  242. # Create board specific header file  
  243. #  
  244. if [ "$APPEND" = "yes" ]    # Append to existing config file  
  245. then  
  246.     echo >> config.h  
  247. else  
  248.     > config.h       # Create new config file  
  249. fi  
  250. ########################################################################  
  251. #在文件的最开头可以看到APPEND为no,所以这里我们在include文件夹下建立config.h文件  
  252. #######################################################################  
  253. echo "/* Automatically generated - do not edit */" >>config.h  
  254.   
  255. echo ${TARGETS}  
  256. for i in ${TARGETS} ; do  
  257.     i="`echo ${i} | sed '/=/ {s/=/  /;q; } ; { s/$/ 1/; }'`"  
  258.     echo "#define CONFIG_${i}" >>config.h ;  
  259. done  
  260. ###################################################  
  261. #这里我们TARGETS为空,上面不执行了  
  262. ##################################################  
  263.   
  264. echo "#define CONFIG_SYS_ARCH  "${arch}""  >> config.h  
  265. echo "#define CONFIG_SYS_CPU   "${cpu}""   >> config.h  
  266. echo "#define CONFIG_SYS_BOARD "${board}"" >> config.h  
  267.   
  268. [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR "${vendor}"" >> config.h  
  269.   
  270. [ "${soc}"    ] && echo "#define CONFIG_SYS_SOC    "${soc}""    >> config.h  
  271.   
  272. cat << EOF >> config.h  
  273. #define CONFIG_BOARDDIR board/$BOARDDIR  
  274. #include   
  275. #include   
  276. #include   
  277. #include   
  278. #include   
  279. EOF  
  280. ######################################################  
  281. #生成config.h文件如下:  
  282. #   /* Automatically generated - do not edit */  
  283. #   #define CONFIG_SYS_ARCH  "arm"  
  284. #   #define CONFIG_SYS_CPU   "arm920t"  
  285. #   #define CONFIG_SYS_BOARD "smdk2410"  
  286. #   #define CONFIG_SYS_VENDOR "samsung"  
  287. #   #define CONFIG_SYS_SOC    "s3c24x0"  
  288. #   #define CONFIG_BOARDDIR board/samsung/smdk2410  
  289. #   #include   
  290. #   #include   
  291. #   #include   
  292. #   #include   
  293. #   #include   
  294. #####################################################  
  295. exit 0  
        

 

        make xxx_config后,主要的变化是多了几个文件:

        1.include/asm    -->     arch/arm/include/arm

        2.include/asm/arch  -->  arch-s3c24x0

        3.include/asm/proc  -->  proc-armv
        4.在include目录下新建了config.mk文件,文件内容是ARCH CPU BOARD VENDOR SOC的定义

        5.在include目录下新建了config.h文件

 

        接着看make:

        给出部分makefile中的注释,主要是一些变量的定义:

[page]

[cpp] view plaincopy
 
  1. VERSION = 2012  
  2. PATCHLEVEL = 07  
  3. SUBLEVEL =  
  4. EXTRAVERSION =  
  5. ifneq "$(SUBLEVEL)" ""  
  6. U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)  
  7. else  
  8. U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL)$(EXTRAVERSION)  
  9. endif  
  10. ################################  
  11. #定义U_BOOT_VERSION为2012.07  
  12. #####################################  
  13.   
  14.   
  15. TIMESTAMP_FILE = $(obj)include/generated/timestamp_autogenerated.h  
  16. VERSION_FILE = $(obj)include/generated/version_autogenerated.h  
  17. ###############################  
  18. #因为obj为空,所以定义TIMESTAMP_FILE为include/generated/timestamp_autogenerated.h  
  19. #定义VERSION_FILE为include/generated/version_autogenerated.h  
  20. #****************  
  21.   
  22. HOSTARCH := $(shell uname -m |   
  23.     sed -e s/i.86/x86/   
  24.         -e s/sun4u/sparc64/   
  25.         -e s/arm.*/arm/   
  26.         -e s/sa110/arm/   
  27.         -e s/ppc64/powerpc/   
  28.         -e s/ppc/powerpc/   
  29.         -e s/macppc/powerpc/  
  30.         -e s/sh.*/sh/)  
  31.   
  32. HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' |   
  33.         sed -e 's/.*/cygwin/')  
  34.   
  35. # Set shell to bash if possible, otherwise fall back to sh  
  36. SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH;   
  37.     else if [ -x /bin/bash ]; then echo /bin/bash;   
  38.     else echo sh; fi; fi)  
  39.   
  40. export  HOSTARCH HOSTOS SHELL  
  41. #########################  
  42. #HOSTARCH为i686,HOSTOS为linux,SHELL为/bin/sh  
  43. #############################  
  44.   
  45. # Deal with colliding definitions from tcsh etc.  
  46. VENDOR=  
  47.   
  48. #########################################################################  
  49. # Allow for silent builds  
  50. ifeq (,$(findstring s,$(MAKEFLAGS)))  
  51. XECHO = echo  
  52. else  
  53. XECHO = :  
  54. endif  
  55. ###########################  
  56. #因为MAKEFLAGS变量的字符串为空,找不到s,所以ifeq为真,XECHO = echo  
  57. ###########################  
  58.   
  59.   
  60. #########################################################################  
  61. #  
  62. # U-boot build supports producing a object files to the separate external  
  63. # directory. Two use cases are supported:  
  64. #  
  65. # 1) Add O= to the make command line  
  66. # 'make O=/tmp/build all'  
  67. #  
  68. # 2) Set environement variable BUILD_DIR to point to the desired location  
  69. # 'export BUILD_DIR=/tmp/build'  
  70. # 'make'  
  71. #  
  72. # The second approach can also be used with a MAKEALL script  
  73. # 'export BUILD_DIR=/tmp/build'  
  74. # './MAKEALL'  
  75. #  
  76. # Command line 'O=' setting overrides BUILD_DIR environent variable.  
  77. #  
  78. # When none of the above methods is used the local build is performed and  
  79. # the object files are placed in the source directory.  
  80. #  
  81.   
  82. ifdef O  
  83. ifeq ("$(origin O)", "command line")  
  84. BUILD_DIR := $(O)  
  85. endif  
  86. endif  
  87. #################################  
  88. #如果没有在make命令行中定义O=/tmp之类的,那么BUILD_DIR就为/tmp,否则为空。  
  89. #当使用make O=/tmp时,表明#ifdef O有定义,而$(origin O)返回的就是"command line"  
  90. #################################  
  91.   
  92. ifneq ($(BUILD_DIR),)  
  93. saved-output := $(BUILD_DIR)  
  94.   
  95. # Attempt to create a output directory.  
  96. $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})  
  97.   
  98. # Verify if it was successful.  
  99. BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)  
  100. $(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))  
  101. endif # ifneq ($(BUILD_DIR),)  
  102. #################################  
  103. #如果BUILD_DIR不为空,那么这几句就执行:  
  104. #首先,saved-output变量也是BUILD_DIR的值  
  105. #如果BUILD_DIR不存在,那么就创建BUILD_DIR目录  
  106. #检测BUILD_DIR目录是否成功建好了,如果有问题就输出错误信息  
  107. #################################  
  108.   
  109.   
  110. OBJTREE     := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))  
  111. SPLTREE     := $(OBJTREE)/spl  
  112. SRCTREE     := $(CURDIR)  
  113. TOPDIR      := $(SRCTREE)  
  114. LNDIR       := $(OBJTREE)  
  115. export  TOPDIR SRCTREE OBJTREE SPLTREE  
  116. ###########################################  
  117. #如果BUILD_DIR有值,那么OBJTREE就是BUILD_DIR的值,如果BUILD_DIR为空,那么OBJTREE就是CURDIR的值,$(CURDIR)时GNU Make内嵌的变量,是当前目录。  
  118. #我们在make时候不加O=/tmp之类的参数,所以OBJTREE就是当前工作目录,SPLTREE是当前工作目录下的spl目录,SRCTREE时当前工作目录,TOPDIR也是当前目录,LNDIR也是当前目录。  
  119. ##########################################  
  120.   
  121. MKCONFIG    := $(SRCTREE)/mkconfig  
  122. export MKCONFIG  
  123. #############################################  
  124. #MKCONFIG定义为当前工作目录下的mkconfig脚本,并export  
  125. #############################################  
  126.   
  127. ifneq ($(OBJTREE),$(SRCTREE))  
  128. REMOTE_BUILD    := 1  
  129. export REMOTE_BUILD  
  130. endif  
  131. ####################################################################  
  132. #在我们的执行中,OBJTREE和SRCTREE是相等的,所以不管了  
  133. ###################################################################  
  134.   
  135. # $(obj) and (src) are defined in config.mk but here in main Makefile  
  136. # we also need them before config.mk is included which is the case for  
  137. # some targets like unconfig, clean, clobber, distclean, etc.  
  138. ifneq ($(OBJTREE),$(SRCTREE))  
  139. obj := $(OBJTREE)/  
  140. src := $(SRCTREE)/  
  141. else  
  142. obj :=  
  143. src :=  
  144. endif  
  145. export obj src  
  146. #######################################  
  147. #可以先看下上面的注释   因为两个路径相同,所以执行else  
  148. #########################################  
  149.   
  150. # Make sure CDPATH settings don't interfere  
  151. unexport CDPATH  
  152.   
  153. #########################################################################  
  154.   
  155. # The "tools" are needed early, so put this first  
  156. # Don't include stuff already done in $(LIBS)  
  157. # The "examples" conditionally depend on U-Boot (say, when USE_PRIVATE_LIBGCC  
  158. # is "yes"), so compile examples after U-Boot is compiled.  
  159. SUBDIR_TOOLS = tools  
  160. SUBDIR_EXAMPLES = examples/standalone examples/api  
  161. SUBDIRS = $(SUBDIR_TOOLS)  
  162. ###############################################  
  163. #定义SUBDIR_TOOLS SUBDIR_EXAMPLES 和 SUBDIRS  
  164. ###############################################  
  165.   
  166. .PHONY : $(SUBDIRS) $(VERSION_FILE) $(TIMESTAMP_FILE)  
  167. ########################  
  168. #定义几个伪目标  
  169. ########################  
  170.   
  171. ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))  
  172.   
  173. # Include autoconf.mk before config.mk so that the config options are available  
  174. # to all top level build files.  We need the dummy all: target to prevent the  
  175. # dependency target in autoconf.mk.dep from being the default.  
  176. all:  
  177. sinclude $(obj)include/autoconf.mk.dep  
  178. sinclude $(obj)include/autoconf.mk  
  179. ###################################################################################  
  180. #包含auoconf.mk和autoconf.mk.dep文件  
  181. ###################################################################################  
  182. ifndef CONFIG_SANDBOX  
  183. SUBDIRS += $(SUBDIR_EXAMPLES)  
  184. endif  
  185. ###################################  
  186. #追加SUBDIRS 为"tools  examples/standalone examples/api"  
  187. ###################################  
  188.   
  189. # load ARCH, BOARD, and CPU configuration  
  190. include $(obj)include/config.mk  
  191. export  ARCH CPU BOARD VENDOR SOC  
  192. #######################################  
  193. #包含include/config.mk文件,这个文件是在make xxx_config过程中产生的  
  194. #######################################  
  195.   
  196. # set default to nothing for native builds  
  197. ifeq ($(HOSTARCH),$(ARCH))  
  198. CROSS_COMPILE ?=  
  199. endif  
  200. #######################################  
  201. #看看注释就知道了,但是很显示我们的HOSTARCH是x86的,目标时arm的  
  202. ########################################  
  203.   
  204. # load other configuration  
  205. include $(TOPDIR)/config.mk  
  206. #######################################  
  207. #包含uboot顶层目录的config.mk文件  
  208. #######################################  
  209.   
  210. # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use  
  211. # that (or fail if absent).  Otherwise, search for a linker script in a  
  212. # standard location.  
  213. LDSCRIPT_MAKEFILE_DIR = $(dir $(LDSCRIPT))  
  214. ##############################################################################  
  215. #用等号赋值的变量是递归方式扩展的变量。变量定义时,变量值中对其他变量的引用不会被替换展开;  
  216. #而是变量在引用它的地方替换展开的同时,它所引用的其它变量才会被一同替换展开。  
  217. #其优点是:  
  218. #这种类型变量在定义时,可以引用其它的之前没有定义的变量(可能在后续部分定义,或者是通过make的命令行选项传递的变量)。  
  219. #LDSCRIPT变量就是后面才定义的  
  220. ##############################################################################  
  221.   
  222. ifndef LDSCRIPT  
  223.     #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug  
  224.     ifdef CONFIG_SYS_LDSCRIPT  
  225.         # need to strip off double quotes  
  226.         LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))  
  227.     endif  
  228. endif  
  229. #######################################################################################  
  230. #如果定义了CONFIG_SYS_LDSCRIPT,将CONFIG_SYS_LDSCRIPT代表的字符串去掉双引号后赋值给LDSCRIPT变量  
  231. #这里我们并没有定义CONFIG_SYS_LDSCRIPT  
  232. #######################################################################################  
  233.   
  234. # If there is no specified link script, we look in a number of places for it  
  235. ifndef LDSCRIPT  
  236.     ifeq ($(CONFIG_NAND_U_BOOT),y)  
  237.         LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds  
  238.         ifeq ($(wildcard $(LDSCRIPT)),)  
  239.             LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot-nand.lds  
  240.         endif  
  241.     endif  
  242.     ifeq ($(wildcard $(LDSCRIPT)),)  
  243.         LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds  
  244.     endif  
  245.     ifeq ($(wildcard $(LDSCRIPT)),)  
  246.         LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot.lds  
  247.     endif  
  248.     ifeq ($(wildcard $(LDSCRIPT)),)  
  249.         LDSCRIPT := $(TOPDIR)/arch/$(ARCH)/cpu/u-boot.lds  
  250.         # We don't expect a Makefile here  
  251.         LDSCRIPT_MAKEFILE_DIR =  
  252.     endif  
  253.     ifeq ($(wildcard $(LDSCRIPT)),)  
  254. $(error could not find linker script)  
  255.     endif  
  256. endif  
  257. ##########################################################################################  
  258. #注释写的很明确,如果没有用CONFIG_SYS_LDSCRIPT指定LDSCRIPT,那么就在几个地方搜  
  259. #第一个地方:如果CONFIG_NAND_U_BOOT是y,就用u-boot-nand.lds         但是这里没有这个定义  
  260. #第一个地方没找到,就找第二个地方:u-boot-2012.07/board/samsung/smdk2410     这个目录没有u-boot.lds文件  
  261. #第二个地方没找到,就找第三个地方:其中CPUDIR是在顶层的config.mk中定义的,在arch/arm/cpu/arm920t中找    这个目录也没有  
  262. #第三个地方没找到,就找第四个地方:arch/arm/cpu/u-boot.lds,这里就找到了!!!!  
  263. ##########################################################################################  
  264.   
  265. #########################################################################  
  266. # U-Boot objects....order is important (i.e. start must be first)  
  267.   
  268. OBJS  = $(CPUDIR)/start.o  
  269. ifeq ($(CPU),x86)  
  270. OBJS += $(CPUDIR)/start16.o  
  271. OBJS += $(CPUDIR)/resetvec.o  
  272. endif  
  273. ifeq ($(CPU),ppc4xx)  
  274. OBJS += $(CPUDIR)/resetvec.o  
  275. endif  
  276. ifeq ($(CPU),mpc85xx)  
  277. OBJS += $(CPUDIR)/resetvec.o  
  278. endif  
  279.   
  280. OBJS := $(addprefix $(obj),$(OBJS))  
  281. #####################################  
  282. #为OBJS增加前缀,其中obj在顶层目录的config.mk中定义,这里根据实际情况 OBJS就是 arch/arm/cpu/arm920t/start.o  
  283. #####################################  
  284.   
  285. LIBS  = lib/libgeneric.o  
  286. LIBS += lib/lzma/liblzma.o  
  287. LIBS += lib/lzo/liblzo.o  
  288. LIBS += lib/zlib/libz.o  
  289. ifeq ($(CONFIG_TIZEN),y)  
  290. LIBS += lib/tizen/libtizen.o  
  291. endif  
  292. LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo   
  293.     "board/$(VENDOR)/common/lib$(VENDOR).o"; fi)  
  294. LIBS += $(CPUDIR)/lib$(CPU).o  
  295. ifdef SOC  
  296. LIBS += $(CPUDIR)/$(SOC)/lib$(SOC).o  
  297. endif  
  298. ifeq ($(CPU),ixp)  
  299. LIBS += arch/arm/cpu/ixp/npe/libnpe.o  
  300. endif  
  301. ifeq ($(CONFIG_OF_EMBED),y)  
  302. LIBS += dts/libdts.o  
  303. endif  
  304. LIBS += arch/$(ARCH)/lib/lib$(ARCH).o  
  305. LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o   
  306.     fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o   
  307.     fs/ubifs/libubifs.o  
  308. LIBS += net/libnet.o  
  309. LIBS += disk/libdisk.o  
  310. LIBS += drivers/bios_emulator/libatibiosemu.o  
  311. LIBS += drivers/block/libblock.o  
  312. LIBS += drivers/dma/libdma.o  
  313. LIBS += drivers/fpga/libfpga.o  
  314. LIBS += drivers/gpio/libgpio.o  
  315. LIBS += drivers/hwmon/libhwmon.o  
  316. LIBS += drivers/i2c/libi2c.o  
  317. LIBS += drivers/input/libinput.o  
  318. LIBS += drivers/misc/libmisc.o  
  319. LIBS += drivers/mmc/libmmc.o  
  320. LIBS += drivers/mtd/libmtd.o  
  321. LIBS += drivers/mtd/nand/libnand.o  
  322. LIBS += drivers/mtd/onenand/libonenand.o  
  323. LIBS += drivers/mtd/ubi/libubi.o  
  324. LIBS += drivers/mtd/spi/libspi_flash.o  
  325. LIBS += drivers/net/libnet.o  
  326. LIBS += drivers/net/phy/libphy.o  
  327. LIBS += drivers/pci/libpci.o  
  328. LIBS += drivers/pcmcia/libpcmcia.o  
  329. LIBS += drivers/power/libpower.o  
  330. LIBS += drivers/spi/libspi.o  
  331. ifeq ($(CPU),mpc83xx)  
  332. LIBS += drivers/qe/libqe.o  
  333. LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o  
  334. LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o  
  335. endif  
  336. ifeq ($(CPU),mpc85xx)  
  337. LIBS += drivers/qe/libqe.o  
  338. LIBS += drivers/net/fm/libfm.o  
  339. LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o  
  340. LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o  
  341. endif  
  342. ifeq ($(CPU),mpc86xx)  
  343. LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o  
  344. LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o  
  345. endif  
  346. LIBS += drivers/rtc/librtc.o  
  347. LIBS += drivers/serial/libserial.o  
  348. ifeq ($(CONFIG_GENERIC_LPC_TPM),y)  
  349. LIBS += drivers/tpm/libtpm.o  
  350. endif  
  351. LIBS += drivers/twserial/libtws.o  
  352. LIBS += drivers/usb/eth/libusb_eth.o  
  353. LIBS += drivers/usb/gadget/libusb_gadget.o  
  354. LIBS += drivers/usb/host/libusb_host.o  
  355. LIBS += drivers/usb/musb/libusb_musb.o  
  356. LIBS += drivers/usb/phy/libusb_phy.o  
  357. LIBS += drivers/usb/ulpi/libusb_ulpi.o  
  358. LIBS += drivers/video/libvideo.o  
  359. LIBS += drivers/watchdog/libwatchdog.o  
  360. LIBS += common/libcommon.o  
  361. LIBS += lib/libfdt/libfdt.o  
  362. LIBS += api/libapi.o  
  363. LIBS += post/libpost.o  
  364.   
  365. ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)  
  366. LIBS += $(CPUDIR)/omap-common/libomap-common.o  
  367. endif  
  368.   
  369. ifeq ($(SOC),mx5)  
  370. LIBS += $(CPUDIR)/imx-common/libimx-common.o  
  371. endif  
  372. ifeq ($(SOC),mx6)  
  373. LIBS += $(CPUDIR)/imx-common/libimx-common.o  
  374. endif  
  375.   
  376. ifeq ($(SOC),s5pc1xx)  
  377. LIBS += $(CPUDIR)/s5p-common/libs5p-common.o  
  378. endif  
  379. ifeq ($(SOC),exynos)  
  380. LIBS += $(CPUDIR)/s5p-common/libs5p-common.o  
  381. endif  
  382.   [page]
  383. LIBS := $(addprefix $(obj),$(sort $(LIBS)))  
  384. ########################################  
  385. #将LIBS排序后为LIBS增加前缀  
  386. #########################################  
  387. .PHONY : $(LIBS)  
  388.   
  389. LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o  
  390. LIBBOARD := $(addprefix $(obj),$(LIBBOARD))  
  391. ###########################################  
  392. #为LIBBOARD增加前缀,LIBBOARD就是board/samsung/smdk2410/libsmdk2410.o  
  393. ###########################################  
  394.   
  395. # Add GCC lib  
  396. ifdef USE_PRIVATE_LIBGCC  
  397. ifeq ("$(USE_PRIVATE_LIBGCC)", "yes")  
  398. PLATFORM_LIBGCC = $(OBJTREE)/arch/$(ARCH)/lib/libgcc.o  
  399. else  
  400. PLATFORM_LIBGCC = -L $(USE_PRIVATE_LIBGCC) -lgcc  
  401. endif  
  402. else  
  403. PLATFORM_LIBGCC := -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc  
  404. endif  
  405. PLATFORM_LIBS += $(PLATFORM_LIBGCC)  
  406. export PLATFORM_LIBS  
  407.   
  408. # Special flags for CPP when processing the linker script.  
  409. # Pass the version down so we can handle backwards compatibility  
  410. # on the fly.  
  411. LDPPFLAGS +=   
  412.     -include $(TOPDIR)/include/u-boot/u-boot.lds.h   
  413.     -DCPUDIR=$(CPUDIR)   
  414.     $(shell $(LD) --version |   
  415.       sed -ne 's/GNU ld version ..*/-DLD_MAJOR=1 -DLD_MINOR=2/p')  
  416.   
  417. __OBJS := $(subst $(obj),,$(OBJS))  
  418. __LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))  
  419.   
  420. #########################################################################  
  421. #########################################################################  
  422.   
  423. ifneq ($(CONFIG_BOARD_SIZE_LIMIT),)  
  424. BOARD_SIZE_CHECK =   
  425.     @actual=`wc -c $@ | awk '{print $$1}'`;   
  426.     limit=$(CONFIG_BOARD_SIZE_LIMIT);   
  427.     if test 
    limit; then   
  428.         echo "$@ exceeds file size limit:";   
  429.         echo "  limit:  $$limit bytes";   
  430.         echo "  actual: $$actual bytes";   
  431.         echo "  excess: $$((actual - limit)) bytes";   
  432.         exit 1;   
  433.     fi  
  434. else  
  435. BOARD_SIZE_CHECK =  
  436. endif  
        

 

        这里也给出顶层目录下的config.mk文件的注释:

 

[cpp] view plaincopy
 
  1. #  
  2. # (C) Copyright 2000-2006  
  3. # Wolfgang Denk, DENX Software Engineering, wd@denx.de.  
  4. #  
  5. # See file CREDITS for list of people who contributed to this  
  6. # project.  
  7. #  
  8. # This program is free software; you can redistribute it and/or  
  9. # modify it under the terms of the GNU General Public License as  
  10. # published by the Free Software Foundation; either version 2 of  
  11. # the License, or (at your option) any later version.  
  12. #  
  13. # This program is distributed in the hope that it will be useful,  
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of  
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
  16. # GNU General Public License for more details.  
  17. #  
  18. # You should have received a copy of the GNU General Public License  
  19. # along with this program; if not, write to the Free Software  
  20. # Foundation, Inc., 59 Temple Place, Suite 330, Boston,  
  21. # MA 02111-1307 USA  
  22. #  
  23.   
  24. #########################################################################  
  25.   
  26. ifeq ($(CURDIR),$(SRCTREE))  
  27. dir :=  
  28. else  
  29. dir := $(subst $(SRCTREE)/,,$(CURDIR))  
  30. endif  
  31. ###########################################################################  
  32. #在顶层makefile中已经分析了CURDIR和SRCTREE都是当前目录,所以这里dir暂时为空  
  33. ###########################################################################  
  34. ifneq ($(OBJTREE),$(SRCTREE))  
  35. # Create object files for SPL in a separate directory  
  36. ifeq ($(CONFIG_SPL_BUILD),y)  
  37. obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)  
  38. else  
  39. obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/)  
  40. endif  
  41. src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/)  
  42.   
  43. $(shell mkdir -p $(obj))  
  44. else  
  45. # Create object files for SPL in a separate directory  
  46. ifeq ($(CONFIG_SPL_BUILD),y)  
  47. obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)  
  48.   
  49. $(shell mkdir -p $(obj))  
  50. else  
  51. obj :=  
  52. endif  
  53. src :=  
  54. endif  
  55. ########################################################################################  
  56. #首先OBJTREE和SRCTREE都是当前目录,所以执行else  
  57. #查找CONFIG_SPL_BUILD是否定义为y,在autoconf.mk中,并没有这个定义,所以obj和src暂时也为空  
  58. ########################################################################################  
  59.   
  60. # clean the slate ...  
  61. PLATFORM_RELFLAGS =  
  62. PLATFORM_CPPFLAGS =  
  63. PLATFORM_LDFLAGS =  
  64.   
  65. #########################################################################  
  66.   
  67. HOSTCFLAGS  = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer   
  68.           $(HOSTCPPFLAGS)  
  69. HOSTSTRIP   = strip  
  70.   
  71. #  
  72. # Mac OS X / Darwin's C preprocessor is Apple specific.  It  
  73. # generates numerous errors and warnings.  We want to bypass it  
  74. # and use GNU C's cpp.  To do this we pass the -traditional-cpp  
  75. # option to the compiler.  Note that the -traditional-cpp flag  
  76. # DOES NOT have the same semantics as GNU C's flag, all it does  
  77. # is invoke the GNU preprocessor in stock ANSI/ISO C fashion.  
  78. #  
  79. # Apple's linker is similar, thanks to the new 2 stage linking  
  80. # multiple symbol definitions are treated as errors, hence the  
  81. # -multiply_defined suppress option to turn off this error.  
  82. #  
  83.   
  84. ifeq ($(HOSTOS),darwin)  
  85. # get major and minor product version (e.g. '10' and '6' for Snow Leopard)  
  86. DARWIN_MAJOR_VERSION    = $(shell sw_vers -productVersion | cut -f 1 -d '.')  
  87. DARWIN_MINOR_VERSION    = $(shell sw_vers -productVersion | cut -f 2 -d '.')  
  88.   
  89. os_x_before = $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a   
  90.     $(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;)  
  91.   
  92. # Snow Leopards build environment has no longer restrictions as described above  
  93. HOSTCC       = $(call os_x_before, 10, 5, "cc", "gcc")  
  94. HOSTCFLAGS  += $(call os_x_before, 10, 4, "-traditional-cpp")  
  95. HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress")  
  96. else  
  97. HOSTCC      = gcc  
  98. endif  
  99.   
  100. ifeq ($(HOSTOS),cygwin)  
  101. HOSTCFLAGS  += -ansi  
  102. endif  
  103.   
  104. # We build some files with extra pedantic flags to try to minimize things  
  105. # that won't build on some weird host compiler -- though there are lots of  
  106. # exceptions for files that aren't complaint.  
  107.   
  108. HOSTCFLAGS_NOPED = $(filter-out -pedantic,$(HOSTCFLAGS))  
  109. HOSTCFLAGS  += -pedantic  
  110. ############################################################  
  111. #HOSTCFLAGS_NOPED是利用filter-out函数从HOSTCFLAGS中过滤掉-pedantic选项  
  112. #而HOSTCFLAGS追加上-pedantic选项  
  113. ############################################################  
  114.   
  115. #########################################################################  
  116. #  
  117. # Option checker, gcc version (courtesy linux kernel) to ensure  
  118. # only supported compiler options are used  
  119. #  
  120. CC_OPTIONS_CACHE_FILE := $(OBJTREE)/include/generated/cc_options.mk  
  121. CC_TEST_OFILE := $(OBJTREE)/include/generated/cc_test_file.o  
  122.   
  123. -include $(CC_OPTIONS_CACHE_FILE)  
  124. #############################################################################  
  125. #定义编译选项  
  126. #在cc_options.mk中有如下选项:  
  127. #   CC_OPTIONS += -marm  
  128. #   CC_OPTIONS += -mno-thumb-interwork  
  129. #   CC_OPTIONS += -mapcs-32  
  130. #   CC_OPTIONS += -malignment-traps  
  131. #   CC_OPTIONS += -Wno-format-nonliteral  
  132. #   CC_OPTIONS += -Wno-format-security  
  133. #   CC_OPTIONS += -mabi=apcs-gnu  
  134. #   CC_OPTIONS += -mabi=aapcs-linux  
  135. #############################################################################  
  136.   
  137. cc-option-sys = $(shell mkdir -p $(dir $(CC_TEST_OFILE));   
  138.         if $(CC) $(CFLAGS) $(1) -S -xc /dev/null -o $(CC_TEST_OFILE)   
  139.         > /dev/null 2>&1; then   
  140.         echo 'CC_OPTIONS += $(strip $1)' >> $(CC_OPTIONS_CACHE_FILE);   
  141.         echo "$(1)"; fi)  
  142.   
  143. ifeq ($(CONFIG_CC_OPT_CACHE_DISABLE),y)  
  144. cc-option = $(strip $(if $(call cc-option-sys,$1),$1,$2))  
  145. else  
  146. cc-option = $(strip $(if $(findstring $1,$(CC_OPTIONS)),$1,  
  147.         $(if $(call cc-option-sys,$1),$1,$2)))  
  148. endif  
  149. ###########################################################################################  
  150. #定义两个函数,cc-option-sys被cc-option调用  
  151. #cc-option被后面的函数调用  
  152. ############################################################################################  
  153.   
  154. # cc-version  
  155. # Usage gcc-ver := $(call cc-version)  
  156. cc-version = $(shell $(SHELL) $(SRCTREE)/tools/gcc-version.sh $(CC))  
  157. ##########################################################################################  
  158. #使用tools/gcc-version.sh脚本来获取编译器的版本  
  159. #在顶层makefile中,有调用cc-version函数  
  160. ##########################################################################################  
  161. #  
  162. # Include the make variables (CC, etc...)  
  163. #  
  164. AS  = $(CROSS_COMPILE)as  
  165. LD  = $(CROSS_COMPILE)ld  
  166. CC  = $(CROSS_COMPILE)gcc  
  167. CPP = $(CC) -E  
  168. AR  = $(CROSS_COMPILE)ar  
  169. NM  = $(CROSS_COMPILE)nm  
  170. LDR = $(CROSS_COMPILE)ldr  
  171. STRIP   = $(CROSS_COMPILE)strip  
  172. OBJCOPY = $(CROSS_COMPILE)objcopy  
  173. OBJDUMP = $(CROSS_COMPILE)objdump  
  174. RANLIB  = $(CROSS_COMPILE)RANLIB  
  175. DTC = dtc  
  176. #########################################################################  
  177. #定义汇编器,连接器,编译器,打包工具,反汇编工具,值的注意的RANLIB的作用是在静态库有添加新的.o后,负责更新索引.  
  178. #########################################################################  
  179.   
  180. # Load generated board configuration  
  181. sinclude $(OBJTREE)/include/autoconf.mk  
  182. sinclude $(OBJTREE)/include/config.mk  
  183. ################################################################################################  
  184. #包上配置编译时产生的autoconf.mk和config.mk文件  
  185. ################################################################################################  
  186.   
  187. # Some architecture config.mk files need to know what CPUDIR is set to,  
  188. # so calculate CPUDIR before including ARCH/SOC/CPU config.mk files.  
  189. # Check if arch/$ARCH/cpu/$CPU exists, otherwise assume arch/$ARCH/cpu contains  
  190. # CPU-specific code.  
  191. CPUDIR=arch/$(ARCH)/cpu/$(CPU)  
  192. ifneq ($(SRCTREE)/$(CPUDIR),$(wildcard $(SRCTREE)/$(CPUDIR)))  
  193. CPUDIR=arch/$(ARCH)/cpu  
  194. endif  
  195. #################################################################################################  
  196. #定义CPUDIR为arch/arm/cpu/arm920t  
  197. #################################################################################################  
  198.   
  199. sinclude $(TOPDIR)/arch/$(ARCH)/config.mk   # include architecture dependend rules  
  200. sinclude $(TOPDIR)/$(CPUDIR)/config.mk      # include  CPU  specific rules  
  201. ##################################################################################################  
  202. #包上arch/arm/config.mk和/arch/arm/cpu/arm920t/config.mk文件  
  203. ##################################################################################################  
  204.   
  205. ifdef   SOC  
  206. sinclude $(TOPDIR)/$(CPUDIR)/$(SOC)/config.mk   # include  SoC  specific rules  
  207. endif  
  208. ######################################################################  
  209. #包上arch/arm/cpu/arm920t/s3c24x0/config.mk文件  
  210. #####################################################################  
  211. ifdef   VENDOR  
  212. BOARDDIR = $(VENDOR)/$(BOARD)  
  213. else  
  214. BOARDDIR = $(BOARD)  
  215. endif  
  216. ifdef   BOARD  
  217. sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk  # include board specific rules  
  218. endif  
  219. ######################################################################################  
  220. #包上board/samsung/smdk2410/config.mk文件  
  221. ######################################################################################  
  222.   
  223. #########################################################################  
  224.   
  225. # We don't actually use $(ARFLAGS) anywhere anymore, so catch people  
  226. # who are porting old code to latest mainline but not updating $(AR).  
  227. ARFLAGS = $(error update your Makefile to use cmd_link_o_target and not AR)  
  228. RELFLAGS= $(PLATFORM_RELFLAGS)  
  229. DBGFLAGS= -g # -DDEBUG  
  230. OPTFLAGS= -Os #-fomit-frame-pointer  
  231.   
  232. OBJCFLAGS += --gap-fill=0xff  
  233.   
  234. gccincdir := $(shell $(CC) -print-file-name=include)  
  235.   
  236. CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS)       
  237.     -D__KERNEL__  
  238.   
  239. # Enable garbage collection of un-used sections for SPL  
  240. ifeq ($(CONFIG_SPL_BUILD),y)  
  241. CPPFLAGS += -ffunction-sections -fdata-sections  
  242. LDFLAGS_FINAL += --gc-sections  
  243. endif  
  244.   
  245. ifneq ($(CONFIG_SYS_TEXT_BASE),)  
  246. CPPFLAGS += -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE)  
  247. endif  
  248.   
  249. ifneq ($(CONFIG_SPL_TEXT_BASE),)  
  250. CPPFLAGS += -DCONFIG_SPL_TEXT_BASE=$(CONFIG_SPL_TEXT_BASE)  
  251. endif  
  252.   
  253. ifneq ($(CONFIG_SPL_PAD_TO),)  
  254. CPPFLAGS += -DCONFIG_SPL_PAD_TO=$(CONFIG_SPL_PAD_TO)  
  255. endif  
  256.   
  257. ifeq ($(CONFIG_SPL_BUILD),y)  
  258. CPPFLAGS += -DCONFIG_SPL_BUILD  
  259. endif  
  260.   
  261. ifneq ($(RESET_VECTOR_ADDRESS),)  
  262. CPPFLAGS += -DRESET_VECTOR_ADDRESS=$(RESET_VECTOR_ADDRESS)  
  263. endif  
  264.   
  265. ifneq ($(OBJTREE),$(SRCTREE))  
  266. CPPFLAGS += -I$(OBJTREE)/include2 -I$(OBJTREE)/include  
  267. endif  
  268.   
  269. CPPFLAGS += -I$(TOPDIR)/include  
  270. CPPFLAGS += -fno-builtin -ffreestanding -nostdinc     
  271.     -isystem $(gccincdir) -pipe $(PLATFORM_CPPFLAGS)  
  272.   
  273. ifdef BUILD_TAG  
  274. CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes   
  275.     -DBUILD_TAG='"$(BUILD_TAG)"'  
  276. else  
  277. CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes  
  278. endif  
  279.   
  280. CFLAGS_SSP := $(call cc-option,-fno-stack-protector)  
  281. CFLAGS += $(CFLAGS_SSP)  
  282. # Some toolchains enable security related warning flags by default,  
  283. # but they don't make much sense in the u-boot world, so disable them.  
  284. CFLAGS_WARN := $(call cc-option,-Wno-format-nonliteral)   
  285.            $(call cc-option,-Wno-format-security)  
  286. CFLAGS += $(CFLAGS_WARN)  
  287.   
  288. # Report stack usage if supported  
  289. CFLAGS_STACK := $(call cc-option,-fstack-usage)  
  290. CFLAGS += $(CFLAGS_STACK)  
  291.   
  292. # $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g  
  293. # option to the assembler.  
  294. AFLAGS_DEBUG :=  
  295.   
  296. # turn jbsr into jsr for m68k  
  297. ifeq ($(ARCH),m68k)  
  298. ifeq ($(findstring 3.4,$(shell $(CC) --version)),3.4)  
  299. AFLAGS_DEBUG := -Wa,-gstabs,-S  
  300. endif  
  301. endif  
  302.   [page]
  303. AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS)  
  304.   
  305. LDFLAGS += $(PLATFORM_LDFLAGS)  
  306. LDFLAGS_FINAL += -Bstatic  
  307.   
  308. LDFLAGS_u-boot += -T $(obj)u-boot.lds $(LDFLAGS_FINAL)  
  309. ifneq ($(CONFIG_SYS_TEXT_BASE),)  
  310. LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)  
  311. endif  
  312.   
  313. LDFLAGS_u-boot-spl += -T $(obj)u-boot-spl.lds $(LDFLAGS_FINAL)  
  314. ifneq ($(CONFIG_SPL_TEXT_BASE),)  
  315. LDFLAGS_u-boot-spl += -Ttext $(CONFIG_SPL_TEXT_BASE)  
  316. endif  
  317.   
  318. # Location of a usable BFD library, where we define "usable" as  
  319. # "built for ${HOST}, supports ${TARGET}".  Sensible values are  
  320. # - When cross-compiling: the root of the cross-environment  
  321. # - Linux/ppc (native): /usr  
  322. # - NetBSD/ppc (native): you lose ... (must extract these from the  
  323. #   binutils build directory, plus the native and U-Boot include  
  324. #   files don't like each other)  
  325. #  
  326. # So far, this is used only by tools/gdb/Makefile.  
  327.   
  328. ifeq ($(HOSTOS),darwin)  
  329. BFD_ROOT_DIR =      /usr/local/tools  
  330. else  
  331. ifeq ($(HOSTARCH),$(ARCH))  
  332. # native  
  333. BFD_ROOT_DIR =      /usr  
  334. else  
  335. #BFD_ROOT_DIR =     /LinuxPPC/CDK       # Linux/i386  
  336. #BFD_ROOT_DIR =     /usr/pkg/cross      # NetBSD/i386  
  337. BFD_ROOT_DIR =      /opt/powerpc  
  338. endif  
  339. endif  
  340.   
  341. #########################################################################  
  342.   
  343. export  HOSTCC HOSTCFLAGS HOSTLDFLAGS PEDCFLAGS HOSTSTRIP CROSS_COMPILE   
  344.     AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP MAKE  
  345. export  CONFIG_SYS_TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS  
  346.   
  347. #########################################################################  
  348.   
  349. # Allow boards to use custom optimize flags on a per dir/file basis  
  350. BCURDIR = $(subst $(SRCTREE)/,,$(CURDIR:$(obj)%=%))  
  351. ALL_AFLAGS = $(AFLAGS) $(AFLAGS_$(BCURDIR)/$(@F)) $(AFLAGS_$(BCURDIR))  
  352. ALL_CFLAGS = $(CFLAGS) $(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR))  
  353. EXTRA_CPPFLAGS = $(CPPFLAGS_$(BCURDIR)/$(@F)) $(CPPFLAGS_$(BCURDIR))  
  354. ALL_CFLAGS += $(EXTRA_CPPFLAGS)  
  355.   
  356. # The _DEP version uses the $< file target (for dependency generation)  
  357. # See rules.mk  
  358. EXTRA_CPPFLAGS_DEP = $(CPPFLAGS_$(BCURDIR)/$(addsuffix .o,$(basename $<)))   
  359.         $(CPPFLAGS_$(BCURDIR))  
  360. $(obj)%.s:  %.S  
  361.     $(CPP) $(ALL_AFLAGS) -o $@ $<  
  362. $(obj)%.o:  %.S  
  363.     $(CC)  $(ALL_AFLAGS) -o $@ $< -c  
  364. $(obj)%.o:  %.c  
  365.     $(CC)  $(ALL_CFLAGS) -o $@ $< -c  
  366. $(obj)%.i:  %.c  
  367.     $(CPP) $(ALL_CFLAGS) -o $@ $< -c  
  368. $(obj)%.s:  %.c  
  369.     $(CC)  $(ALL_CFLAGS) -o $@ $< -c -S  
  370.   
  371. #########################################################################  
  372.   
  373. # If the list of objects to link is empty, just create an empty built-in.o  
  374. cmd_link_o_target = $(if $(strip $1),  
  375.               $(LD) $(LDFLAGS) -r -o $@ $1,  
  376.               rm -f $@; $(AR) rcs $@ )  
  377.   
  378. #########################################################################  

        主要是一些变量和函数的定义,编译链接的参数设置以及依赖规则.

 

        最后分析下make:

 

[cpp] view plaincopy
 
  1. $(obj)include/autoconf.mk.dep: $(obj)include/config.h include/common.h  
  2.     @$(XECHO) Generating $@ ;   
  3.     set -e ;   
  4.     : Generate the dependancies ;   
  5.     $(CC) -x c -DDO_DEPS_ONLY -M $(CFLAGS) $(CPPFLAGS)   
  6.         -MQ $(obj)include/autoconf.mk include/common.h > $@  
  7.   
  8. $(obj)include/autoconf.mk: $(obj)include/config.h  
  9.     @$(XECHO) Generating $@ ;   
  10.     set -e ;   
  11.     : Extract the config macros ;   
  12.     $(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h |   
  13.         sed -n -f tools/scripts/define2mk.sed > $@.tmp &&   
  14.     mv $@.tmp $@  
        第一个是生成include/autoconf.mk的依赖文件

 

        第二个是根据include/config.h的文件内容,利用tools/scripts/define2mk.sed脚本将所有的CONFIG提取到autoconf.mk文件中
 

        终极目标是:ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map

        u-boot.srec也是根据u-boot用objcopy工具搞出来的,不知的什么作用

        u-boot.bin也是根据u-boot用objcopy工具搞出来的,最终烧写的二进制bin档

        System.map是符号列表

 

[cpp] view plaincopy
 
  1. $(obj)u-boot.bin:   $(obj)u-boot  
  2.         $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@  
  3.         $(BOARD_SIZE_CHECK)  
  4. ###################################################################################  
  5. #要得到最后的u-boot.bin,必须得到u-boot.u-boot.bin是最后要烧写到板子上的二进制bin档  
  6. #利用objcopy来得到这个二进制文件($@是规则的目标文件名,$<是规则的第一个依赖文件名)  
  7. #调用BOARD_SIZE_CHECK  
  8. ###################################################################################  

u-boot的依赖分析:
$(obj)u-boot: depend
$(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
$(GEN_UBOOT)


u-boot 依赖depend $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
然后用$(GEN_UBOOT)生成最后的u-boot,GEN_UBOOT就是用ld链接的过程


a.看一下depend:
depend dep: $(TIMESTAMP_FILE) $(VERSION_FILE)
$(obj)include/autoconf.mk
$(obj)include/generated/generic-asm-offsets.h
$(obj)include/generated/asm-offsets.h
for dir in $(SUBDIRS) $(CPUDIR) $(LDSCRIPT_MAKEFILE_DIR) ; do
$(MAKE) -C $$dir _depend ; done
对$(SUBDIRS) $(CPUDIR) $(LDSCRIPT_MAKEFILE_DIR)目录生成depend依赖文件;
而_depend是在rules.mk中定义的,利用CC的-M选项生成依赖文件.

b.看一下$(SUBDIR_TOOLS):
         tools目录

c.看一下$(OBJS):
$(OBJS): depend
$(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))
看下$(if $(REMOTE_BUILD),$@,$(notdir $@))
因为$(REMOTE_BUILD)为空,所以返回的是$(notdir $@)的值;
因为$@指的是规则的目标,所以就是$(OBJS),而$(OBJS)就是arch/arm/cpu/arm920t/start.o
notdir内嵌函数返回的文件名;所以返回start.o
执行makc -C arch/arm/cpu/arm920t start.o

d.$(LIBBOARD)
$(LIBBOARD): depend $(LIBS)
$(MAKE) -C $(dir $(subst $(obj),,$@))
执行make -C board/samsung/smdk2410

e.$(LIBS)
$(LIBS): depend $(SUBDIR_TOOLS)
$(MAKE) -C $(dir $(subst $(obj),,$@))
进入到LIBS包含的很多目录,执行make,生成很多.a文件.

f.$(LDSCRIPT)
$(LDSCRIPT): depend
$(MAKE) -C $(dir $@) $(notdir $@)
在前面找链接脚本时已然知晓LDSCRIPT就是arch/arm/cpu/u-boot.lds
执行make -C arch/arm/cpu u-boot.lds  这个目录没有makefile,这什么意思?!!!

g.$(obj)u-boot.lds
$(obj)u-boot.lds: $(LDSCRIPT)
$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@

       这些就是编译uboot的规则,分析的比较粗糙,在移植的过程中肯定还会遇到各式各样的问题,在移植过程中再进一步深入并修正.
关键字:ARM汇编  u-boot  makefile  mkconfig 引用地址:GNU ARM汇编--(十七)u-boot的makefile和mkconfig解读

上一篇:GNU ARM汇编--(二十)总结
下一篇:GNU ARM汇编--(十八)u-boot-采用nand_spl方式的启动方法

推荐阅读最新更新时间:2024-03-16 14:35

arm汇编指令--STR
STR指令的格式为: STR{条件} 源寄存器, 存储器地址 STR指令用亍从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常 用,丏寻址方式灵活多样,使用方式可参考指令LDR。 指令示例: STR R0, ,#8 ;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1。 STR R0, ;将R0中的字数据写入以R1+8为地址的存储器中。 str r1, ;将r1寄存器的值,传送到地址值为r0的(存储器)内存中
[单片机]
【嵌入式】从零开始移植U-boot到mini2440(四)——C runtime配置篇
设置C运行环境及代码relocate - lib/crt0.S C-runtime startup Code for ARM U-Boot 在CPU完成最基本的初始化之后,我们总不能一直以汇编的方式写代码,此时我们就需要C运行环境。同时其他地方经常会把relocate单独拉出来讲,其实本质上来讲,也是属于创造C运行环境的一部分。 首先我们应该理解,C语言运行对于芯片来讲除了可以稳定,正确地执行指令,还需要什么样的内存环境? 众所周知,内存环境可以分成五段,其中TEXT段,data段在bin文件中,或者说就是在我们写代码的时候已经定义好,BSS段需要有系统初始化,剩下的是堆区和栈区,需要我们启动的时候划分好。 按照这个思路,
[单片机]
【嵌入式】从零开始移植<font color='red'>U-boot</font>到mini2440(四)——C runtime配置篇
ARM汇编: ldr与mov 、 b与bl
ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令。 比如想把数据从内存中某处读取到寄存器中,只能使用ldr 比如: ldr r0, 0x12345678 就是把0x12345678这个地址中的值存放到r0中。 而mov不能干这个活,mov只能在寄存器之间移动数据,或者把立即数移动到寄存器中,这个和x86这种CISC架构的芯片区别最大的地方。 x86中没有ldr这种指令,因为x86的mov指令可以将数据从内存中移动到寄存器中。 另外还有一个就是ldr伪指令,虽然ldr伪指令和ARM的ldr指令很像,但是作用不太一样。ldr伪指令可以在立即数前加上=,以表示把一个地址写到某寄存器中,
[单片机]
u-boot-2016.09移植(1)-单板配置
cpu : s5pv210(armv7) uboot :u-boot-2016.09 ubuntu :ubuntu 16.04 移植平台:tq210 因为smdkc100与我们要移植的s5pv210同为armv7,所以我们以smdkc100为模板来修改。 一、添加单板信息 u-boot-2016.09$ cp -arf board/samsung/smdkc100 board/samsung/tq210 进入tq210目录下将tq210/下的smdkc100.c重命名为tq210.c u-boot-2016.09/board/samsung/tq210$ mv smdkc100.c tq210.c 修改
[单片机]
ARM汇编进阶
接触嵌入式以来,汇编来来回回学了好几遍,感觉还是有几个地方不清楚,所以在这里做一下总结,基本的非常简单的指令就不多余介绍了,主要分享一些个人觉得虽然微不足道,但是对于理解ARM汇编有帮助的一些知识 在这里一定要说一下,刚开始学的时候步入了一个大坑,我以为我学的是ARM汇编,后来了解到了,原来是GNU汇编,怪不得我有些问题去网上找的时候迷迷糊糊的,直到最近才纠正过来 所以首先就是介绍一下这两种汇编有什么区别 ARM汇编与GNU汇编区别 ARM汇编开发,有两种开发方式,一种是使用ARM汇编,一种是使用ARM GNU汇编。 两种汇编开发,使用的汇编指令是完全一样的。 区别是宏指令,伪指令,伪操作不一样。 有上述区
[单片机]
<font color='red'>ARM汇编</font>进阶
Windows下u-boot-2011.03在Mini2440移植详解(7)
Nand Flash 启动 && Nor Flash和Nand Flash双启动 Nand Flash启动 参考网址: http://blog.csdn.net/canjiangsu/article/details/6162677 http://blog.chinaunix.net/uid-28335137-id-3721851.html http://www.cnblogs.com/LoongEmbedded/archive/2010/11/18/1880379.html http://www.crifan.com/switch_s3c2410_nandflash_k9f1208u0ak9f1208u0b_r
[单片机]
Windows下u-boot-2011.03在Mini2440移植详解(7)
[Linux 底层]U-boot ksz9031网络驱动调试
ksz9031的介绍可以回归一下datasheet的介绍,一款很优秀的千兆以太网; 【Datasheet】PHY KSZ9031千兆网络芯片解读 系统版本:Ubuntu18.04-64 编译器版本:gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1) uboot版本:2018.07 -linux4sam_6.0 板子型号:at91sama5d3x-xplained MCU型号:sama5d36 关注微信公众号,回复“ksz9031驱动”,免费下载ksz9031的驱动源代码。 硬件参考图如下: 1、uboot官网开发板默认配置文件路径
[单片机]
[Linux 底层]<font color='red'>U-boot</font> ksz9031网络驱动调试
基于U-BOOT的S3C44B0引导装载程序的设计与实现
引言 嵌入式Linux的引导装载程序(Bootloader)是操作系统内核启动之前运行的一段程序,其作用与PC机上的BIOS类似。通过这段程序,将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好正确的环境 。Bootloader 与底层硬件相关密切,即每个不同配置的目标板都有不同的Bootloader。对于两块不同的嵌入式板,即使它们使用同一种CPU构建,要想让运行在其中一块上的Bootloader程序也能够运行在另一块板子上,通常也都需要修改Bootloader源程序。 嵌入式系统的硬件部分不可能是完全一致的,不可能有通用的bootloader。因此,需要针对硬件系统进行有关引导程序的设计。对于嵌入式系统来
[单片机]
基于<font color='red'>U-BOOT</font>的S3C44B0引导装载程序的设计与实现
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved