看了韦东山老师的视频收获真的很大。并且自己分析了一下uboot配置编译链接,虽然有很多是韦老师讲的,但是自己还是很有信心的。
下面是我分析基于s3c-u-boot-1.1.6来分析一下smdk6410的u_boot的配置过程。
当我们下载到新的u_boot以后,配置命令为:make smdk6410_config,打开顶层目录的Makefile,我们可以看见如下代码:
smdk6410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s3c64xx smdk6410 samsung s3c6410
当我们执行make smdk6410_config命令的时候,实际上执行的是:
@$(MKCONFIG) $(@:_config=) arm s3c64xx smdk6410 samsung s3c6410
下面我们来分析上面的代码:
MKCONFIG:在makefile下面搜索可知:MKCONFIG := $(SRCTREE)/mkconfig。
即MKCONFIG等于源码文件下有一个mkconfig。
$(@:_config=):$(@表示目标,即smdk6410_config;而_config=空格,即去掉smdk6410_config中的_config。所以上面的一句话就是:
源:@$(MKCONFIG) $(@:_config=) arm s3c64xx smdk6410 samsung s3c6410
实际:mkconfig smdk6410 arm s3c64xx smdk6410 samsung s3c6410
所以我们执行make smdk6410_config命令的时候,
最后实际就是执行mkconfig smdk6410 arm s3c64xx smdk6410 samsung s3c6410这一行命令。
下面我们打开mkconfig分析:
命令:mkconfig smdk6410 arm s3c64xx smdk6410 samsung s3c6410
$0$1$2$3$4$5$6
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
#下面是分析命令传递进来的参数中是否含有“--”,“-a”,“-n”,如果有执行相应的操作,
#但是现在没有,所以while这些不执行(即蓝色部分)
while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
*) break ;;
esac
done
#不执行上面的语句,继续执行下面的;
#下面的语句意思是如果BOARD_NAME定义了,则不执行
#如果没有定义则执行BOARD_NAME="$1",即BOARD_NAME=smdk6410
#而在前面BOARD_NAME=""没有定义,所以BOARD_NAME=smdk6410
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
#下面的语句中“$#”表示参数的个数
#意思就是如果参数的个数小于4个或者大于6个就退出。
#显然参数个数等于6,没有退出,不执行,继续执行
[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1
#没有退出,则执行下面语句,即打印Configuring for ${BOARD_NAME} board..."
echo "Configuring for ${BOARD_NAME} board..."
#
# Create link to architecture specific headers
#
#if的条件[ "$SRCTREE" != "$OBJTREE" ]是判断SRCTREE是否等于OBJTREE;
#在顶层makefile中查找SRCTREE和OBJTREE可以发现下面语句
#OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
#SRCTREE := $(CURDIR)
#而OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))的含义是如果
#定义BUILD_DIR,则OBJTREE=BUILD_DIR,否则OBJTREE=CURDIR
#显然没有定义BUILD_DIR,所以OBJTREE=CURDIR
#而语句SRCTREE := $(CURDIR)定义SRCTREE=CURDIR
#所以SRCTREE=OBJTREE,所以蓝色部分不考虑
if [ "$SRCTREE" != "$OBJTREE" ] ; then
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -f asm
ln -s ${SRCTREE}/include/asm-$2 asm
LNPREFIX="../../include2/asm/"
cd ../include
rm -rf asm-$2
rm -f asm
mkdir asm-$2
ln -s asm-$2 asm
else
#执行下面三句,就相当于建立一个链接文件asm,它指向$ 2(即arm )
#这样做的原因:
#当我们在源码中包含#include<asm-arm/type.h>的时候不需要改动,如果是i386呢?
#Avr32呢?所以简历这个链接是为了不需要我们总是修改代码
#则直接写#include<asm/type.h>即可
cd ./include
rm -f asm
ln -s asm-$2 asm
fi
#下面是删除asm-arm/arch目录
rm -f asm-$2/arch
#如果$6为空或者等于NULL则执行ln -s ${LNPREFIX}arch-$3 asm-$2/arch
#而实际$6=s3c6410,所以蓝色部分可以忽略。
if [ -z "$6" -o "$6" = "NULL" ] ; then
ln -s ${LNPREFIX}arch-$3 asm-$2/arch
else
#执行下面语句相当于在asm-arm($2)目录下面建立一个链接文件arch
#而链接文件arch的指向是arch-s3c6410($6)
ln -s ${LNPREFIX}arch-$6 asm-$2/arch
fi
#下面是通过判断“$3”来建立链接,$3=s3c64xx,所以蓝色部分忽略
# create link for s3c24xx SoC
if [ "$3" = "s3c24xx" ] ; then
rm -f regs.h
ln -s $6.h regs.h
rm -f asm-$2/arch
ln -s arch-$3 asm-$2/arch
fi
# create link for s3c64xx SoC
#执行下面语句
#建立链接regs.h-s3c6410($6)
#在asm-arm($2)目录下建立链接arch,指向:arch-s3c64xx ($3)
if [ "$3" = "s3c64xx" ] ; then
rm -f regs.h
ln -s $6.h regs.h
rm -f asm-$2/arch
ln -s arch-$3 asm-$2/arch
fi
#判断$2,$2=arm,所以执行在asm-arm($2)目录建立链接文件proc
#指向:proc-armv
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi
# create link for s3c64xx-mp SoC
#$3=s3c64xx,所以蓝色部分忽略
if [ "$3" = "s3c64xx-mp" ] ; then
rm -f regs.h
ln -s $6.h regs.h
rm -f asm-$2/arch
ln -s arch-$3 asm-$2/arch
fi
#
# Create include file for Make
#
#“>”表示新建立一个文件“>>”表示将内容追加进文件
#echo "ARCH = $2" > config.mk
#即表示新建立一个文件config.mk,并且将信息 "ARCH = arm "加入
#echo "CPU = $3" >> config.mk
#则是将信息"CPU = s3c64xx "追加进config.mk文件
#echo "BOARD = $4" >> config.mk
#则是将信息"BOARD = smdk6410 "追加进config.mk文件
#也就是config.mk文件的内容就是:
#ARCH = arm
#CPU = s3c64xx
#BOARD = smdk6410
echo "ARCH = $2" > config.mk
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
#如果“$5”、“$6”存在并且不等于NULL时
#将信息“VENDOR = samsung” 和“SOC = s3c6410”追加进config.mk文件
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
#
# Create board specific header file
#
#在前面APPEND=no,所以不成立,蓝色部分忽略
if [ "$APPEND" = "yes" ]# Append to existing config file
then
echo >> config.h
else
#执行下面语句,即新建立头文件config.h
> config.h # Create new config file
fi
#头文件config.h的内容就是:
#/* Automatically generated - do not edit */和#include <configs/smdk6410 .h>
#而是否支持某些命令就在smdk6410 .h里面修改。
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.h
exit 0