作者:冯老师,华清远见嵌入式学院讲师。
编译u-boot的步骤为:
$ make distclean
$ make fsc100_config
$ make
在u-boot执行make之前,会完成配置过程,make fsc100_config,这个目标是调用uboot根目录下的mkconfig文件。分析过程如下:
make fsc100_config,在Makefile中搜索_config,看到了如下内容:
makefile中有个这样的表达方式:$(A:patternA=patternB)。意思就是将 A中 patternA格式的字符用patternB来代替。回归$(@:_config),@代表输入的参数, 即:fsc100_config ,patternA是_config,patternB是空的。说白了就是将fsc100_config的 _config去掉。 $(@:_config=)的作用:替换功能,smdkc100_config替换成了smdkc100
$(MKCONFIG) –A fsc100
继续找MKCONFIG变量:
CURDIR是make的内嵌变量,自动设置为当前目录
$(MKCONFIG) –A fsc100最终相当于u-boot-samsung/mkconfig –A fsc100
接下来分析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
***$#表示输入进来的参数个数,make –A fsc100,此时,$#为2, 且$1是-A,所以条件成立
# Automatic mode
line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
echo "make: *** No rule to make target \`$2_config'. Stop." >&2
exit 1
}
***搜索boards.cfg文件,把含义fsc100的行,赋给了line变量,此时line变量的值为
***fsc100 arm armv7 fsc100 samsung s5pc1xx
set ${line}
***此处,把fsc100 arm armv7 fsc100 samsung s5pc1xx分别赋给了$1 $2 $3 $4 $5 $6
# 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
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
[ $# -lt 4 ] && exit 1
[ $# -gt 7 ] && exit 1
***以上代码中的条件都不成立,没有执行
# Strip all options and/or _config suffixes
CONFIG_NAME="${1%_config}"
***${1%_config}的作用是,如果$1变量结尾是_config,就去掉_config, $1的值是fsc100,CONFIG_NAME变量被赋值为fsc100.注意此处假如$1是fsc100_config_config,被赋值fsc100_config,只去1个。
[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"
***BOARD_NAME被赋值为,fsc100
arch="$2"
***arch赋值为arm
cpu="$3"
***cpu赋值为armv7
if [ "$4" = "-" ] ; then
board=${BOARD_NAME}
else
board="$4"
fi
***board赋值为fsc100
[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
***vendor赋值为samsung
[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"
***soc赋值为s5pc1xx
[ $# -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
}
***条件不成立,此处代码不执行
if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then
echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2
exit 1
fi
*** 判断ARCH是否存在,而且若存在,是否等于arch,若不成立,报错
if [ "$options" ] ; then
echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
echo "Configuring for ${BOARD_NAME} board..."
fi
***此处代码不执行
#
# Create link to architecture specific headers
#
if [ "$SRCTREE" != "$OBJTREE" ] ; then
***判断SRCTREE和OBJTREE是否一致,这两个目录都指的是u-boot-samsung,所以条件不成立
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
***删除include/asm/arch文件夹
if [ -z "${soc}" ] ; then
ln -s ${LNPREFIX}arch-${cpu} asm/arch
else
ln -s ${LNPREFIX}arch-${soc} asm/arch
***建立链接include/asm/arch到arch-s5pc1xx
fi
if [ "${arch}" = "arm" ] ; then
rm -f asm/proc
ln -s ${LNPREFIX}proc-armv asm/proc
***建立链接asm/proc到proc-armv
fi
#
# Create include file for Make
#
echo "ARCH = ${arch}" > config.mk
echo "CPU = ${cpu}" >> config.mk
echo "BOARD = ${board}" >> config.mk
[ "${vendor}" ] && echo "VENDOR = ${vendor}" >> config.mk
[ "${soc}" ] && echo "SOC = ${soc}" >> config.mk
***创建顶层包含的include/config.mk文件,内容为:ARCH=arm CPU=armv7 BOARD=fsc100 VENDOR=samsung SOC=s5pc1xx
# Assign board directory to BOARDIR variable
if [ -z "${vendor}" ] ; then
BOARDDIR=${board}
else
BOARDDIR=${vendor}/${board}
***BOARDDIR的定义为:samsung/fsc100
fi
#
# Create board specific header file
#
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file
***创建空文档config.h
fi
echo "/* Automatically generated - do not edit */" >>config.h
for i in ${TARGETS} ; do
i="`echo ${i} | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'`"
echo "#define CONFIG_${i}" >>config.h ;
done
***${TARGETS}为空,不执行
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>
EOF
***写config.h文件,EOF是分隔符,前后两个EOF中间的内容被写入了config.h文件
exit 0
总结:mkconfig文件,建了两个新文件config.h和config.mk。
在include/asm目录下建立两个链接文件arch->arch-s5pc1xx proc->proc-armv