x210v3开发板u-boot-2012.10移植之三---mkconfig分析

时间:2022-07-13 17:11:22

                                                                         疯雨-版权所有,转载请注明【http://blog.csdn.net/u010346967】

编辑顶层的Makefile文件

root@crazyrain:/home/share/uboot/u-boot-2012.10# vim Makefile

搜索s5p_goni_config目标,没找到。那么就是说这个目标是由其他文件产生的,并不是直接在Makefile中给出的。那么搜索_config,发现如下代码

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

一下子愣是没看懂,%是个通配符,那么::这个是什么规则呢?表示没见过。百度双冒号规则,以下内容来自http://blog.chinaunix.net/uid-20536947-id-1931549.html

makefile双冒号规则

双冒号规则就是使用“::”代替普通规则的“:”得到的规则。当同一个文件作为多个规则的目标时,双冒号规则的处理和普通规则的处理过程完全不同(双冒号规则允许在多个规则中为同一个目标指定不同的重建目标的命令)。

首先需要明确的是:Makefile中,一个目标可以出现在多个规则中。但是这些规则必须是同一类型的规则,要么都是普通规则,要么都是双冒号规则。而不允许一个目标同时出现在两种不同类型的规则中。双冒号规则和普通规则的处理的不同点表现在以下几个方面:

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

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

我们来看一个例子,在我们的Makefile中包含以下两个规则:

 

Newprog :: foo.c

       $(CC) $(CFLAGS) $< -o $@

Newprog :: bar.c

       $(CC) $(CFLAGS) $< -o $@

 

如果“foo.c”文件被修改,执行make以后将根据“foo.c”文件重建目标“Newprog”。而如果“bar.c”被修改那么“Newprog”将根据“bar.c”被重建。回想一下,如果以上两个规则为普通规时出现的情况是什么?(make将会出错并提示错误信息)

当同一个目标出现在多个双冒号规则中时,规则的执行顺序和普通规则的执行顺序一样,按照其在Makefile中的书写顺序执行。

GNU make的双冒号规则给我们提供一种根据依赖的更新情况而执行不同的命令来重建同一目标的机制。一般这种需要的情况很少,所以双冒号规则的使用比较罕见。一般双冒号规则都需要定义命令,如果一个双冒号规则没有定义命令,在执行规则时将为其目标自动查找隐含规则。

搞清楚了,继续分析

@表示去回显,就是在控制台看不到命令信息。 $()表示引用变量,$(MKCONFIG)也就是引用MKCONFIG变量,搜索这个变量

MKCONFIG        := $(SRCTREE)/mkconfig
export MKCONFIG
SRCTREE         := $(CURDIR)
CURDIR是makefile的内嵌变量,显示当前路径

$(@:_config=)什么意思?

这里使用了Makefile中的替换引用规则,格式为“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是:替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。

类似常看到的例子 obj=$(srcfiles:%.c=%.o): 由.c得到对应的.o文件.

 @代表的是目标 s5p_goni_config, 那么$(@:_config=)就是将s5p_goni_config中的_config替换为空!得到s5p_goni

那么

@$(MKCONFIG) -A $(@:_config=)  就等价于./mkconfig -A s5p_goni
接下来分析mkconfig文件  vim 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-2010 DENX Software Engineering, Wolfgang Denk <wd@denx.de>
#


APPEND=no # Default: Create new config file
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=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
echo "make: *** No rule to make target \`$2_config'. Stop." >&2
exit 1
}


set ${line}
# add default board name if needed
[ $# = 3 ] && set ${line} ${1}
elif [ "${MAKEFLAGS+set}${MAKELEVEL+set}" = "setset" ] ; then
# only warn when using a config target in the Makefile
cat <<-EOF


warning: Please migrate to boards.cfg. Failure to do so will
mean removal of your board in the next release.


EOF
sleep 5
fi
*************************************
$#表示参数个数 ./mkconfig -A s5p_goni包含2个参数, $1表示第一个参数 -A, $2表示第二个参数 s5p_goni,
如果参数个数等于2并且第一个参数为-A 运行then后面的命令 这里完全满足 \是转义字符先不管。
egrep命令检索扩展的正则表达式(包括表达式组和可选项),-i不区分大小写,[:space:] 匹配空白字符,包括空格,tab,* 匹配0个或多个字符
egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg 也就是在boards.cfg文件中查找 s5p_goni 字符串
所以要建立自己的配置文件,必须在这里建立自己的配置项,在boards.cfg文件s5p_goni后添加一行:
x210v3 arm armv7 x210v3 samsung s5pc1xx
其实分析到这里就可以了,make x210v3_config 试试,果然
root@crazyrain:/home/share/uboot/u-boot-2012.10# make x210v3_config
Configuring for x210v3 board...
说明配置已经生效,不过make一下应该会出问题,因为还有很多文件没有建立。不管他make一下试试
/home/share/uboot/u-boot-2012.10/include/config.h:10: fatal error: configs/x210v3.h: No such file or directory
compilation terminated.
make: *** [lib/asm-offsets.s] 错误 1
先接着往下分析,后面再来解决这个问题
*******************************************************************************
while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%_config}" ; shift ;;
-t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;
*) break ;;
esac
done
********************************我是分割线*************************************
这里判断参数个数是否(gt是大于的意思)大于零,我们这里参数明显多于零,所以继续执行。由于我们的$1是"-A",所以直接退出,继续下面执行。
*******************************************************************************

