分析一个软件先从根目录Makefile分析.
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 6
EXTRAVERSION=
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL).$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h
HOSTARCH := $(shell uname -m | \
sed -e s/i.86/i386/ \
-e s/sun4u/sparc64/ \
-e s/arm.*/arm/ \
-e s/sa110/arm/ \
-e s/powerpc/ppc/ \
-e s/macppc/ppc/)
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
export HOSTARCH HOSTOS
上述代码无非是关于uboot版本号, VERSION_FILE将版本号存放在$(SRCTREE)include/version_autogenerated.h中, 编译后生成的文件代码为:
#define U_BOOT_VERSION "U-boot 1.1.6"
HOSTARCH获得当前体系结构并且将i.86替换为i386, arm.*替换为arm等等, 以此类推.
HOSTOS获得当前的操作系统并且讲大写转化为小写并且将cygwin.*替换为cygwin.
ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif
ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)
# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
# Verify if it was successful.
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif # ifneq ($(BUILD_DIR),)
上述代码指定了make时的命令行编译选项, 如果命令行制定了O="xxx/xxxx"选项则BUILD_DIR设为该目录, 如果BUILD_DIR环境变量不为空则尝试去创建输出目录, 最后检查创建的目录是否存在, 如果不存在则输出一段错误消息"output directory "$saved-output" does not exist".
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
ifeq ($(OBJTREE)/include/config.mk,$(wildcard $(OBJTREE)/include/config.mk))
# load ARCH, BOARD, and CPU configuration
include $(OBJTREE)/include/config.mk
export ARCH CPU BOARD VENDOR SOC
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-
endif
MKCONFIG := $(SRCTREE)/mkconfig, 所以调用mkconfig脚本, $(@:_config=)将smdk2410_config后面的_config替换为空,
所以该命令就解释为./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0, 然后来看mkconfig脚本文件有以下几行代码,
echo "ARCH = $2" > config.mk
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
该代码将ARCH CPU BOARD传入的arm arm920t smdk2410 写入config.mk文件中, 并且判断第五个和第六个参数是否为空, 如果不为空则也写入config.mk中第5个参数为空所以不写入, 第六个为s3c24x0所以SOC=s3c24x0.
现在来分析mkconfig的其他代码:
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"
[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1
若@#(传递给脚本的参数个数)大于0, 判断第一个参数由于我们的传递的参数没有-a -n --所以执行最后的break.
后续的代码判断BOARD_NAME是否为空, 为空的话则BOARD_NAME=$1(例子中就是arm).
后面判断传递的参数个数的限制, 个数只能在4-6之间, 如果不在则mkconfig脚本退出.
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
cd ./include
rm -f asm
ln -s asm-$2 asm
fi
rm -f asm-$2/arch
if [ -z "$6" -o "$6" = "NULL" ] ; then
ln -s ${LNPREFIX}arch-$3 asm-$2/arch
else
ln -s ${LNPREFIX}arch-$6 asm-$2/arch
fi
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi
if SRCTREE != OBJTREE; SRCTREE代表源码目录, OBJTREE代表生成的对象目录, 如果我们指定了BUILD_DIR变量则, OBJTREE = BUILD_DIR.此时OBJTREE可能不等于SRCTREE, 所以会执行if条件中的代码, 这里为了方便我们不指定BUILD_DIR变量, 则SRCTREE == OBJTREE, 所以执行else, else 代码进入include目录删除asm目录, 创建一个asm-$2(这里是arm)的软连接, 相当于假设我们定义#include <asm/xx.h> 头文件的实际目录就会是asm-arm/xx.h.
接下来: if [ -z "$6" -o ......] -z代表是否为0 -o 是逻辑或, 显然我们传递的第六个参数不为0 或者NULL, 所以我们执行else分支,
所以生成软连接arch-s3c24x0.