由于所找到的资料均是英语的,故此文也直接用英语。
Chapter 2 Uboot make file
2.1How to make uboot for arm architecture
To build uboot for arm architecture in the host machine, we need cross compiler.The default cross compiler in uboot is arm-linux-gcc, and we can use our own cross compiler. There are 2 ways to set our own cross compiler:
a.export CROSS_COMPILE=arm-none-linux-gnueabi-
b.Change the top make file of uboot by adding:
ifeq ($(ARCH),arm)
CROSS_COMPILE=arm-none-linux-gnueabi-
endif
just behind:
ifeq ($(HOSTARCH), $(ARCH))
CROSS_COMPILE?=
endif
To build uboot for arm architecture in the source directory (local build), we type the following command (cross compiler was set properly in the above step):
make distclean
make <board_type>_config
make all
To build uboot out of the source directory, we do:
export BUILD_DIR=~/project/uboot
make distclean
make<board_type>_config
make all
or
make O=~/project/uboot
make distclean
make <board_type>_config
make all
Note: O command line setting overrides BUILD_DIR environment variable.
To make the analysis easier, we build uboot in the source directory in the following sections.
2.2 Uboot make file outline
a.make <board_type>_config
It will pass the Target, Architecture, CPU, Board, [Vendor], [Soc] arguments tothe ./mkconfig (under the same directory of top makefile) script.
The./mkconfig script will create link: ./include/asm to the real arch'sinclude/asm.
It also creates ./include/config.mk and ./include/config.h. ./include/config.mk will be included by top Makefile, and ./include/config.h is the auto-generated header file for given board_type.
b.make all
1.make all will first update the ./include/autoconf.mk and./include/autoconf.mk.dep based on the file ./include/config.h generated by command make <board_type>_config.
./include/autoconf.mk.dep contains a rule, whose target is ./include/autoconf.mk, and prerequisites are all files included by ./include/common.h.
./include/autoconf.mk is the collection of macros startting with “CONFIG_” defined in./include/common.h and files included by ./include/common.h.
2. make all then includes ./include/config.mk and ./config.mk to decide src, objdirectory, and cross compile tools’ flags based on included specific arch, cpu,board, and soc’s config.mk, and pattern rules for various object files.
3.make all finally updates the all prerequisites of the target $(obj)uboot: depend, $(SUBDIR), $(OBJS), $(LIBBOARD), $(LIBS), $(LDSCRIPT),$(ojb)u-boot.lds, $(GEN_UBOOT) to update the global target $(obj)uboot.
2.3make <board_type>_config
2.3.1make <board_type>_config outline
Let's take smdk2410_config as example to analyze the progress of make<board_type>_config.
MKCONFIG := $(SRCTREE)/mkconfig
exportMKCONFIG
smdk2410_config: unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0
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
#Here unconfig doesn't have any prerequisites, and it isn't a real file, so it always will be updated (the target doesn't exist, and thus the recipe is always triggered), when we type makesmdk2410_config. It's better we declare unconfig as a phony target, but the uboot make file doesn't do this. Unconfig removes almost all files generated inthe process of building uboot.
In the recipe to update smdk2410_config target, $(MKCONFIG) will be expanded as the mkconfig under the top make file, which is a bash script file.
$(@:_config=)is equivalent to $(patsubst, %_config, %, $(@)), i.e. $(patsubst, %config, %,$@). It means replacing _config in the rule's target name by empty string, thus$(@:_config=) generates smdk2410.
So the recipe is invoked as following:
./mkconfigsmdk2410 arm arm920t smdk2410 samsung s3c24x0
2.3.2mkconfig script file
Now we analyze the bash script file line by line.
#!/bin/sh -e
# Script tocreate header files and links to configure
# U-Boot for aspecific board.
#
#Parameters: Target Architecture CPU Board [VENDOR] [SOC]
#
# (C)2002-2006 DENX Software Engineering, Wolfgang Denk <wd@denx.de>
#
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
TARGETS=""
while [ $# -gt0 ] ; 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
#This checks the argument options passed into the script. However, when we invoke mkconfig by make <board_type>_config, we don't pass any argumentoption. So, this part is not executed.
["${BOARD_NAME}" ] || BOARD_NAME="$1"
#This set BOARD_NAME to the board name argument.
[ $# -lt 4 ]&& exit 1
[ $# -gt 6 ]&& exit 1
#It checks the argument count, if it's < 4 or > 6, then exit.
if ["${ARCH}" -a "${ARCH}" != "$2" ]; then
echo "Failed: \$ARCH=${ARCH}, should be '$2'for ${BOARD_NAME}" 1>&2
exit 1
fi
#It checks whether the arch environment variable ARCH is equal to arch argumentor not. If not, exit.
echo"Configuring for ${BOARD_NAME} board..."
#
# Create linkto architecture specific headers
#
if ["$SRCTREE" != "$OBJTREE" ] ; then
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -f asm
ln -s ${SRCTREE}/arch/$2/include/asm asm
LNPREFIX=${SRCTREE}/arch/$2/include/asm/
cd ../include
rm -f asm
ln -s ${SRCTREE}/arch/$2/include/asm asm
else
cd ./include
rm -f asm
ln -s ../arch/$2/include/asm asm
fi
rm -f asm/arch
#For local build, it creates a link ./include/asm to ./arch/arm/include/asm. And remove the arch directory under ./include/asm. In fact, there is no arch under./arch/arm/include/asm.
if [ -z"$6" -o "$6" = "NULL" ] ; then
ln -s ${LNPREFIX}arch-$3 asm/arch
else
ln -s ${LNPREFIX}arch-$6 asm/arch
fi
#Here $6 is s3c24x0, so the else clause is executed. For local build, ${LNPREFIX} is empty, thus it creates a link ./include/asm/arch to ./include/asm/arch-s3c24x0.
if ["$2" = "arm" ] ; then
rm -f asm/proc
ln -s ${LNPREFIX}proc-armv asm/proc
fi
#If the architecture is arm, it creates a link ./include/asm/proc to ./include/asm/proc-armv.
#
# Createinclude file for Make
#
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
#Write the ARCH CPU BOARD VENDOR SOC variables into ./include/config.mk.
# Assign boarddirectory to BOARDIR variable
if [ -z"$5" -o "$5" = "NULL" ] ; then
BOARDDIR=$4
else
BOARDDIR=$5/$4
fi
#Set BOARDDIR to samsung/smdk2410.
#
# Create boardspecific header file
#
if ["$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else