自己寫的bootloader可以引導(dǎo)kernel了,我以為曾經(jīng)神秘的u-boot代碼將變得毫無挑戰(zhàn),然事實(shí)表明u-boot作為優(yōu)秀的開源代碼,閱讀起來還是很有挑戰(zhàn)的,值得一讀!
閱讀碰到的頭等問題:Makefile和shell腳本看不懂...
說起來做linux也很久了,Makefile和shell腳本都接觸過,但真的都是略懂而已.因?yàn)楣镜腗akefile和shell簡單的一眼望的對穿,很初級的寫法,簡單的應(yīng)用.再隨便在網(wǎng)上下個老外的開源代碼,那個Makefile和shell復(fù)雜啊.一不留神想起來了qt的qmake根據(jù)工程文件生成的Makefile也是很簡單,但qmake是人家老外寫的.不說其他語言了,只看Makefile和shell,中外的差距就在那了.
這次準(zhǔn)備移植u-boot到tq2440上,選用的u-boot版本是u-boot-2012.07.
下面是我對u-boot配置和編譯的makefile mkconfig config.mk等文件的解讀,有些解讀我是在源檔上添加文字注釋的,有些是另外寫的,解讀難免有誤,若有讀者發(fā)現(xiàn)了,希望能夠指出,在下感激不盡!
在編譯u-boot的過程,就是make xxx_config和make兩步
以make smdk2410_config為例:
當(dāng)以smdk2410_config為目標(biāo)時,makefile中前面一些變量的定義和其他文件的引用也是有的,這個在原檔中添加了有關(guān)注釋:
在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 $@
- $(MKCONFIG) -A $(@:_config=)
%是個通配符,make xxx_config都是這個目標(biāo).目標(biāo)的依賴是unconfig,unconfig的命令是刪除一些文件,而這些文件正是從make xxx_config過程中產(chǎn)生的.unconfig就是清理配置的.
我們來看@$(MKCONFIG) -A $(@:_config=)
其實(shí)執(zhí)行的是mkconfig -A smdk2410
我們可以在該行上面添加一行:echo $@
則會輸出smdk2410_config,因?yàn)?@就是指目標(biāo)
$(@:_config=)是變量的替換引用
格式為“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是:替換變量“VAR”中所有“A”字符結(jié)尾的字為“B”結(jié)尾的字。
所以smdk2410_config末尾的_config去除了.
下面就是執(zhí)行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 <wd@denx.de>
- #
-
- 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}
- #####################################
- #我們執(zhí)行腳本的命令是mkconfig -A smdk2410,$#表示的是參數(shù)的個數(shù),$1表示的是第一個參數(shù)
- #line 就是在boards.cfg文件中smdk2410的那行,而-i表示忽略大小寫
- #在boards.cfg文件中,有
- #Target ARCH CPU Board name Vendor SoC Options
- #smdk2410 arm arm920t - samsung s3c24x0
- # set ${line}
- # set也可用于在腳本內(nèi)部給出其運(yùn)行參數(shù),所以這個時候參數(shù)就變?yōu)?smdk2410 arm arm920t - samsung s3c24x0"
- #這個時候參數(shù)個數(shù)就變成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
- ################################################
- #因?yàn)?1的值為smdk2410,所以case找不到對應(yīng)的
- #################################################
-
- [ $# -lt 4 ] && exit 1
- [ $# -gt 7 ] && exit 1
- ##################################################
- #對參數(shù)個數(shù)做檢查,小于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在之前已經(jīng)被設(shè)定了,就不做任何動作;如果為空,就設(shè)定為smdk2410.這里設(shè)定為smdk2410
- ############################################
-
- arch="$2"
- cpu="$3"
- if [ "$4" = "-" ] ; then
- board=${BOARD_NAME}
- else
- board="$4"
- fi
- ######################################################
- #設(shè)定arch變量的值為arm
- #cpu變量的值為arm920t
- #因?yàn)榈谒膫€變量為"-",所以board變量的值為smdk2410
- #######################################################
-
-
- [ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
- [ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"
- #############################################################
- #設(shè)定verdor變量的值為samsung
- #設(shè)定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
- }
- #################################################
- #因?yàn)槲覀兊淖兞總€數(shù)就是6個,這一段不執(zhí)行
- #################################################
- 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已經(jīng)有值了,那么就檢測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中我們已經(jīng)知道SRCTREE和OBJTREE都是當(dāng)前目錄,所以這里執(zhí)行else
- #進(jìn)入./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不為空,執(zhí)行else
- #將asm/arch鏈向arch-s3c24x0,看一下arch-s3c24x0目錄,里面都是s3c24x0相關(guān)的頭文件
- ##########################################################
-
- 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}
- #######################################################################
- #因?yàn)関endor變量不為空,所以執(zhí)行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為空,上面不執(zhí)行了
- ##################################################
-
- 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文件,文件內(nèi)容是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
- ###############################
- #因?yàn)閛bj為空,所以定義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
- ###########################
- #因?yàn)镸AKEFLAGS變量的字符串為空,找不到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,否則為空。
- #當(dāng)使用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不為空,那么這幾句就執(zhí)行:
- #首先,saved-output變量也是BUILD_DIR的值
- #如果BUILD_DIR不存在,那么就創(chuàng)建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內(nèi)嵌的變量,是當(dāng)前目錄。
- #我們在make時候不加O=/tmp之類的參數(shù),所以O(shè)BJTREE就是當(dāng)前工作目錄,SPLTREE是當(dāng)前工作目錄下的spl目錄,SRCTREE時當(dāng)前工作目錄,TOPDIR也是當(dāng)前目錄,LNDIR也是當(dāng)前目錄。
- ##########################################
-
- MKCONFIG := $(SRCTREE)/mkconfig
- export MKCONFIG
- #############################################
- #MKCONFIG定義為當(dāng)前工作目錄下的mkconfig腳本,并export
- #############################################
-
- ifneq ($(OBJTREE),$(SRCTREE))
- REMOTE_BUILD := 1
- export REMOTE_BUILD
- endif
- ####################################################################
- #在我們的執(zhí)行中,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
- #######################################
- #可以先看下上面的注釋 因?yàn)閮蓚€路徑相同,所以執(zhí)行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)
- ########################
- #定義幾個偽目標(biāo)
- ########################
-
- 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過程中產(chǎn)生的
- #######################################
-
- # set default to nothing for native builds
- ifeq ($(HOSTARCH),$(ARCH))
- CROSS_COMPILE ?=
- endif
- #######################################
- #看看注釋就知道了,但是很顯示我們的HOSTARCH是x86的,目標(biāo)時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))
- ##############################################################################
- #用等號賦值的變量是遞歸方式擴(kuò)展的變量。變量定義時,變量值中對其他變量的引用不會被替換展開;
- #而是變量在引用它的地方替換展開的同時,它所引用的其它變量才會被一同替換展開。
- #其優(yōu)點(diǎn)是:
- #這種類型變量在定義時,可以引用其它的之前沒有定義的變量(可能在后續(xù)部分定義,或者是通過make的命令行選項(xiàng)傳遞的變量)。
- #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 但是這里沒有這個定義
- #第一個地方?jīng)]找到,就找第二個地方:u-boot-2012.07/board/samsung/smdk2410 這個目錄沒有u-boot.lds文件
- #第二個地方?jīng)]找到,就找第三個地方:其中CPUDIR是在頂層的config.mk中定義的,在arch/arm/cpu/arm920t中找 這個目錄也沒有
- #第三個地方?jīng)]找到,就找第四個地方: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中定義,這里根據(jù)實(shí)際情況 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 $@ | awk '{print $$1}'`; \
- limit=$(CONFIG_BOARD_SIZE_LIMIT); \
- if test $$actual -gt $$limit; then \
- echo "$@ 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, wd@denx.de.
- #
- # 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中已經(jīng)分析了CURDIR和SRCTREE都是當(dāng)前目錄,所以這里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都是當(dāng)前目錄,所以執(zhí)行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函數(shù)從HOSTCFLAGS中過濾掉-pedantic選項(xiàng)
- #而HOSTCFLAGS追加上-pedantic選項(xiàng)
- ############################################################
-
- #########################################################################
- #
- # 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)
- #############################################################################
- #定義編譯選項(xiàng)
- #在cc_options.mk中有如下選項(xiàng):
- # 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
- ###########################################################################################
- #定義兩個函數(shù),cc-option-sys被cc-option調(diào)用
- #cc-option被后面的函數(shù)調(diào)用
- ############################################################################################
-
- # cc-version
- # Usage gcc-ver := $(call cc-version)
- cc-version = $(shell $(SHELL) $(SRCTREE)/tools/gcc-version.sh $(CC))
- ##########################################################################################
- #使用tools/gcc-version.sh腳本來獲取編譯器的版本
- #在頂層makefile中,有調(diào)用cc-version函數(shù)
- ##########################################################################################
- #
- # 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的作用是在靜態(tài)庫有添加新的.o后,負(fù)責(zé)更新索引.
- #########################################################################
-
- # Load generated board configuration
- sinclude $(OBJTREE)/include/autoconf.mk
- sinclude $(OBJTREE)/include/config.mk
- ################################################################################################
- #包上配置編譯時產(chǎn)生的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 $@ $<
- $(obj)%.o: %.S
- $(CC) $(ALL_AFLAGS) -o $@ $< -c
- $(obj)%.o: %.c
- $(CC) $(ALL_CFLAGS) -o $@ $< -c
- $(obj)%.i: %.c
- $(CPP) $(ALL_CFLAGS) -o $@ $< -c
- $(obj)%.s: %.c
- $(CC) $(ALL_CFLAGS) -o $@ $< -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 $@ $1,\
- rm -f $@; $(AR) rcs $@ )
-
- #########################################################################
主要是一些變量和函數(shù)的定義,編譯鏈接的參數(shù)設(shè)置以及依賴規(guī)則.
最后分析下make:
- $(obj)include/autoconf.mk.dep: $(obj)include/config.h include/common.h
- @$(XECHO) Generating $@ ; \
- set -e ; \
- : Generate the dependancies ; \
- $(CC) -x c -DDO_DEPS_ONLY -M $(CFLAGS) $(CPPFLAGS) \
- -MQ $(obj)include/autoconf.mk include/common.h > $@
-
- $(obj)include/autoconf.mk: $(obj)include/config.h
- @$(XECHO) Generating $@ ; \
- set -e ; \
- : Extract the config macros ; \
- $(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h | \
- sed -n -f tools/scripts/define2mk.sed > $@.tmp && \
- mv $@.tmp $@
第一個是生成include/autoconf.mk的依賴文件
第二個是根據(jù)include/config.h的文件內(nèi)容,利用tools/scripts/define2mk.sed腳本將所有的CONFIG提取到autoconf.mk文件中
終極目標(biāo)是:ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map
u-boot.srec也是根據(jù)u-boot用objcopy工具搞出來的,不知的什么作用
u-boot.bin也是根據(jù)u-boot用objcopy工具搞出來的,最終燒寫的二進(jìn)制bin檔
System.map是符號列表
- $(obj)u-boot.bin: $(obj)u-boot
- $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
- $(BOARD_SIZE_CHECK)
- ###################################################################################
- #要得到最后的u-boot.bin,必須得到u-boot.u-boot.bin是最后要燒寫到板子上的二進(jìn)制bin檔
- #利用objcopy來得到這個二進(jìn)制文件($@是規(guī)則的目標(biāo)文件名,$<是規(guī)則的第一個依賴文件名)
- #調(diào)用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選項(xiàng)生成依賴文件.
b.看一下$(SUBDIR_TOOLS):
tools目錄
c.看一下$(OBJS):
$(OBJS):depend
$(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))
看下$(if $(REMOTE_BUILD),$@,$(notdir $@))
因?yàn)?(REMOTE_BUILD)為空,所以返回的是$(notdir $@)的值;
因?yàn)?@指的是規(guī)則的目標(biāo),所以就是$(OBJS),而$(OBJS)就是arch/arm/cpu/arm920t/start.o
notdir內(nèi)嵌函數(shù)返回的文件名;所以返回start.o
執(zhí)行makc -C arch/arm/cpu/arm920t start.o
d.$(LIBBOARD)
$(LIBBOARD):depend $(LIBS)
$(MAKE) -C $(dir $(subst $(obj),,$@))
執(zhí)行make -C board/samsung/smdk2410
e.$(LIBS)
$(LIBS):depend $(SUBDIR_TOOLS)
$(MAKE) -C $(dir $(subst $(obj),,$@))
進(jìn)入到LIBS包含的很多目錄,執(zhí)行make,生成很多.a文件.
f.$(LDSCRIPT)
$(LDSCRIPT):depend
$(MAKE) -C $(dir $@) $(notdir $@)
在前面找鏈接腳本時已然知曉LDSCRIPT就是arch/arm/cpu/u-boot.lds
執(zhí)行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 - <$^ >$@
這些就是編譯uboot的規(guī)則,分析的比較粗糙,在移植的過程中肯定還會遇到各式各樣的問題,在移植過程中再進(jìn)一步深入并修正.
原文地址為:http://blog.csdn.net/dndxhej/article/details/8134148