您的位置:首页 > 其它

全志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:: 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

--------------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  u-boot 全志 配置流程