zoukankan      html  css  js  c++  java
  • uboot make xxx_config与make的过程分析

    一直很想捋清楚make xxx_config,make 的执行过程。

    在uboot的makefile中有这样的话:

    %_config::unconfig 

    @$(MKCONFIG) -A $(@:_config=)

    这里可以看到%_config目标后面是双冒号,而我们平常看的只有一个冒号,这个就是makefile 的双冒号规则了,而平常我们见的单冒号就是普通规则。Makefile 中规定:一个目标可以出现在多个规则中。但是这些规则必须是同一类型的规则,要么都是普通规则,要么都是双冒号规则。而不允许一个目标同时出现在两种不同类型的规则中。双冒号规则和普通规则的处理的不同点表现在以下几个方面:

    1. 双冒号规则中,当依赖文件比目标更新时。规则将会被执行。对于一个没有依赖而只有命令行的双冒号规则,当引用此目标时,规则的命令将会被无条件执行。而普通规则,当规则的目标文件存在时,此规则的命令永远不会被执行(目标文件永远是最新的)。

    2. 当同一个文件作为多个双冒号规则的目标时。这些不同的规则会被独立的处理,而不是像普通规则那样合并所有的依赖到一个目标文件。这就意味着对这些规则的处理就像多个不同的普通规则一样。就是说多个双冒号规则中的每一个的依赖文件被改变之后,make只执行此规则定义的命令,而其它的以这个文件作为目标的双冒号规则将不会被执行。

    关于板子的配置信息都独立出来放在了boards.cfg文件中,这样在我们执行不同的"make <board_name>_config"时,都会执行。

    %_config::unconfig 

    @$(MKCONFIG) -A $(@:_config=)

    这个命令,但是uboot使用双引号规则后,都会按照各自的<board_name>_config生成相应的目标文件。

    1. 而@的作用是在执行这条命令的时候不进行显示,$(MKCONFIG)是取变量MKCONFIG,由MKCONFIG := $(SRCTREE)/mkconfig这条语句知,就是当前目录下的mkconfig文件,$(@:_config=)的意思是,讲目标文件名字中含有的_config用等号后面的的字符替换掉,这里=后面为空,所以其效果就是把_config去掉,这样,make smdk2410_config实际上就是先执行unconfig的命令,再执行mkconfig –A smdk2410。那么,紧接着,我们来看下mkconfig 都做了些什么:
    2. # Script to create header files and links to configure
    3. # U-Boot for a specific board.
    4. # Parameters: Target Architecture CPU Board [VENDOR] [SOC]
    5. 由mkconfig的注释可以看出mkconfig是用来生成一些头文件和连接的。
    6. if [ ( $# -eq 2 ) -a ( "$1" = "-A" ) ] ; then
    7. # Automatic mode
    8. line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
    9. echo "make: *** No rule to make target \`$2_config'. Stop." >&2
    10. exit 1
    11. }
    12. set ${line}
    13. # add default board name if needed
    14. [ $# = 3 ] && set ${line} ${1}
    15. fi
    16. $#代表传递给程序的参数的总个数,-a的意思就是前后两个都成立,if的判断条件才为真,$1为第一参数,而我们执行的命令是:mkconfig –A smdk2410,参数个数为2,第一个参数为-A,所以if条件为真。
    17. line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
    18. echo "make: *** No rule to make target \`$2_config'. Stop." >&2
    19. exit 1
    20. }
    21. 这条我猜测是读取boards.cfg文件中的${2}的信息,而我们传递的第二个参数是smdk2410,所以就是读取boards.cfg文件中的smdk2410的信息,如果不存在smdk2410的信息的话,就打印出一条语句:make: *** No rule to make target \`$2_config'. Stop." >&2并退出。
    22. 从boards.cfg读出的信息为:
    23. smdk2410 arm arm920t - samsung s3c24x0
    24. 接下来:
    25. while [ $# -gt 0 ] ; do //参数个数大于0执行
    26. case "$1" in
    27. --) shift ; break ;;
    28. -a) shift ; APPEND=yes ;;
    29. -n) shift ; BOARD_NAME="${1%_config}" ; shift ;;
    30. -t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;
    31. *) break ;;
    32. esac
    33. done
    34. //mkconfig中没有这些参数,所以上面语句不执行
    35. [ $# -lt 4 ] && exit 1
    36. [ $# -gt 6 ] && exit 1
    37. //从boards.cfg中读出的参数为5个,小于4大于6都是错误的将退出。
    38. CONFIG_NAME="${1%_config}"
    39. // CONFIG_NAME设为第一个参数smdk2410
    40. [ "${BOARD_NAME}" ] || BOARD_NAME="${CONFIG_NAME}"
    41. // BOARD_NAME刚开始是空的,现在设为CONFIG_NAME即smdk2410
    42. arch="$2"
    43. cpu="$3"
    44. //arch设为arm,cpu设为arm920t
    45. if [ "$4" = "-" ] ; then
    46. board=${BOARD_NAME}
    47. else
    48. board="$4"
    49. fi
    50. //因为有-所以board为smdk2410
    51. [ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
    52. [ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"
    53. //设置厂商和soc名字分别为samsung和s3c24x0
    54. if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then
    55. echo "Failed: $ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2
    56. exit 1
    57. fi
    58. //判断是否为arm,不是则提示出错信息。
    59. echo "Configuring for ${BOARD_NAME} board..."
    60. //打印相应的信息
    61. //接下来是创建平台相关的头文件的链接
    62. # Create link to architecture specific headers
    63. #
    64. if [ "$SRCTREE" != "$OBJTREE" ] ; then
    65. mkdir -p ${OBJTREE}/include
    66. mkdir -p ${OBJTREE}/include2
    67. cd ${OBJTREE}/include2
    68. rm -f asm
    69. ln -s ${SRCTREE}/arch/${arch}/include/asm asm
    70. LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/
    71. cd ../include
    72. rm -f asm
    73. ln -s ${SRCTREE}/arch/${arch}/include/asm asm
    74. else
    75. cd ./include
    76. rm -f asm
    77. ln -s ../arch/${arch}/include/asm asm
    78. fi
    79. //$SRCTREE是源代码目录,OBJTREE是目标文件目录,if [ "$SRCTREE" != "$OBJTREE" ]此句是判断源代码目录和目标文件目录是否一样,可以选择在其他目录下编译uboot,这样可以令源代码目录保持干净,可以同时使用不同的配置进行编译。这里我们打算直接在源代码目录下编译,所以将执行else的代码,cd ./include进入include目录,rm -f asm删除asm文件(这是上一次配置时建立的链接文件),然后再次建立链接文件,ln -s ../arch/${arch}/include/asm asm,并令它指向../arch/${arch}/include/asm,即../arch/arm/include/asm,接下来:
    80. rm -f asm/arch
    81. if [ -z "${soc}" ] ; then
    82. ln -s ${LNPREFIX}arch-${cpu} asm/arch
    83. else
    84. ln -s ${LNPREFIX}arch-${soc} asm/arch
    85. fi
    86. //如果soc为空则执行,否则执行else语句
    87. if [ "${arch}" = "arm" ] ; then
    88. rm -f asm/proc
    89. ln -s ${LNPREFIX}proc-armv asm/proc
    90. fi
    91. //创建一些链接
    92. 接下来:
    93. //创建#include/config.mk
    94. # Create include file for Make
    95. #
    96. echo "ARCH = ${arch}" > config.mk
    97. echo "CPU = ${cpu}" >> config.mk
    98. echo "BOARD = ${board}" >> config.mk
    99. [ "${vendor}" ] && echo "VENDOR = ${vendor}" >> config.mk
    100. [ "${soc}" ] && echo "SOC = ${soc}" >> config.mk
    101. 经过这几句之后:ARCH = arm,CPU = arm920t,BOARD = smdk2410,VENDOR=samsung,SOC=s3c24x0.
    102. # Assign board directory to BOARDIR variable
    103. if [ -z "${vendor}" ] ; then
    104. BOARDDIR=${board}
    105. else
    106. BOARDDIR=${vendor}/${board}
    107. Fi
    108. //指定开发板目录,vendor为空,则为${board}否则为${vendor}/${board},这里就为samsung/smdk2410
    109. //创建开发板相关的头文件
    110. # Create board specific header file
    111. #
    112. if [ "$APPEND" = "yes" ] # Append to existing config file
    113. then
    114. echo >> config.h
    115. else
    116. > config.h # Create new config file
    117. fi
    118. echo "/* Automatically generated - do not edit */" >>config.h
    119. for i in ${TARGETS} ; do
    120. echo "#define CONFIG_MK_${i} 1" >>config.h ;
    121. done
    122. cat << EOF >> config.h
    123. #define CONFIG_BOARDDIR board/$BOARDDIR
    124. #include <config_defaults.h>
    125. #include <configs/${CONFIG_NAME}.h>
    126. #include <asm/config.h>
    127. EOF
    128. exit 0
    129. APPEND维持原值‘no’,config.h重新建立,为#include <configs/${CONFIG_NAME}.h>
    130. 即#include <configs/smdk2410.h>
    131. 总结:从以上过程可以看出,如果要在如果要在board目录下新建一个开发板<board_name> 的目录,或着在board目录的子目录下新建一个开发板<board_name> 的目录,需要在board.cfg配置文件中添加相应的信息,在#include/configs目录下也要建立一个文件<board_name.h>,里面存放的就是开发板board_name的配置信息。
    132. 这里的配置信息主要分为两类,从顶层的README可知:
    133. There are two classes of configuration variables:
    134. * Configuration _OPTIONS_:
    135. These are selectable by the user and have names beginning with
    136. "CONFIG_".
    137. //这些主要勇于选择CPU,SOC,开发板类型,设置系统时钟,选择设备驱动等
    138. * Configuration _SETTINGS_:
    139. These depend on the hardware etc. and should not be meddled with if
    140. you don't know what you're doing; they have names beginning with
    141. "CONFIG_SYS_".
    142. //因为UBOOT中几乎每个文件都要被编译和连接,但是这些文件是否包含有效的代码,则由宏开关来设置,这个就是这些宏开关。
  • 相关阅读:
    Java实现 LeetCode 382 链表随机节点
    Java实现 LeetCode 382 链表随机节点
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
    Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
    Linux下的iwpriv(iwlist、iwconfig)的简单应用
    OCX控件的注册卸载,以及判断是否注册
    .OCX、.dll文件注册命令Regsvr32的使用
  • 原文地址:https://www.cnblogs.com/yangv/p/5243039.html
Copyright © 2011-2022 走看看