[ $# -lt 4 ] && exit 1
[ $# -gt 7 ] && exit 1
********************************我是分割线*************************************
$#表示参数个数,如果参数个数小于4个大于7个就退出,我们得到六个参数:"x210v3 arm armv7 x210v3 samsung s5pc1xx",所以不会退出
*******************************************************************************
# Strip all options and/or _config suffixes
CONFIG_NAME="${1%_config}"


[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"


arch="$2"
cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'`
spl_cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $2}'`
if [ "$4" = "-" ] ; then
board=${BOARD_NAME}
else
board="$4"
fi
********************************我是分割线*************************************
CONFIG_NAME="${1%_config}" 去掉_config
[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}" 如果没定义BOARD_NAME,就BOARD_NAME=CONFIG_NAME
这里得到CONFIG_NAME为x210v3
BOARD_NAME为x210v3
arch="$2"及arm
cpu="$3"及armv7
board="$4"及x210v3
*******************************************************************************
[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"[ $# -gt 6 ] && [ "$7" != "-" ] && { # 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="${7%:*}" if [ "$tmp" ] ; then CONFIG_NAME="$tmp" fi # Check if we only have a colon... if [ "${tmp}" != "$7" ] ; then options=${7#*:} TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}" fi}
********************************我是分割线*************************************
vendor="$5"及samsung
soc="$6"及s5pc1xx
我们这里没有$7,这里的$7主要是来做开发板配置信息检查的,这里我们暂时不用关心。
*******************************************************************************
if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2 exit 1fi
********************************我是分割线*************************************
这里ARCH不为空并且ARCH和arch值都是arm,所以下面不这句话不打印,继续执行
*******************************************************************************
if [ "$options" ] ; then echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"else echo "Configuring for ${BOARD_NAME} board..."fi
********************************我是分割线*************************************
虽然我们这里没有取出options的值,但是options的值不为空,所以会打印信息:Configuring for x210v3 board ...
*******************************************************************************


#
# Create link to architecture specific headers
#
if [ "$SRCTREE" != "$OBJTREE" ] ; then
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -f asm
ln -s ${SRCTREE}/arch/${arch}/include/asm asm
LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/
cd ../include
mkdir -p asm
else
cd ./include
rm -f asm
ln -s ../arch/${arch}/include/asm asm
fi

rm -f asm/arch
********************************我是分割线*************************************
判断是否在源代码目录下编译Uboot,不是就执行下面,else就是表示是在源代码目录编译,并根据arch的值建立软链接asm,链接到arch/arm/include/asm,显然这里是在源代码目录
*******************************************************************************


if [ -z "${soc}" ] ; then
ln -s ${LNPREFIX}arch-${cpu} asm/arch
else
ln -s ${LNPREFIX}arch-${soc} asm/arch
fi
********************************我是分割线*************************************
这里判断soc是否有值,在arch/arm/include/asm建立软链接,arch -> arch-s5pc1xx
*******************************************************************************


if [ "${arch}" = "arm" ] ; then
rm -f asm/proc
ln -s ${LNPREFIX}proc-armv asm/proc
fi


********************************我是分割线*************************************
同上,proc -> proc-armv
*******************************************************************************

#
# Create include file for Make
#
( echo "ARCH = ${arch}"
if [ ! -z "$spl_cpu" ] ; then
echo 'ifeq ($(CONFIG_SPL_BUILD),y)'
echo "CPU = ${spl_cpu}"
echo "else"
echo "CPU = ${cpu}"
echo "endif"
else
echo "CPU = ${cpu}"
fi
echo "BOARD = ${board}"


[ "${vendor}" ] && echo "VENDOR = ${vendor}"
[ "${soc}" ] && echo "SOC = ${soc}"
exit 0 ) > config.mk
********************************我是分割线*************************************
! -z "$spl_cpu" 判断是否为空字符串 不是返回真,这里为空
在include目录下生成 config.mk,内容如下:
ARCH = arm
CPU = armv7
BOARD = x210v3
VENDOR = samsung
SOC = s5pc1xx
*******************************************************************************


# Assign board directory to BOARDIR variable
if [ -z "${vendor}" ] ; then
BOARDDIR=${board}
else
BOARDDIR=${vendor}/${board}
fi
********************************我是分割线*************************************
-z "${vendor}" 为0判断 显然不为0
BOARDDIR=samsung/x210v3
*******************************************************************************


#
# Create board specific header file
#
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
********************************我是分割线*************************************
APPEND值为no,所以建空文件config.h
*******************************************************************************


for i in ${TARGETS} ; do
i="`echo ${i} | sed '/=/ {s/=/ /;q; } ; { s/$/ 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


[ "${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
********************************我是分割线*************************************
向config.h追加信息,内容如下:
/* Automatically generated - do not edit */
#define CONFIG_BOARDDIR board/samsung/x210v3
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/x210v3.h>
#include <asm/config.h>
*******************************************************************************


exit 0