GNU ARM彙編--(十七)u-boot的makefile和mkconfig解讀
自己寫的bootloader可以引導kernel了,我以為曾經神祕的u-boot程式碼將變得毫無挑戰,然事實表明u-boot作為優秀的開原始碼,閱讀起來還是很有挑戰的,值得一讀!
閱讀碰到的頭等問題:Makefile和shell指令碼看不懂...
說起來做linux也很久了,Makefile和shell指令碼都接觸過,但真的都是略懂而已.因為公司的Makefile和shell簡單的一眼望的對穿,很初級的寫法,簡單的應用.再隨便在網上下個老外的開原始碼,那個Makefile和shell複雜啊.一不留神想起來了qt的qmake根據工程檔案生成的Makefile也是很簡單,但qmake是人家老外寫的.不說其他語言了,只看Makefile和shell,中外的差距就在那了.
這次準備移植u-boot到tq2440上,選用的u-boot版本是u-boot-2012.07.
下面是我對u-boot配置和編譯的makefile mkconfig config.mk等檔案的解讀,有些解讀我是在源檔上新增文字註釋的,有些是另外寫的,解讀難免有誤,若有讀者發現了,希望能夠指出,在下感激不盡!
在編譯u-boot的過程,就是make xxx_config和make兩步
以make smdk2410_config為例:
當以smdk2410_config為目標時,makefile中前面一些變數的定義和其他檔案的引用也是有的,這個在原檔中添加了有關注釋:
在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
echo [email protected]
$(MKCONFIG) -A $(@:_config=)
%是個萬用字元,make xxx_config都是這個目標.目標的依賴是unconfig,unconfig的命令是刪除一些檔案,而這些檔案正是從make xxx_config過程中產生的.unconfig就是清理配置的.
我們來看@$(MKCONFIG) -A $(@:_config=)
其實執行的是mkconfig -A smdk2410
我們可以在該行上面新增一行:echo [email protected]
則會輸出smdk2410_config,因為[email protected]就是指目標
$(@:_config=)是變數的替換引用
格式為“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是:替換變數“VAR”中所有“A”字元結尾的字為“B”結尾的字。
所以smdk2410_config末尾的_config去除了.
下面就是執行mkconfig指令碼了,mkconfig -A smdk2410
給出添加註釋的mkconfig檔案:
#!/bin/sh -e
# Script to create header files and links to configure
# U-Boot for a specific board.
#
# Parameters: Target Architecture CPU Board [VENDOR] [SOC]
#
# (C) 2002-2010 DENX Software Engineering, Wolfgang Denk <[email protected]>
#
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
TARGETS=""
arch=""
cpu=""
board=""
vendor=""
soc=""
options=""
echo $#
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}
echo ${line}
echo $#
# add default board name if needed
[ $# = 3 ] && set ${line} ${1}
#####################################
#我們執行指令碼的命令是mkconfig -A smdk2410,$#表示的是引數的個數,$1表示的是第一個引數
#line 就是在boards.cfg檔案中smdk2410的那行,而-i表示忽略大小寫
#在boards.cfg檔案中,有
#Target ARCH CPU Board name Vendor SoC Options
#smdk2410 arm arm920t - samsung s3c24x0
# set ${line}
# set也可用於在指令碼內部給出其執行引數,所以這個時候引數就變為"smdk2410 arm arm920t - samsung s3c24x0"
#這個時候引數個數就變成6個了
######################################
elif [ "${MAKEFLAGS+set}${MAKELEVEL+set}" = "setset" ] ; then
# only warn when using a config target in the Makefile
cat <<-EOF
warning: Please migrate to boards.cfg. Failure to do so will
mean removal of your board in the next release.
EOF
sleep 5
fi
echo $1
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
################################################
#因為$1的值為smdk2410,所以case找不到對應的
#################################################
[ $# -lt 4 ] && exit 1
[ $# -gt 7 ] && exit 1
##################################################
#對引數個數做檢查,小於4個或大於7個就退出
##################################################
# Strip all options and/or _config suffixes
CONFIG_NAME="${1%_config}"
####################
#CONFIG_NAME的值為smdk2410
#########################
echo config_
echo ${CONFIG_NAME}
[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"
echo board
echo ${BOARD_NAME}
###########################################
#如果BOARD_NAME在之前已經被設定了,就不做任何動作;如果為空,就設定為smdk2410.這裡設定為smdk2410
############################################
arch="$2"
cpu="$3"
if [ "$4" = "-" ] ; then
board=${BOARD_NAME}
else
board="$4"
fi
######################################################
#設定arch變數的值為arm
#cpu變數的值為arm920t
#因為第四個變數為"-",所以board變數的值為smdk2410
#######################################################
[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"
#############################################################
#設定verdor變數的值為samsung
#設定soc變數的值為s3c24x0
#############################################################
[ $# -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
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
}
#################################################
#因為我們的變數個數就是6個,這一段不執行
#################################################
echo ${ARCH}
echo ${arch}
if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then
echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2
exit 1
fi
####################################################
#ARCH是在頂層makefile中定義的,在此刻還是為空的。
#如果ARCH已經有值了,那麼就檢測ARCH和arch是否匹配了.
####################################################
if [ "$options" ] ; then
echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
echo "Configuring for ${BOARD_NAME} board..."
fi
###########################################################################
#我們沒有定義options變數,所以輸出Configuring for smdk2410 board...
###########################################################################
#
# Create link to architecture specific headers
#
echo ${SRCTREE}
echo ${OBJTREE}
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
#############################################################################
#在makefile中我們已經知道SRCTREE和OBJTREE都是當前目錄,所以這裡執行else
#進入./include目錄,刪除asm連結,並重新建立連結asm,指向arch/arm/include/asm
#############################################################################
rm -f asm/arch
#########################################################################
#刪除include目錄下的asm下的arch連結檔案
########################################################################
ss=
echo ${ss}
if [ -z "${ss}" ] ; then
echo "null"
else
echo "not null"
fi
echo ${LNPREFIX}
if [ -z "${soc}" ] ; then
ln -s ${LNPREFIX}arch-${cpu} asm/arch
else
ln -s ${LNPREFIX}arch-${soc} asm/arch
fi
##########################################################
#-z用來檢測字串是否為空,為空返回真
#這裡我們的soc不為空,執行else
#將asm/arch鏈向arch-s3c24x0,看一下arch-s3c24x0目錄,裡面都是s3c24x0相關的標頭檔案
##########################################################
if [ "${arch}" = "arm" ] ; then
rm -f asm/proc
ln -s ${LNPREFIX}proc-armv asm/proc
fi
###########################################################
#刪除asm/proc連結檔案
#將asm/proc鏈向proc-armv目錄,該目錄下是四個標頭檔案:domain.h\processor.h\ptrace.h\system.h
#############################################################
#
# 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
######################################################################
#上面幾句的作用在註釋中描述的很清楚
#include/config.mk的檔案如下:
#ARCH = arm
#CPU = arm920t
#BOARD = smdk2410
#VENDOR = samsung
#SOC = s3c24x0
######################################################################
# Assign board directory to BOARDIR variable
if [ -z "${vendor}" ] ; then
BOARDDIR=${board}
else
BOARDDIR=${vendor}/${board}
fi
echo ${BOARDDIR}
#######################################################################
#因為vendor變數不為空,所以執行else
#BOARDDIR的值為samsung/s3c24x0
########################################################################
#
# 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
########################################################################
#在檔案的最開頭可以看到APPEND為no,所以這裡我們在include資料夾下建立config.h檔案
#######################################################################
echo "/* Automatically generated - do not edit */" >>config.h
echo ${TARGETS}
for i in ${TARGETS} ; do
i="`echo ${i} | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'`"
echo "#define CONFIG_${i}" >>config.h ;
done
###################################################
#這裡我們TARGETS為空,上面不執行了
##################################################
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>
EOF
######################################################
#生成config.h檔案如下:
# /* Automatically generated - do not edit */
# #define CONFIG_SYS_ARCH "arm"
# #define CONFIG_SYS_CPU "arm920t"
# #define CONFIG_SYS_BOARD "smdk2410"
# #define CONFIG_SYS_VENDOR "samsung"
# #define CONFIG_SYS_SOC "s3c24x0"
# #define CONFIG_BOARDDIR board/samsung/smdk2410
# #include <config_cmd_defaults.h>
# #include <config_defaults.h>
# #include <configs/smdk2410.h>
# #include <asm/config.h>
# #include <config_fallbacks.h>
#####################################################
exit 0
make xxx_config後,主要的變化是多了幾個檔案:
1.include/asm --> arch/arm/include/arm
2.include/asm/arch --> arch-s3c24x0
3.include/asm/proc --> proc-armv
4.在include目錄下新建了config.mk檔案,檔案內容是ARCH CPU BOARD VENDOR SOC的定義
5.在include目錄下新建了config.h檔案
接著看make:
給出部分makefile中的註釋,主要是一些變數的定義:
VERSION = 2012
PATCHLEVEL = 07
SUBLEVEL =
EXTRAVERSION =
ifneq "$(SUBLEVEL)" ""
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
else
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL)$(EXTRAVERSION)
endif
################################
#定義U_BOOT_VERSION為2012.07
#####################################
TIMESTAMP_FILE = $(obj)include/generated/timestamp_autogenerated.h
VERSION_FILE = $(obj)include/generated/version_autogenerated.h
###############################
#因為obj為空,所以定義TIMESTAMP_FILE為include/generated/timestamp_autogenerated.h
#定義VERSION_FILE為include/generated/version_autogenerated.h
#****************
HOSTARCH := $(shell uname -m | \
sed -e s/i.86/x86/ \
-e s/sun4u/sparc64/ \
-e s/arm.*/arm/ \
-e s/sa110/arm/ \
-e s/ppc64/powerpc/ \
-e s/ppc/powerpc/ \
-e s/macppc/powerpc/\
-e s/sh.*/sh/)
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
# Set shell to bash if possible, otherwise fall back to sh
SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi; fi)
export HOSTARCH HOSTOS SHELL
#########################
#HOSTARCH為i686,HOSTOS為linux,SHELL為/bin/sh
#############################
# Deal with colliding definitions from tcsh etc.
VENDOR=
#########################################################################
# Allow for silent builds
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
###########################
#因為MAKEFLAGS變數的字串為空,找不到s,所以ifeq為真,XECHO = echo
###########################
#########################################################################
#
# U-boot build supports producing a object files to the separate external
# directory. Two use cases are supported:
#
# 1) Add O= to the make command line
# 'make O=/tmp/build all'
#
# 2) Set environement variable BUILD_DIR to point to the desired location
# 'export BUILD_DIR=/tmp/build'
# 'make'
#
# The second approach can also be used with a MAKEALL script
# 'export BUILD_DIR=/tmp/build'
# './MAKEALL'
#
# Command line 'O=' setting overrides BUILD_DIR environent variable.
#
# When none of the above methods is used the local build is performed and
# the object files are placed in the source directory.
#
ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif
#################################
#如果沒有在make命令列中定義O=/tmp之類的,那麼BUILD_DIR就為/tmp,否則為空。
#當使用make O=/tmp時,表明#ifdef O有定義,而$(origin O)返回的就是"command line"
#################################
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),)
#################################
#如果BUILD_DIR不為空,那麼這幾句就執行:
#首先,saved-output變數也是BUILD_DIR的值
#如果BUILD_DIR不存在,那麼就建立BUILD_DIR目錄
#檢測BUILD_DIR目錄是否成功建好了,如果有問題就輸出錯誤資訊
#################################
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SPLTREE := $(OBJTREE)/spl
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE SPLTREE
###########################################
#如果BUILD_DIR有值,那麼OBJTREE就是BUILD_DIR的值,如果BUILD_DIR為空,那麼OBJTREE就是CURDIR的值,$(CURDIR)時GNU Make內嵌的變數,是當前目錄。
#我們在make時候不加O=/tmp之類的引數,所以OBJTREE就是當前工作目錄,SPLTREE是當前工作目錄下的spl目錄,SRCTREE時當前工作目錄,TOPDIR也是當前目錄,LNDIR也是當前目錄。
##########################################
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
#############################################
#MKCONFIG定義為當前工作目錄下的mkconfig指令碼,並export
#############################################
ifneq ($(OBJTREE),$(SRCTREE))
REMOTE_BUILD := 1
export REMOTE_BUILD
endif
####################################################################
#在我們的執行中,OBJTREE和SRCTREE是相等的,所以不管了
###################################################################
# $(obj) and (src) are defined in config.mk but here in main Makefile
# we also need them before config.mk is included which is the case for
# some targets like unconfig, clean, clobber, distclean, etc.
ifneq ($(OBJTREE),$(SRCTREE))
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
endif
export obj src
#######################################
#可以先看下上面的註釋 因為兩個路徑相同,所以執行else
#########################################
# Make sure CDPATH settings don't interfere
unexport CDPATH
#########################################################################
# The "tools" are needed early, so put this first
# Don't include stuff already done in $(LIBS)
# The "examples" conditionally depend on U-Boot (say, when USE_PRIVATE_LIBGCC
# is "yes"), so compile examples after U-Boot is compiled.
SUBDIR_TOOLS = tools
SUBDIR_EXAMPLES = examples/standalone examples/api
SUBDIRS = $(SUBDIR_TOOLS)
###############################################
#定義SUBDIR_TOOLS SUBDIR_EXAMPLES 和 SUBDIRS
###############################################
.PHONY : $(SUBDIRS) $(VERSION_FILE) $(TIMESTAMP_FILE)
########################
#定義幾個偽目標
########################
ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
# Include autoconf.mk before config.mk so that the config options are available
# to all top level build files. We need the dummy all: target to prevent the
# dependency target in autoconf.mk.dep from being the default.
all:
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk
###################################################################################
#包含auoconf.mk和autoconf.mk.dep檔案
###################################################################################
ifndef CONFIG_SANDBOX
SUBDIRS += $(SUBDIR_EXAMPLES)
endif
###################################
#追加SUBDIRS 為"tools examples/standalone examples/api"
###################################
# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export ARCH CPU BOARD VENDOR SOC
#######################################
#包含include/config.mk檔案,這個檔案是在make xxx_config過程中產生的
#######################################
# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif
#######################################
#看看註釋就知道了,但是很顯示我們的HOSTARCH是x86的,目標時arm的
########################################
# load other configuration
include $(TOPDIR)/config.mk
#######################################
#包含uboot頂層目錄的config.mk檔案
#######################################
# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
# that (or fail if absent). Otherwise, search for a linker script in a
# standard location.
LDSCRIPT_MAKEFILE_DIR = $(dir $(LDSCRIPT))
##############################################################################
#用等號賦值的變數是遞迴方式擴充套件的變數。變數定義時,變數值中對其他變數的引用不會被替換展開;
#而是變數在引用它的地方替換展開的同時,它所引用的其它變數才會被一同替換展開。
#其優點是:
#這種型別變數在定義時,可以引用其它的之前沒有定義的變數(可能在後續部分定義,或者是通過make的命令列選項傳遞的變數)。
#LDSCRIPT變數就是後面才定義的
##############################################################################
ifndef LDSCRIPT
#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
ifdef CONFIG_SYS_LDSCRIPT
# need to strip off double quotes
LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
endif
endif
#######################################################################################
#如果定義了CONFIG_SYS_LDSCRIPT,將CONFIG_SYS_LDSCRIPT代表的字串去掉雙引號後賦值給LDSCRIPT變數
#這裡我們並沒有定義CONFIG_SYS_LDSCRIPT
#######################################################################################
# If there is no specified link script, we look in a number of places for it
ifndef LDSCRIPT
ifeq ($(CONFIG_NAND_U_BOOT),y)
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
ifeq ($(wildcard $(LDSCRIPT)),)
LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot-nand.lds
endif
endif
ifeq ($(wildcard $(LDSCRIPT)),)
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
endif
ifeq ($(wildcard $(LDSCRIPT)),)
LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot.lds
endif
ifeq ($(wildcard $(LDSCRIPT)),)
LDSCRIPT := $(TOPDIR)/arch/$(ARCH)/cpu/u-boot.lds
# We don't expect a Makefile here
LDSCRIPT_MAKEFILE_DIR =
endif
ifeq ($(wildcard $(LDSCRIPT)),)
$(error could not find linker script)
endif
endif
##########################################################################################
#註釋寫的很明確,如果沒有用CONFIG_SYS_LDSCRIPT指定LDSCRIPT,那麼就在幾個地方搜
#第一個地方:如果CONFIG_NAND_U_BOOT是y,就用u-boot-nand.lds 但是這裡沒有這個定義
#第一個地方沒找到,就找第二個地方:u-boot-2012.07/board/samsung/smdk2410 這個目錄沒有u-boot.lds檔案
#第二個地方沒找到,就找第三個地方:其中CPUDIR是在頂層的config.mk中定義的,在arch/arm/cpu/arm920t中找 這個目錄也沒有
#第三個地方沒找到,就找第四個地方:arch/arm/cpu/u-boot.lds,這裡就找到了!!!!
##########################################################################################
#########################################################################
# U-Boot objects....order is important (i.e. start must be first)
OBJS = $(CPUDIR)/start.o
ifeq ($(CPU),x86)
OBJS += $(CPUDIR)/start16.o
OBJS += $(CPUDIR)/resetvec.o
endif
ifeq ($(CPU),ppc4xx)
OBJS += $(CPUDIR)/resetvec.o
endif
ifeq ($(CPU),mpc85xx)
OBJS += $(CPUDIR)/resetvec.o
endif
OBJS := $(addprefix $(obj),$(OBJS))
#####################################
#為OBJS增加字首,其中obj在頂層目錄的config.mk中定義,這裡根據實際情況 OBJS就是 arch/arm/cpu/arm920t/start.o
#####################################
LIBS = lib/libgeneric.o
LIBS += lib/lzma/liblzma.o
LIBS += lib/lzo/liblzo.o
LIBS += lib/zlib/libz.o
ifeq ($(CONFIG_TIZEN),y)
LIBS += lib/tizen/libtizen.o
endif
LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \
"board/$(VENDOR)/common/lib$(VENDOR).o"; fi)
LIBS += $(CPUDIR)/lib$(CPU).o
ifdef SOC
LIBS += $(CPUDIR)/$(SOC)/lib$(SOC).o
endif
ifeq ($(CPU),ixp)
LIBS += arch/arm/cpu/ixp/npe/libnpe.o
endif
ifeq ($(CONFIG_OF_EMBED),y)
LIBS += dts/libdts.o
endif
LIBS += arch/$(ARCH)/lib/lib$(ARCH).o
LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \
fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \
fs/ubifs/libubifs.o
LIBS += net/libnet.o
LIBS += disk/libdisk.o
LIBS += drivers/bios_emulator/libatibiosemu.o
LIBS += drivers/block/libblock.o
LIBS += drivers/dma/libdma.o
LIBS += drivers/fpga/libfpga.o
LIBS += drivers/gpio/libgpio.o
LIBS += drivers/hwmon/libhwmon.o
LIBS += drivers/i2c/libi2c.o
LIBS += drivers/input/libinput.o
LIBS += drivers/misc/libmisc.o
LIBS += drivers/mmc/libmmc.o
LIBS += drivers/mtd/libmtd.o
LIBS += drivers/mtd/nand/libnand.o
LIBS += drivers/mtd/onenand/libonenand.o
LIBS += drivers/mtd/ubi/libubi.o
LIBS += drivers/mtd/spi/libspi_flash.o
LIBS += drivers/net/libnet.o
LIBS += drivers/net/phy/libphy.o
LIBS += drivers/pci/libpci.o
LIBS += drivers/pcmcia/libpcmcia.o
LIBS += drivers/power/libpower.o
LIBS += drivers/spi/libspi.o
ifeq ($(CPU),mpc83xx)
LIBS += drivers/qe/libqe.o
LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
endif
ifeq ($(CPU),mpc85xx)
LIBS += drivers/qe/libqe.o
LIBS += drivers/net/fm/libfm.o
LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
endif
ifeq ($(CPU),mpc86xx)
LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
endif
LIBS += drivers/rtc/librtc.o
LIBS += drivers/serial/libserial.o
ifeq ($(CONFIG_GENERIC_LPC_TPM),y)
LIBS += drivers/tpm/libtpm.o
endif
LIBS += drivers/twserial/libtws.o
LIBS += drivers/usb/eth/libusb_eth.o
LIBS += drivers/usb/gadget/libusb_gadget.o
LIBS += drivers/usb/host/libusb_host.o
LIBS += drivers/usb/musb/libusb_musb.o
LIBS += drivers/usb/phy/libusb_phy.o
LIBS += drivers/usb/ulpi/libusb_ulpi.o
LIBS += drivers/video/libvideo.o
LIBS += drivers/watchdog/libwatchdog.o
LIBS += common/libcommon.o
LIBS += lib/libfdt/libfdt.o
LIBS += api/libapi.o
LIBS += post/libpost.o
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
LIBS += $(CPUDIR)/omap-common/libomap-common.o
endif
ifeq ($(SOC),mx5)
LIBS += $(CPUDIR)/imx-common/libimx-common.o
endif
ifeq ($(SOC),mx6)
LIBS += $(CPUDIR)/imx-common/libimx-common.o
endif
ifeq ($(SOC),s5pc1xx)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.o
endif
ifeq ($(SOC),exynos)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.o
endif
LIBS := $(addprefix $(obj),$(sort $(LIBS)))
########################################
#將LIBS排序後為LIBS增加字首
#########################################
.PHONY : $(LIBS)
LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
###########################################
#為LIBBOARD增加字首,LIBBOARD就是board/samsung/smdk2410/libsmdk2410.o
###########################################
# Add GCC lib
ifdef USE_PRIVATE_LIBGCC
ifeq ("$(USE_PRIVATE_LIBGCC)", "yes")
PLATFORM_LIBGCC = $(OBJTREE)/arch/$(ARCH)/lib/libgcc.o
else
PLATFORM_LIBGCC = -L $(USE_PRIVATE_LIBGCC) -lgcc
endif
else
PLATFORM_LIBGCC := -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
endif
PLATFORM_LIBS += $(PLATFORM_LIBGCC)
export PLATFORM_LIBS
# Special flags for CPP when processing the linker script.
# Pass the version down so we can handle backwards compatibility
# on the fly.
LDPPFLAGS += \
-include $(TOPDIR)/include/u-boot/u-boot.lds.h \
-DCPUDIR=$(CPUDIR) \
$(shell $(LD) --version | \
sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
__OBJS := $(subst $(obj),,$(OBJS))
__LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))
#########################################################################
#########################################################################
ifneq ($(CONFIG_BOARD_SIZE_LIMIT),)
BOARD_SIZE_CHECK = \
@actual=`wc -c [email protected] | awk '{print $$1}'`; \
limit=$(CONFIG_BOARD_SIZE_LIMIT); \
if test $$actual -gt $$limit; then \
echo "[email protected] exceeds file size limit:"; \
echo " limit: $$limit bytes"; \
echo " actual: $$actual bytes"; \
echo " excess: $$((actual - limit)) bytes"; \
exit 1; \
fi
else
BOARD_SIZE_CHECK =
endif
這裡也給出頂層目錄下的config.mk檔案的註釋:
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, [email protected]
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
#########################################################################
ifeq ($(CURDIR),$(SRCTREE))
dir :=
else
dir := $(subst $(SRCTREE)/,,$(CURDIR))
endif
###########################################################################
#在頂層makefile中已經分析了CURDIR和SRCTREE都是當前目錄,所以這裡dir暫時為空
###########################################################################
ifneq ($(OBJTREE),$(SRCTREE))
# Create object files for SPL in a separate directory
ifeq ($(CONFIG_SPL_BUILD),y)
obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)
else
obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/)
endif
src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/)
$(shell mkdir -p $(obj))
else
# Create object files for SPL in a separate directory
ifeq ($(CONFIG_SPL_BUILD),y)
obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)
$(shell mkdir -p $(obj))
else
obj :=
endif
src :=
endif
########################################################################################
#首先OBJTREE和SRCTREE都是當前目錄,所以執行else
#查詢CONFIG_SPL_BUILD是否定義為y,在autoconf.mk中,並沒有這個定義,所以obj和src暫時也為空
########################################################################################
# clean the slate ...
PLATFORM_RELFLAGS =
PLATFORM_CPPFLAGS =
PLATFORM_LDFLAGS =
#########################################################################
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer \
$(HOSTCPPFLAGS)
HOSTSTRIP = strip
#
# Mac OS X / Darwin's C preprocessor is Apple specific. It
# generates numerous errors and warnings. We want to bypass it
# and use GNU C's cpp. To do this we pass the -traditional-cpp
# option to the compiler. Note that the -traditional-cpp flag
# DOES NOT have the same semantics as GNU C's flag, all it does
# is invoke the GNU preprocessor in stock ANSI/ISO C fashion.
#
# Apple's linker is similar, thanks to the new 2 stage linking
# multiple symbol definitions are treated as errors, hence the
# -multiply_defined suppress option to turn off this error.
#
ifeq ($(HOSTOS),darwin)
# get major and minor product version (e.g. '10' and '6' for Snow Leopard)
DARWIN_MAJOR_VERSION = $(shell sw_vers -productVersion | cut -f 1 -d '.')
DARWIN_MINOR_VERSION = $(shell sw_vers -productVersion | cut -f 2 -d '.')
os_x_before = $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \
$(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;)
# Snow Leopards build environment has no longer restrictions as described above
HOSTCC = $(call os_x_before, 10, 5, "cc", "gcc")
HOSTCFLAGS += $(call os_x_before, 10, 4, "-traditional-cpp")
HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress")
else
HOSTCC = gcc
endif
ifeq ($(HOSTOS),cygwin)
HOSTCFLAGS += -ansi
endif
# We build some files with extra pedantic flags to try to minimize things
# that won't build on some weird host compiler -- though there are lots of
# exceptions for files that aren't complaint.
HOSTCFLAGS_NOPED = $(filter-out -pedantic,$(HOSTCFLAGS))
HOSTCFLAGS += -pedantic
############################################################
#HOSTCFLAGS_NOPED是利用filter-out函式從HOSTCFLAGS中過濾掉-pedantic選項
#而HOSTCFLAGS追加上-pedantic選項
############################################################
#########################################################################
#
# Option checker, gcc version (courtesy linux kernel) to ensure
# only supported compiler options are used
#
CC_OPTIONS_CACHE_FILE := $(OBJTREE)/include/generated/cc_options.mk
CC_TEST_OFILE := $(OBJTREE)/include/generated/cc_test_file.o
-include $(CC_OPTIONS_CACHE_FILE)
#############################################################################
#定義編譯選項
#在cc_options.mk中有如下選項:
# CC_OPTIONS += -marm
# CC_OPTIONS += -mno-thumb-interwork
# CC_OPTIONS += -mapcs-32
# CC_OPTIONS += -malignment-traps
# CC_OPTIONS += -Wno-format-nonliteral
# CC_OPTIONS += -Wno-format-security
# CC_OPTIONS += -mabi=apcs-gnu
# CC_OPTIONS += -mabi=aapcs-linux
#############################################################################
cc-option-sys = $(shell mkdir -p $(dir $(CC_TEST_OFILE)); \
if $(CC) $(CFLAGS) $(1) -S -xc /dev/null -o $(CC_TEST_OFILE) \
> /dev/null 2>&1; then \
echo 'CC_OPTIONS += $(strip $1)' >> $(CC_OPTIONS_CACHE_FILE); \
echo "$(1)"; fi)
ifeq ($(CONFIG_CC_OPT_CACHE_DISABLE),y)
cc-option = $(strip $(if $(call cc-option-sys,$1),$1,$2))
else
cc-option = $(strip $(if $(findstring $1,$(CC_OPTIONS)),$1,\
$(if $(call cc-option-sys,$1),$1,$2)))
endif
###########################################################################################
#定義兩個函式,cc-option-sys被cc-option呼叫
#cc-option被後面的函式呼叫
############################################################################################
# cc-version
# Usage gcc-ver := $(call cc-version)
cc-version = $(shell $(SHELL) $(SRCTREE)/tools/gcc-version.sh $(CC))
##########################################################################################
#使用tools/gcc-version.sh指令碼來獲取編譯器的版本
#在頂層makefile中,有呼叫cc-version函式
##########################################################################################
#
# Include the make variables (CC, etc...)
#
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
LDR = $(CROSS_COMPILE)ldr
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB = $(CROSS_COMPILE)RANLIB
DTC = dtc
#########################################################################
#定義彙編器,聯結器,編譯器,打包工具,反彙編工具,值的注意的RANLIB的作用是在靜態庫有新增新的.o後,負責更新索引.
#########################################################################
# Load generated board configuration
sinclude $(OBJTREE)/include/autoconf.mk
sinclude $(OBJTREE)/include/config.mk
################################################################################################
#包上配置編譯時產生的autoconf.mk和config.mk檔案
################################################################################################
# Some architecture config.mk files need to know what CPUDIR is set to,
# so calculate CPUDIR before including ARCH/SOC/CPU config.mk files.
# Check if arch/$ARCH/cpu/$CPU exists, otherwise assume arch/$ARCH/cpu contains
# CPU-specific code.
CPUDIR=arch/$(ARCH)/cpu/$(CPU)
ifneq ($(SRCTREE)/$(CPUDIR),$(wildcard $(SRCTREE)/$(CPUDIR)))
CPUDIR=arch/$(ARCH)/cpu
endif
#################################################################################################
#定義CPUDIR為arch/arm/cpu/arm920t
#################################################################################################
sinclude $(TOPDIR)/arch/$(ARCH)/config.mk # include architecture dependend rules
sinclude $(TOPDIR)/$(CPUDIR)/config.mk # include CPU specific rules
##################################################################################################
#包上arch/arm/config.mk和/arch/arm/cpu/arm920t/config.mk檔案
##################################################################################################
ifdef SOC
sinclude $(TOPDIR)/$(CPUDIR)/$(SOC)/config.mk # include SoC specific rules
endif
######################################################################
#包上arch/arm/cpu/arm920t/s3c24x0/config.mk檔案
#####################################################################
ifdef VENDOR
BOARDDIR = $(VENDOR)/$(BOARD)
else
BOARDDIR = $(BOARD)
endif
ifdef BOARD
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules
endif
######################################################################################
#包上board/samsung/smdk2410/config.mk檔案
######################################################################################
#########################################################################
# We don't actually use $(ARFLAGS) anywhere anymore, so catch people
# who are porting old code to latest mainline but not updating $(AR).
ARFLAGS = $(error update your Makefile to use cmd_link_o_target and not AR)
RELFLAGS= $(PLATFORM_RELFLAGS)
DBGFLAGS= -g # -DDEBUG
OPTFLAGS= -Os #-fomit-frame-pointer
OBJCFLAGS += --gap-fill=0xff
gccincdir := $(shell $(CC) -print-file-name=include)
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \
-D__KERNEL__
# Enable garbage collection of un-used sections for SPL
ifeq ($(CONFIG_SPL_BUILD),y)
CPPFLAGS += -ffunction-sections -fdata-sections
LDFLAGS_FINAL += --gc-sections
endif
ifneq ($(CONFIG_SYS_TEXT_BASE),)
CPPFLAGS += -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE)
endif
ifneq ($(CONFIG_SPL_TEXT_BASE),)
CPPFLAGS += -DCONFIG_SPL_TEXT_BASE=$(CONFIG_SPL_TEXT_BASE)
endif
ifneq ($(CONFIG_SPL_PAD_TO),)
CPPFLAGS += -DCONFIG_SPL_PAD_TO=$(CONFIG_SPL_PAD_TO)
endif
ifeq ($(CONFIG_SPL_BUILD),y)
CPPFLAGS += -DCONFIG_SPL_BUILD
endif
ifneq ($(RESET_VECTOR_ADDRESS),)
CPPFLAGS += -DRESET_VECTOR_ADDRESS=$(RESET_VECTOR_ADDRESS)
endif
ifneq ($(OBJTREE),$(SRCTREE))
CPPFLAGS += -I$(OBJTREE)/include2 -I$(OBJTREE)/include
endif
CPPFLAGS += -I$(TOPDIR)/include
CPPFLAGS += -fno-builtin -ffreestanding -nostdinc \
-isystem $(gccincdir) -pipe $(PLATFORM_CPPFLAGS)
ifdef BUILD_TAG
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes \
-DBUILD_TAG='"$(BUILD_TAG)"'
else
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
endif
CFLAGS_SSP := $(call cc-option,-fno-stack-protector)
CFLAGS += $(CFLAGS_SSP)
# Some toolchains enable security related warning flags by default,
# but they don't make much sense in the u-boot world, so disable them.
CFLAGS_WARN := $(call cc-option,-Wno-format-nonliteral) \
$(call cc-option,-Wno-format-security)
CFLAGS += $(CFLAGS_WARN)
# Report stack usage if supported
CFLAGS_STACK := $(call cc-option,-fstack-usage)
CFLAGS += $(CFLAGS_STACK)
# $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g<format>
# option to the assembler.
AFLAGS_DEBUG :=
# turn jbsr into jsr for m68k
ifeq ($(ARCH),m68k)
ifeq ($(findstring 3.4,$(shell $(CC) --version)),3.4)
AFLAGS_DEBUG := -Wa,-gstabs,-S
endif
endif
AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS)
LDFLAGS += $(PLATFORM_LDFLAGS)
LDFLAGS_FINAL += -Bstatic
LDFLAGS_u-boot += -T $(obj)u-boot.lds $(LDFLAGS_FINAL)
ifneq ($(CONFIG_SYS_TEXT_BASE),)
LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
endif
LDFLAGS_u-boot-spl += -T $(obj)u-boot-spl.lds $(LDFLAGS_FINAL)
ifneq ($(CONFIG_SPL_TEXT_BASE),)
LDFLAGS_u-boot-spl += -Ttext $(CONFIG_SPL_TEXT_BASE)
endif
# Location of a usable BFD library, where we define "usable" as
# "built for ${HOST}, supports ${TARGET}". Sensible values are
# - When cross-compiling: the root of the cross-environment
# - Linux/ppc (native): /usr
# - NetBSD/ppc (native): you lose ... (must extract these from the
# binutils build directory, plus the native and U-Boot include
# files don't like each other)
#
# So far, this is used only by tools/gdb/Makefile.
ifeq ($(HOSTOS),darwin)
BFD_ROOT_DIR = /usr/local/tools
else
ifeq ($(HOSTARCH),$(ARCH))
# native
BFD_ROOT_DIR = /usr
else
#BFD_ROOT_DIR = /LinuxPPC/CDK # Linux/i386
#BFD_ROOT_DIR = /usr/pkg/cross # NetBSD/i386
BFD_ROOT_DIR = /opt/powerpc
endif
endif
#########################################################################
export HOSTCC HOSTCFLAGS HOSTLDFLAGS PEDCFLAGS HOSTSTRIP CROSS_COMPILE \
AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP MAKE
export CONFIG_SYS_TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS
#########################################################################
# Allow boards to use custom optimize flags on a per dir/file basis
BCURDIR = $(subst $(SRCTREE)/,,$(CURDIR:$(obj)%=%))
ALL_AFLAGS = $(AFLAGS) $(AFLAGS_$(BCURDIR)/$(@F)) $(AFLAGS_$(BCURDIR))
ALL_CFLAGS = $(CFLAGS) $(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR))
EXTRA_CPPFLAGS = $(CPPFLAGS_$(BCURDIR)/$(@F)) $(CPPFLAGS_$(BCURDIR))
ALL_CFLAGS += $(EXTRA_CPPFLAGS)
# The _DEP version uses the $< file target (for dependency generation)
# See rules.mk
EXTRA_CPPFLAGS_DEP = $(CPPFLAGS_$(BCURDIR)/$(addsuffix .o,$(basename $<))) \
$(CPPFLAGS_$(BCURDIR))
$(obj)%.s: %.S
$(CPP) $(ALL_AFLAGS) -o [email protected] $<
$(obj)%.o: %.S
$(CC) $(ALL_AFLAGS) -o [email protected] $< -c
$(obj)%.o: %.c
$(CC) $(ALL_CFLAGS) -o [email protected] $< -c
$(obj)%.i: %.c
$(CPP) $(ALL_CFLAGS) -o [email protected] $< -c
$(obj)%.s: %.c
$(CC) $(ALL_CFLAGS) -o [email protected] $< -c -S
#########################################################################
# If the list of objects to link is empty, just create an empty built-in.o
cmd_link_o_target = $(if $(strip $1),\
$(LD) $(LDFLAGS) -r -o [email protected] $1,\
rm -f [email protected]; $(AR) rcs [email protected] )
#########################################################################
主要是一些變數和函式的定義,編譯連結的引數設定以及依賴規則.
最後分析下make:
$(obj)include/autoconf.mk.dep: $(obj)include/config.h include/common.h
@$(XECHO) Generating [email protected] ; \
set -e ; \
: Generate the dependancies ; \
$(CC) -x c -DDO_DEPS_ONLY -M $(CFLAGS) $(CPPFLAGS) \
-MQ $(obj)include/autoconf.mk include/common.h > [email protected]
$(obj)include/autoconf.mk: $(obj)include/config.h
@$(XECHO) Generating [email protected] ; \
set -e ; \
: Extract the config macros ; \
$(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h | \
sed -n -f tools/scripts/define2mk.sed > [email protected] && \
mv [email protected] [email protected]
第一個是生成include/autoconf.mk的依賴檔案
第二個是根據include/config.h的檔案內容,利用tools/scripts/define2mk.sed指令碼將所有的CONFIG提取到autoconf.mk檔案中
終極目標是:ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map
u-boot.srec也是根據u-boot用objcopy工具搞出來的,不知的什麼作用
u-boot.bin也是根據u-boot用objcopy工具搞出來的,最終燒寫的二進位制bin檔
System.map是符號列表
$(obj)u-boot.bin: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< [email protected]
$(BOARD_SIZE_CHECK)
###################################################################################
#要得到最後的u-boot.bin,必須得到u-boot.u-boot.bin是最後要燒寫到板子上的二進位制bin檔
#利用objcopy來得到這個二進位制檔案([email protected]是規則的目標檔名,$<是規則的第一個依賴檔名)
#呼叫BOARD_SIZE_CHECK
###################################################################################
u-boot的依賴分析:
$(obj)u-boot:depend \
$(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
$(GEN_UBOOT)
u-boot 依賴depend $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
然後用$(GEN_UBOOT)生成最後的u-boot,GEN_UBOOT就是用ld連結的過程
a.看一下depend:
depend dep:$(TIMESTAMP_FILE) $(VERSION_FILE) \
$(obj)include/autoconf.mk \
$(obj)include/generated/generic-asm-offsets.h \
$(obj)include/generated/asm-offsets.h
for dir in $(SUBDIRS) $(CPUDIR) $(LDSCRIPT_MAKEFILE_DIR) ; do \
$(MAKE) -C $$dir _depend ; done
對$(SUBDIRS) $(CPUDIR) $(LDSCRIPT_MAKEFILE_DIR)目錄生成depend依賴檔案;
而_depend是在rules.mk中定義的,利用CC的-M選項生成依賴檔案.
b.看一下$(SUBDIR_TOOLS):
tools目錄
c.看一下$(OBJS):
$(OBJS):depend
$(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),[email protected],$(notdir [email protected]))
看下$(if $(REMOTE_BUILD),[email protected],$(notdir [email protected]))
因為$(REMOTE_BUILD)為空,所以返回的是$(notdir [email protected])的值;
因為[email protected]指的是規則的目標,所以就是$(OBJS),而$(OBJS)就是arch/arm/cpu/arm920t/start.o
notdir內嵌函式返回的檔名;所以返回start.o
執行makc -C arch/arm/cpu/arm920t start.o
d.$(LIBBOARD)
$(LIBBOARD):depend $(LIBS)
$(MAKE) -C $(dir $(subst $(obj),,[email protected]))
執行make -C board/samsung/smdk2410
e.$(LIBS)
$(LIBS):depend $(SUBDIR_TOOLS)
$(MAKE) -C $(dir $(subst $(obj),,[email protected]))
進入到LIBS包含的很多目錄,執行make,生成很多.a檔案.
f.$(LDSCRIPT)
$(LDSCRIPT):depend
$(MAKE) -C $(dir [email protected]) $(notdir [email protected])
在前面找連結指令碼時已然知曉LDSCRIPT就是arch/arm/cpu/u-boot.lds
執行make -C arch/arm/cpu u-boot.lds 這個目錄沒有makefile,這什麼意思?!!!
g.$(obj)u-boot.lds
$(obj)u-boot.lds: $(LDSCRIPT)
$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >[email protected]
這些就是編譯uboot的規則,分析的比較粗糙,在移植的過程中肯定還會遇到各式各樣的問題,在移植過程中再進一步深入並修正.