全志sunxi u-boot 配置过程简析
2017-03-10 15:06
267 查看
基于u-boot-2014.01.tar.bz2(SUNXI 提供)
一:编译uboot,先是:make Cubieboard2_config,然后:make(编译)(也可以make Cubieboard2 CROSS_tools...,不仅会配置uboot还会make),那么make Cubieboard2_config(make Cubieboard2)到底做了什么?
在执行命令的时候,都直接和Makefile挂钩,打开uboot顶层目录下的Makefile,搜索发现了uboot的配置过程如下:(注意区别u-boot-1.1.6的)
可以看到%_config目标后面是双冒号,而我们平常看的只有一个冒号,这是Makefile 的双冒号规则,而平常我们见的单冒号就是普通规则。
Makefile中规定:一个目标可以出现在多个规则中。但是这些规则必须是同一类型的规则,要么都是普通规则,要么都是双冒号规则。而不允许一个目标同时出现在两种不同类型的规则中。双冒号规则和普通规则的处理的不同点表现在以下两方面:
1. 双冒号规则中,当依赖文件比目标更新时。规则将会被执行。对于一个没有依赖而只有命令行的双冒号规则,当引用此目标时,规则的命令将会被无条件执行。而普通规则,当规则的目标文件存在时,此规则的命令永远不会被执行(目标文件永远是最新的)。
2. 当同一个文件作为多个双冒号规则的目标时。这些不同的规则会被独立的处理,而不是像普通规则那样合并所有的依赖到一个目标文件。这就意味着对这些规则的处理就像多个不同的普通规则一样。就是说多个双冒号规则中的每一个的依赖文件被改变之后,make只执行此规则定义的命令,而其它的以这个文件作为目标的双冒号规则将不会被执行。
uboot从2010.09版本开始工程结构发生变化,关于板子的配置信息都独立出来放在了boards.cfg文件 在我们执行不同的“make <board_name>_config”时,都会执行
这个命令,但是uboot使用双冒号规则后,都会按照各自的<board_name>_config生成相应的目标文件,从而节省了Makefile的代码量。
(1).@的作用是:在执行这条命令的时候不进行显示;
(2).$(MKCONFIG)的作用是:取出变量MKCONFIG的值。变量MKCONFIG定义在该Makefile上面,具体如下:
(3).$(@:_config=)的作用是:将目标文件名字中含有的_config的部分用等号后面的字符替换掉,这里=后面为空,所以其效果就是把_config去掉。
综上所述:
执行make Cubieboard2_config,最终会执行如下命令:
mkconfig -A Cubieboard2
------------------------------------
$1 $2
二:
紧接着,分析mkconfig脚本文件,打开uboot根目录下面的mkconfig脚本文件,观看分析:
(1).贴出mkconfig
[align=left]******因为在UBOOT_TREE/spl/Makefile定义了CONFIG_SPL_BUILD,执行到这,config.mk为******:[/align]
[align=left] ARCH = arm[/align]
[align=left] CPU = armv7[/align]
[align=left] BOARD = Cubieboard2[/align]
[align=left] VENDOR = sunxi[/align]
[align=left] SOC =sunx[/align]
[align=left]*******************************************************************************[/align]
****************执行以上20条命令后,u-boot目录的include/configs内容如下:*********
/* Automatically generated - do not edit */
#define CONFIG_CUBIEBOARD2 1
#define CONFIG_SPL 1
#define CONFIG_SUNXI_GMAC 1
#define CONFIG_STATUSLED 244
#define CONFIG_STATUSLED1 245
#define CONFIG_FAST_MBUS 1
#define CONFIG_SYS_ARCH "arm"
#define CONFIG_SYS_CPU "armv7"
#define CONFIG_SYS_BOARD "sunxi"
#define CONFIG_SYS_TARGET "Cubieboard2"
#define CONFIG_SYS_SOC "sunxi"
#define CONFIG_BOARDDIR board/sunxi
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/sun7i.h>
#include <asm/config.h>
#include <config_fallbacks.h>
#include <config_uncmd_spl.h
--------------------------------------------
总结: make Cubieboard2做了3件事:
1. 更新config.mk
2. 创建链接文件
3. 根据boards.cfg生成$U-BOOT/include/config.h
--------------------------------------------
一:编译uboot,先是:make Cubieboard2_config,然后:make(编译)(也可以make Cubieboard2 CROSS_tools...,不仅会配置uboot还会make),那么make Cubieboard2_config(make Cubieboard2)到底做了什么?
在执行命令的时候,都直接和Makefile挂钩,打开uboot顶层目录下的Makefile,搜索发现了uboot的配置过程如下:(注意区别u-boot-1.1.6的)
%_config:: unconfig @$(MKCONFIG) -A $(@:_config=)
可以看到%_config目标后面是双冒号,而我们平常看的只有一个冒号,这是Makefile 的双冒号规则,而平常我们见的单冒号就是普通规则。
Makefile中规定:一个目标可以出现在多个规则中。但是这些规则必须是同一类型的规则,要么都是普通规则,要么都是双冒号规则。而不允许一个目标同时出现在两种不同类型的规则中。双冒号规则和普通规则的处理的不同点表现在以下两方面:
1. 双冒号规则中,当依赖文件比目标更新时。规则将会被执行。对于一个没有依赖而只有命令行的双冒号规则,当引用此目标时,规则的命令将会被无条件执行。而普通规则,当规则的目标文件存在时,此规则的命令永远不会被执行(目标文件永远是最新的)。
2. 当同一个文件作为多个双冒号规则的目标时。这些不同的规则会被独立的处理,而不是像普通规则那样合并所有的依赖到一个目标文件。这就意味着对这些规则的处理就像多个不同的普通规则一样。就是说多个双冒号规则中的每一个的依赖文件被改变之后,make只执行此规则定义的命令,而其它的以这个文件作为目标的双冒号规则将不会被执行。
uboot从2010.09版本开始工程结构发生变化,关于板子的配置信息都独立出来放在了boards.cfg文件 在我们执行不同的“make <board_name>_config”时,都会执行
%_config:: unconfig @$(MKCONFIG) -A $(@:_config=)
这个命令,但是uboot使用双冒号规则后,都会按照各自的<board_name>_config生成相应的目标文件,从而节省了Makefile的代码量。
(1).@的作用是:在执行这条命令的时候不进行显示;
(2).$(MKCONFIG)的作用是:取出变量MKCONFIG的值。变量MKCONFIG定义在该Makefile上面,具体如下:
MKCONFIG := $(SRCTREE)/mkconfig // 即当前目录下的mkconfig
(3).$(@:_config=)的作用是:将目标文件名字中含有的_config的部分用等号后面的字符替换掉,这里=后面为空,所以其效果就是把_config去掉。
综上所述:
执行make Cubieboard2_config,最终会执行如下命令:
mkconfig -A Cubieboard2
------------------------------------
$1 $2
二:
紧接着,分析mkconfig脚本文件,打开uboot根目录下面的mkconfig脚本文件,观看分析:
(1).贴出mkconfig
#!/bin/sh -e # Script to create header files and links to configure # U-Boot for a specific board. # # Parameters: Target Architecture CPU Board [VENDOR] [SOC] # # (C) 2002-2013 DENX Software Engineering, Wolfgang Denk <wd@denx.de> # # SPDX-License-Identifier: GPL-2.0+ # APPEND=no # 创建新的配置文件(默认) BOARD_NAME="" # Name to print in make output TARGETS="" #用于后面填充 arch="" cpu="" board="" vendor="" soc="" options="" if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then # Automatic mode line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' boards.cfg` // 将boards.cfg搜索第一个不为#注释符,$7以$2打头的行, 打印$1, $2, $3, $4, $5, $6, $7, $8 if [ -z "$line" ] ; then// line为空,这里不成立 echo "make: *** No rule to make target \`$2_config'. Stop." >&2 exit 1 fi set ${line} // line = $1, $2, $3, $4, $5, $6, $7, $8 // 在boards.cfg有# Status, Arch, CPU:SPLCPU, SoC, Vendor, Board name, Target, Options, Maintainers // ########################################################################################################### //line = Active arm armv7 sunxi - sunxi Cubieboard2 sun7i:CUBIEBOARD2,SPL,SUNXI_GMAC,STATUSLED=244,STATUSLED1=245,FAST_MBUS // $1 $2 $3 $4 $5 $6 $7 - $8 # add default board name if needed [ $# = 3 ] && set ${line} ${1}// 参数个数为3,这里也不成立 fi // 没有一个符合的case,继续往下运行 while [ $# -gt 0 ] ; do case "$1" in --) shift ; break ;; -a) shift ; APPEND=yes ;; -n) shift ; BOARD_NAME="${7%_config}" ; shift ;; -t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;; *) break ;; esac done [ $# -lt 7 ] && exit 1 // 不成立 [ $# -gt 8 ] && exit 1 // 不成立 # Strip all options and/or _config suffixes CONFIG_NAME="${7%_config}" // CONFIG_NAME=Cubieboard2 [ "${BOARD_NAME}" ] || BOARD_NAME="${7%_config}" // BOARD_NAME=Cubieboard arch="$2" // arch=arm cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'`// 用:隔开 $3 ,打印第一个域$1,如CPU:SPLCPU $1=CPU spl_cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $2}'`// $2=SPLCPU if [ "$6" = "-" ] ; then // $6 != - board=${BOARD_NAME} else board="$6" // board=sunxi fi [ "$5" != "-" ] && vendor="$5" // $5为空 [ "$4" != "-" ] && soc="$4" // soc=sunxi [ $# -gt 7 ] && [ "$8" != "-" ] && { // 成立 # check if we have a board config name in the options field # the options field mave have a board config name and a list # of options, both separated by a colon (':'); the options are # separated by commas (','). # # Check for board name tmp="${8%:*}" if [ "$tmp" ] ; then CONFIG_NAME="$tmp"// 去掉$8冒号之后的内容,CONFIG_NAME=sun7i fi # Check if we only have a colon... if [ "${tmp}" != "$8" ] ; then options=${8#*:} // 表示$8冒号后面的内容,options=CUBIEBOARD2,SPL,SUNXI_EMAC,STATUSLED=244 TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}"// TARGETS=CUBIEBOARD2,SPL,SUNXI_GMAC,STATUSLED=244,STATUSLED1=245,FAST_MBUS fi } if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then // ARCH=arch,不成立 echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2 exit 1 fi # # Test above needed aarch64, now we need arm # if [ "${arch}" = "aarch64" ]; then arch="arm" fi // 对于Cubieboard2,配置命令:make Cubieboard2 CROSS_COMPILE=arm-linux-gnueabihf- // 打印 Configuring for Cubieboard2 - Board: sun7i, Options: CUBIEBOARD2,SPL,SUNXI_EMAC,STATUSLED=244 if [ "$options" ] ; then echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}" else echo "Configuring for ${BOARD_NAME} board..." fi # # 创建链接指向架构相关文件 # if [ "$SRCTREE" != "$OBJTREE" ] ; then // $SRCTREE" = "$OBJTREE,不执行这句 mkdir -p ${OBJTREE}/include LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/ cd ${OBJTREE}/include mkdir -p asm else cd arch/${arch}/include // cd arch/arm/include fi rm -f asm/arch if [ -z "${soc}" ] ; then // soc成立, 执行 ln -s ${LNPREFIX}arch-${cpu} asm/arch // 创建asm/arch指向arch-sunxi else ln -s ${LNPREFIX}arch-${soc} asm/arch fi if [ "${arch}" = "arm" ] ; then rm -f asm/proc ln -s ${LNPREFIX}proc-armv asm/proc // 创建asm/proc指向proc-armv fi if [ "$SRCTREE" = "$OBJTREE" ] ; then cd ${SRCTREE}/include // 进到根目录的include fi # # Create include file for Make # ( echo "ARCH = ${arch}" // ARCH=arm if [ ! -z "$spl_cpu" ] ; then echo 'ifeq ($(CONFIG_SPL_BUILD),y)'// if CONFIG_SPL_BUILD=y echo "CPU = ${spl_cpu}" // CPU=armv7 echo "else" echo "CPU = ${cpu}" // CPU=armv7 echo "endif" else echo "CPU = ${cpu}" fi echo "BOARD = ${board}" // BOARD=Cubieboard2 [ "${vendor}" ] && echo "VENDOR = ${vendor}"// VENDOR=sunxi [ "${soc}" ] && echo "SOC = ${soc}" // SOC=sunxi exit 0 ) > config.mk // 将以上内容加入config.mk
# Assign board directory to BOARDIR variable if [ -z "${vendor}" ] ; then BOARDDIR=${board} // BOARDDIR=sunxi else BOARDDIR=${vendor}/${board} fi # # 创建板级的头文件 # if [ "$APPEND" = "yes" ] # Append to existing config file// APEND=NO,不成立 往下走 then echo >> config.h else > config.h # 创建config.h fi echo "/* Automatically generated - do not edit */" >>config.h for i in ${TARGETS} ; do // 从board.cfg可知TARGETS i="`echo ${i} | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'`"// 如果TARGETS冒号后有变量,对于未赋值变量,统一赋值为1,定义了的,维持原值不变 echo "#define CONFIG_${i}" >>config.h ; done echo "#define CONFIG_SYS_ARCH \"${arch}\"" >> config.h echo "#define CONFIG_SYS_CPU \"${cpu}\"" >> config.h echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h echo "#define CONFIG_SYS_TARGET \"${BOARD_NAME}\"" >> config.h [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h [ "${soc}" ] && echo "#define CONFIG_SYS_SOC \"${soc}\"" >> config.h cat << EOF >> config.h #define CONFIG_BOARDDIR board/$BOARDDIR #include <config_cmd_defaults.h> #include <config_defaults.h> #include <configs/${CONFIG_NAME}.h> #include <asm/config.h> #include <config_fallbacks.h> #include <config_uncmd_spl.h> EOF
[align=left]******因为在UBOOT_TREE/spl/Makefile定义了CONFIG_SPL_BUILD,执行到这,config.mk为******:[/align]
[align=left] ARCH = arm[/align]
[align=left] CPU = armv7[/align]
[align=left] BOARD = Cubieboard2[/align]
[align=left] VENDOR = sunxi[/align]
[align=left] SOC =sunx[/align]
[align=left]*******************************************************************************[/align]
****************执行以上20条命令后,u-boot目录的include/configs内容如下:*********
/* Automatically generated - do not edit */
#define CONFIG_CUBIEBOARD2 1
#define CONFIG_SPL 1
#define CONFIG_SUNXI_GMAC 1
#define CONFIG_STATUSLED 244
#define CONFIG_STATUSLED1 245
#define CONFIG_FAST_MBUS 1
#define CONFIG_SYS_ARCH "arm"
#define CONFIG_SYS_CPU "armv7"
#define CONFIG_SYS_BOARD "sunxi"
#define CONFIG_SYS_TARGET "Cubieboard2"
#define CONFIG_SYS_SOC "sunxi"
#define CONFIG_BOARDDIR board/sunxi
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/sun7i.h>
#include <asm/config.h>
#include <config_fallbacks.h>
#include <config_uncmd_spl.h
--------------------------------------------
总结: make Cubieboard2做了3件事:
1. 更新config.mk
2. 创建链接文件
3. 根据boards.cfg生成$U-BOOT/include/config.h
--------------------------------------------
相关文章推荐
- 多处转载综合:UBoot配置过程(顶层Makefile)
- U-Boot配置过程
- U-Boot--配置过程分析
- U-Boot的配置、编译、连接过程
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——配置过程(三)
- 移植uboot-1.1.6到勤研2440之二移植支持Nand Flash(和精智2440接近,仿照100ask24x0_config配置,重现韦东山的uboot-1.1.6_patch过程)
- u-boot-2012.10分析一配置过程
- u-boot的配置过程
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——配置过程(三)
- u-boot配置和编译过程浅析
- U-boot 编译学习---配置过程
- U-Boot的配置、编译、连接过程
- U-boot分析第1章------------------Makefile(配置过程)
- u-boot配置过程分析(ARM)
- U-BOOT配置编译全过程
- u-boot-2012.04.01的配置编译过程分析.doc
- u-boot-2012.10分析一配置过程
- U-BOOT配置过程
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——配置过程(二)
- U-Boot的配置、编译、连接过程