1.make Back210_config:配置编译的环境,CPU的类型等。
2.make :根_C据NAME_config,编译生成最后的u-boot.bin
1:make NAME_config:
查看顶层目录的Makefile文件
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep
%_config:: unconfig
@$(MKCONFIG) -A $(@:_config=)
%_config:其中%代表任意的字符,依赖于unconfig
unconfig:执行删除文件的命令
@$(MKCONFIG) -A $(@:_config=)
@代表不让用户看到这一行的执行过程
MKCONFIG定义是:MKCONFIG := $(SRCTREE)/mkconfig,
而SRCTREE的定义是 SRCTREE := $(CURDIR),可以看出MKCONFIG是当前目录下的一个名为mkconfig的文件
$@表示目标文件,在此代表%_config,其中_config用空代替,那么此时传入的参数为:
/mkconfig -A Back210
打开mkconfig文件,可以看出是一个shell脚本:#!/bin/sh -e
声明了几个变量
APPEND=no
BOARD_NAME=""
TARGETS=""
arch=""
cpu=""
board=""
vendor=""
soc=""
options=""
if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ;
检测传入的参数是否是2个,且参数1为-A,而传入的参数是 /mkconfig -A Back210,所以符合条件,
执行line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
echo "make: *** No rule to make target \`$2_config'. Stop." >&2
exit 1
}
${2}是Back210,
其中boards.cfg 为当前目录下的一个板级配置文件,打开看看
Target ARCH CPU Board name Vendor SoC Options
omap3_sdp3430 arm armv7 sdp3430 ti omap3
devkit8000 arm armv7 devkit8000 timll omap3
omap4_panda arm armv7 panda ti omap4
omap4_sdp4430 arm armv7 sdp4430 ti omap4
s5p_goni arm armv7 goni samsung s5pc1xx
Back210 arm armv7 Back samsung s5pc1xx
smdkc100 arm armv7 smdkc100 samsung s5pc1xx
这里只截取部分
三星的210是armv7的,架构是arm,板级名字为Back(因人而异),厂商的名字为samsung,SOC为s5pc1xx,options为空
好,重新回到mkconfig文件:
line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg`
这句话会到boards.cfg查找${2}的字符
假如不存在的话,打印make: *** No rule to make target..
假如存在的话,line = Back210 arm armv7 Back samsung s5pc1xx
执行 set ${line} 的作用是重新为shell脚本读入参数,参数是line
那么此时mkconfig 文件的参数重新变为:
boards.cfg:Target ARCH CPU Board name Vendor SoC Options
mkconfig :Back210 arm armv7 Back samsung s5pc1xx
${1} ${2} ${3} ${4} ${5} ${6}
接着往下:
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
$#为传入参数的个数,显然大于0,不符合条件,跳出,也不满足小于4和大于7.
往下:
CONFIG_NAME="${1%_config}"
[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"
CONFIG_NAME="${1%_config}"执行为结果是Back210
[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}": BOARD_NAME在之前的定义是"" ,会执行BOARD_NAME="${1%_config},同样BOARD_NAME=Back210
所以执行的结果是CONFIG_NAME=BOARD_NAME=Back210
往下:
arch="$2" #arch=arm
cpu="$3" #cpu=armv7
if [ "$4" = "-" ] ; then
board=${BOARD_NAME}
else
board="$4" #board=Back
fi
[ $# -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 #注意:一般没有第7个参数
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为顶层的Makefile目录下定义的,打开Makefile
Makefile:
# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export ARCH CPU BOARD VENDOR SOC
include/config.mk在首次解压并没有 ,所以 ARCH CPU BOARD VENDOR SOC 都为空。
回到mkconfig文件:
ARCH为空,所以[ "${ARCH}" -a "${ARCH}" != "${arch}" ] 返回值为1,
和C语言不同,当if语句中命令的状态退出码为0时,then语句执行,显然在这里不被执行。
接着往下:
if [ "$options" ] ; then
echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
echo "Configuring for ${BOARD_NAME} board..."
fi
options为空,返回码为1,所以执行Configuring for ${BOARD_NAME} board...:BOARD_NAME为Back210
接着往下:
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
SRCTREE 和 OBJTREE 是在顶层的Makefile中定义的,打开Makefile
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
SRCTREE=CURDIR,
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR)) 是当BUILD_DIR定义的时候,才等于BUILD_DIR,否则为CURDIR,
BUILD_DIR我们并没有执行类似于make O,所以OBJTREE=CURDIR
所以OBJTREE=SRCTREE=CURDIR。
回到mkconfig文件:
所以会执行else的分支:
cd ./include
rm -f asm
ln -s ../arch/${arch}/include/asm asm
fi
解析:
进入include的目录下
删除asm的文件
建立asm->../arch/${arch}/include/asm的软链接,其中 arch=arm 那么就是: asm ->../arch/arm/include/asm
往下:
rm -f asm/arch
if [ -z "${soc}" ] ; then
ln -s ${LNPREFIX}arch-${cpu} asm/arch
else
ln -s ${LNPREFIX}arch-${soc} asm/arch
fi
解析:
删除asm/arch
判断soc是否长度为0,显然不为0,执行else
建立asm/arch -> arch-s5pc1xx的软链接, 那么就是:../arch/arm/include/asm/arch -> arch-s5pc1xx
接着往下:
if [ "${arch}" = "arm" ] ; then
rm -f asm/proc
ln -s ${LNPREFIX}proc-armv asm/proc
fi
解析:
arch为arm,进入then
删除 asm/proc 即 那么就是:../arch/arch/arm/include/asm/proc
建立asm/proc -> proc-armv的软链接 那么就是:../arch/arm/include/asm/proc ->proc-armv
往下:
# 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
# Assign board directory to BOARDIR variable
if [ -z "${vendor}" ] ; then
BOARDDIR=${board}
else
BOARDDIR=${vendor}/${board}
fi
解析:
ARCH = arm >config.mk
CPU = armv7 >>config.mk
BOARD = Back >>config.mk
VENDOR = samsung >> config.mk
SOC = s5pc1xx >> config.mk
生成的config.mk(include目录下)文件
ARCH = arm
CPU = armv7
BOARD = Back
VENDOR = samsung
SOC = s5pc1xx
接着往下:
# 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
for i in ${TARGETS} ; do
i="`echo ${i} | sed '/=/ {s/=/\t/;q } ; { s/$/\t1/ }'`"
echo "#define CONFIG_${i}" >>config.h ;
done
解析:
APPEND 为no,
执行else分支 >config.h
"/* Automatically generated - do not edit */" >> config.h 追加/* Automatically generated - do not edit */到config.h文件
TARGETS为空,跳出for循环
接着往下:
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
exit 0
解析:
从cat << EOF >> config.h 下一句开始的内容追加到config.h,直到遇到EOF(EOF 不会追加)
退出
config.h文件:
* Automatically generated - do not edit */
#define CONFIG_BOARDDIR board/samsung/Back
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/Back210.h>
#include <asm/config.h>
至此第一阶段的配置工作完毕
总结一下:
@1:include/asm ->../arch/arm/include/asm
@2:arch/arm/include/asm/arch -> arch-s5pc1xx
@3:arch/arm/include/asm/proc ->proc-armv
@4:config.mk(include目录下)文件,类似于:
ARCH = arm
CPU = armv7
BOARD = Back
VENDOR = samsung
SOC = s5pc1xx
@5:config.h(include目录下) 文件,类似于:
* Automatically generated - do not edit */
#define CONFIG_BOARDDIR board/samsung/Back
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/Back210.h>
#include <asm/config.h>
uboot 2011-06 之顶层Makefile分析
最新推荐文章于 2024-05-10 19:30:09 发布