了解u-boot的童靴都清楚u-boot.bin的生成分為兩個步驟:配置和編譯。下面我們先來說一下配置的過程,執(zhí)行的命令是
make -C $BOOTLDR_PATH ARCH=arm CROSS_COMPILE=$CROSS_COMPILER_KERNEL_PREFIX s3c2440_config
這條指令的意思是進入到$BOOTLDR_PATH目錄,執(zhí)行make,指定芯片架構(gòu)ARCH為ARM,指定編譯工具鏈CROSS_COMPILE,目標是s3c2440_config。
打開boot目錄下的Makefile,大概1000行,還是比較簡單的。搜索目標s3c2440_config:,沒找到,搜索_config:,找到了
%_config:: unconfig
@$(MKCONFIG) -A $(@:_config=)
注意
_config:最后的:號,因為這個可以去除掉全部非目標的搜索記錄。
嗯,就是這里,%表示通配符,也就說執(zhí)行make s3c2440_config和make xxxxx_config目標都是這個。依賴目標是unconfig,搜索unconfig:。
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
這是一個偽目標,所做的動作是刪除生成的中間文件。繼續(xù)看命令
@$(MKCONFIG) -A $(@:_config=)`
找到MKCONFIG的定義
SRCTREE := $(CURDIR)
MKCONFIG := $(SRCTREE)/mkconfig
CURDIR是Makefile的內(nèi)嵌變量,表示當前目錄。$(@:_config=)表示將$@中的_config替換為空,也就是說上面這條命令等價于$(SRCTREE)/mkconfig -A s3c2440,看樣子重點是文件$(SRCTREE)/mkconfig。打開文件mkconfig,上來就是判斷,這在shell腳本中是非常常見的。
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}
fi
當入?yún)?shù)目為2,并且第一個入?yún)?code>-A時,line等于egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg的結(jié)果,實際上后面這個就是將文件boards.cfg中含有s3c2440字符的一行賦值給line,line的內(nèi)容是smdk2440 arm arm920t - samsung s3c24x0。重點是下面一句,set ${line},重新設(shè)置$1等等。下面就是一些賦值行為
CONFIG_NAME="${1%_config}" # $1為smdk2440,去除$1中的_config還是smdk2440
BOARD_NAME="${1%_config}"
arch="$2" # 等于arm
cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'` # 等于arm920t
board=${BOARD_NAME}
vendor=$5 # 等于samsung
soc=$6 # 等于s3c24x0
下面執(zhí)行的是一些創(chuàng)建軟鏈接的行為
cd ./include
rm -f asm
ln -s ../arch/${arch}/include/asm asm # 創(chuàng)建軟鏈接 asm -> ../arch/arm/include/asm
rm -f asm/arch
ln -s ${LNPREFIX}arch-${soc} asm/arch # 創(chuàng)建軟鏈接 arch -> arch-s3c24x0
rm -f asm/proc
ln -s ${LNPREFIX}proc-armv asm/proc # 創(chuàng)建軟鏈接 proc -> proc-armv
下面將創(chuàng)建文件include/config.mk
( 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
向include/config.mk寫入
ARCH = arm
CPU = arm920t
BOARD = smdk2440
VENDOR = samsung
SOC = s3c24x0
BOARDDIR=${vendor}/${board} # 等于samsung/smdk2440
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/=/ /;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
上面這段生成文件include/config.h,并寫入
/* Automatically generated - do not edit */
#define CONFIG_SYS_ARCH "arm"
#define CONFIG_SYS_CPU "arm920t"
#define CONFIG_SYS_BOARD "smdk2440"
#define CONFIG_SYS_VENDOR "samsung"
#define CONFIG_BOARDDIR board/samsung/smdk2440
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/smdk2440.h>
#include <asm/config.h>
#include <config_fallbacks.h>
#include <config_uncmd_spl.h>
根據(jù)上面的分析我們可以知道boot的配置過程
- 根據(jù)芯片在
boards.cfg查找到此款芯片的相關(guān)信息; - 對
include/asm下的一些目錄進行軟鏈接操作; - 將芯片的相關(guān)信息寫入
include/config.mk和include/config.h
include/config.mk是后面編譯時需要使用的,include/config.h則是代碼中的。