第四章——u-boot之Makefile

编译u-boot就两步

make tiny4412_config

make


执行make tiny4412_config相当于执行顶层目录中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
	@$(MKCONFIG) -A $(@:_config=)
#########################################################################
#%是个通配符,make xxx_config都是这个目标.目标的依赖是unconfig,
#unconfig的命令是删除一些文件,而这些文件正是从make xxx_config过程中产生的.unconfig就是清理配置的.
#我们来看@$(MKCONFIG) -A $(@:_config=)
#MKCONFIG在Makefile中定义为顶层目录中的mkconfig脚本
#$(@:_config=)是变量的替换引用
#格式为“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是:替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。
#所以tiny4412_config末尾的_config去除了.
#下面就是执行mkconfig脚本了,mkconfig -A tiny4412
#########################################################################

我们来看一下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=""

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}
	# add default board name if needed
	[ $# = 3 ] && set ${line} ${1}
fi
#####################################  
#我们执行脚本的命令是mkconfig -A tiny4412,$#表示的是参数的个数,$1表示的是第一个参数  
#搜索boards.cfg文件中tiny4412的那行,而-i表示忽略大小写  
#set也可用于在脚本内部给出其运行参数,所以这个时候参数就变为
#tiny4412 arm armv7 tiny4412 samsung exynos
#这个时候参数个数就变成6个了  
######################################

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

[ $# -lt 4 ] && exit 1
[ $# -gt 7 ] && exit 1
############################################################################
#这部分条件不成立
############################################################################

# Strip all options and/or _config suffixes
CONFIG_NAME="${1%_config}"
####################  
#CONFIG_NAME = tiny4412  
#########################

[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"
####################  
#BOARD_NAME = tiny4412  
#########################

arch="$2"
cpu="$3"
if [ "$4" = "-" ] ; then
	board=${BOARD_NAME}
else
	board="$4"
fi
[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"
[ $# -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
}
############################################################################
#arch   = arm 
#cpu    = armv7 
#board  = tiny4412 
#vendor = samsung 
#soc    = exynos
############################################################################

if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then
	echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2
	exit 1
fi
####################################################  
#ARCH为空
#如果ARCH已经有值了,那么就检测ARCH和arch是否匹配了
####################################################

if [ "$options" ] ; then
	echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
	echo "Configuring for ${BOARD_NAME} board..."
fi
###########################################################################  
#Configuring for tiny4412 board...  
########################################################################### 
#
# Create link to 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/${arch}/include/asm asm
	LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/
	cd ../include
	rm -f asm
	ln -s ${SRCTREE}/arch/${arch}/include/asm asm
else
	cd ./include
	rm -f asm
	ln -s ../arch/${arch}/include/asm asm
fi

rm -f asm/arch

if [ -z "${soc}" ] ; then
	ln -s ${LNPREFIX}arch-${cpu} asm/arch
else
	ln -s ${LNPREFIX}arch-${soc} asm/arch
fi

if [ "${arch}" = "arm" ] ; then
	rm -f asm/proc
	ln -s ${LNPREFIX}proc-armv asm/proc
fi
###########################################################################  
#在配置文件中建立连接,为了别的文件包含头文件的时候方便
###########################################################################

#
# 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

# Assign board directory to BOARDIR variable
if [ -z "${vendor}" ] ; then
    BOARDDIR=${board}
else
    BOARDDIR=${vendor}/${board}
fi
######################################################################  
#新建文件config.mk,在顶层目录Makefile中会用到
#include/config.mk的文件如下:  
#ARCH   = arm  
#CPU    = arm920t  
#BOARD  = smdk2410  
#VENDOR = samsung  
#SOC    = 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
echo "/* Automatically generated - do not edit */" >>config.h
########################################################################  
#在文件的最开头可以看到APPEND为no,所以这里我们在include文件夹下建立config.h文件  
####################################################################### 

for i in ${TARGETS} ; do
	i="`echo ${i} | sed '/=/ {s/=/\t/;q } ; { s/$/\t1/ }'`"
	echo "#define CONFIG_${i}" >>config.h ;
done
###################################################  
#这里我们TARGETS为空,上面不执行了  
################################################## 

cat << EOF >> config.h
#define CONFIG_BOARDDIR board/$BOARDDIR
#include <config_defaults.h>
#include <configs/${CONFIG_NAME}.h>
#include <asm/config.h>
EOF

exit 0

执行完make tiny4412_config之后的变化

1.文件连接

2.include/config.mk

3.include/config.h


执行make后,make会想去生成第一个目标,Makefile中前两个目标都是all,伪目标all前一个会被后一个覆盖,也就是Makefile中只有最好一个目标all生效,这里Makefile会去生成第二个all,下面是Makefile的代码

#
# (C) Copyright 2000-2010
# 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 Foundatio; 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
#

#########################################################################

VERSION = 2010
PATCHLEVEL = 12
SUBLEVEL =
EXTRAVERSION =
ifneq "$(SUBLEVEL)" ""
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
else
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL)$(EXTRAVERSION)
endif
#########################################################################
#U_BOOT_VERSION = 2012.12
#########################################################################

TIMESTAMP_FILE = $(obj)include/timestamp_autogenerated.h
VERSION_FILE = $(obj)include/version_autogenerated.h
###############################  
#TIMESTAMP_FILE = include/generated/timestamp_autogenerated.h  
#VERSION_FILE   = include/generated/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/ppc64/powerpc/ \
	    -e s/ppc/powerpc/ \
	    -e s/macppc/powerpc/\
	    -e s/sh.*/sh/)
#########################################################################
#“sed –e”表示后面跟的是一串命令脚本,而表达式“s/abc/def/”表示要从标准输入中,
#查找到内容为“abc”的,然后替换成“def”。其中“abc”表达式用可以使用“.”作为通配符。 
#命令“uname –m”将输出主机CPU的体系架构类型。
#作者的电脑使用Intel Core2系列的CPU,因此“uname –m”输出“i686”。
#“i686”可以匹配命令“sed -e s/i.86/i386/”中的“i.86”,
#因此在作者的机器上执行Makefile,HOSTARCH将被设置成“i386” 。 
#HOSTARCH := i386
#########################################################################		

HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
	    sed -e 's/\(cygwin\).*/cygwin/')
#########################################################################
#“uname –s”输出主机内核名字,作者使用Linux发行版Ubuntu9.10,因此“uname –s”结果是“Linux”。
#“tr '[:upper:]' '[:lower:]'”作用是将标准输入中的所有大写字母转换为响应的小写字母。
#因此执行结果是将HOSTOS 设置为“linux”。 
#HOSTOS := linux
#########################################################################		

# 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)
#########################################################################
#"$$BASH"的作用实质上是生成了字符串“$BASH”(前一个$号的作用是指明第二个$是普通的字符)。
#若执行当前Makefile的shell中定义了“$BASH”环境变量,且文件“$BASH”是可执行文件,则SHELL的值为“$BASH”。
#否则,若“/bin/bash”是可执行文件,则SHELL值为“/bin/bash”。若以上两条都不成立,则将“sh”赋值给SHELL变量。
#SHELL := /bin/sh
#########################################################################
export	HOSTARCH HOSTOS SHELL

# Deal with colliding definitions from tcsh etc.
VENDOR=

#########################################################################
# Allow for silent builds
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
###########################  
#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

ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)
#########################################################################
#在命令行参数选项添加O=,意为设置生成文件目录
#函数$( origin, variable) 输出的结果是一个字符串,
#输出结果由变量variable定义的方式决定,
#若variable在命令行中定义过,
#则origin函数返回值为"command line"。
#########################################################################

# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
#########################################################################
#创建文件夹,-p为一次创建多级文件夹
#########################################################################

# Verify if it was successful.

BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
#########################################################################
#命令之间使用 && 连接,实现逻辑与的功能
#只有在 && 左边的命令返回真(命令返回值 $? == 0),&& 右边的命令才会被执行
#只要有一个命令返回假(命令返回值 $? == 1),后面的命令就不会被执行
#
#命令之间使用 || 连接,实现逻辑或的功能
#只有在 || 左边的命令返回假(命令返回值 $? == 1),|| 右边的命令才会被执行。
#这和 c 语言中的逻辑或语法功能相同,即实现短路逻辑或操作。 
#只要有一个命令返回真(命令返回值 $? == 0),后面的命令就不会被执行
#########################################################################
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif # ifneq ($(BUILD_DIR),)
#################################  
#如果BUILD_DIR为空,则报错
#################################

OBJTREE		:= $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE		:= $(CURDIR)
TOPDIR		:= $(SRCTREE)
LNDIR		:= $(OBJTREE)
export	TOPDIR SRCTREE OBJTREE

MKCONFIG	:= $(SRCTREE)/mkconfig
export MKCONFIG
#########################################################################
#CURDIR变量指示Make当前的工作目录,由于当前Make在U-Boot顶层目录执行Makefile,
#因此CURDIR此时就是U-Boot顶层目录。
#
#OBJTREE和LNDIR为存放生成文件的目录,TOPDIR与SRCTREE为源码所在目录。
#变量MKCONFIG:这个变量指向一个脚本,即顶层目录的mkconfig。
#########################################################################

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
#######################################  
#OBJTREE和SRCTREE是相等,所以执行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)
SUBDIRS	= tools \
	  examples/standalone \
	  examples/api
###############################################  
#SUBDIRS	= tools examples/standalone examples/api
###############################################

.PHONY : $(SUBDIRS)
###############################################  
#.PHONY为定义伪目标
#下文规则中$(SUBDIRS)为目标时,不管其存在与否都会更新其依赖
###############################################

ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
#########################################################################
#wildcard是Makefile中的关键字,它的作用是让通配符在变量中展开。
#此处$(obj)为空,相当于ifeq ($(obj)include/config.mk,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
###################################################################################  
#通过实验发现这里的all:没啥用,不知道为什么还要写
#
#如果指示符“include”指定的文件不是以斜线开始(绝对路径,如/usr/src/Makefile...),
#而且当前目录下也不存在此文件;make将根据文件名试图在以下几个目录下查找:
#首先,查找使用命令行选项“-I”或者“--include-dir”指定的目录,如果找到指定的文件,则使用这个文件;
#否则继续依此搜索以下几个目录(如果其存在):“/usr/gnu/include”、“/usr/local/include”和“/usr/include”。
#
#当在这些目录下都没有找到“include”指定的文件时,make将会提示一个包含文件未找到的告警提示,但是不会立刻退出。
#而是继续处理Makefile的后续内容。当完成读取整个Makefile后,
#make将试图使用规则来创建通过指示符“include”指定的但未找到的文件,
#当不能创建它时(没有创建这个文件的规则),make将提示致命错误并退出。会输出类似如下错误提示:
#
#Makefile:错误的行数:未找到文件名:提示信息(No such file or directory)
#Make:*** No rule to make target ‘<filename>’. Stop
#
#通常我们在Makefile中可使用“-include”来代替“include”,
#来忽略由于包含文件不存在或者无法创建时的错误提示(“-”的意思是告诉make,忽略此操作的错误。make继续执行)。
#
#为了和其它的make程序进行兼容。也可以使用“sinclude”来代替“-include”(GNU所支持的方式)。
###################################################################################

# 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的,ARCH是arm的,  
########################################

# load other configuration
include $(TOPDIR)/config.mk
#######################################  
#包含uboot顶层目录的config.mk文件,
#这个文件主要是关于编译选项,汇编器,连接器,
#编译器,打包工具,反汇编工具等的设置
#######################################

#########################################################################
# U-Boot objects....order is important (i.e. start must be first)

OBJS  = $(CPUDIR)/start.o
ifeq ($(CPU),i386)
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增加前缀,addprefix为加前缀函数
#CPUDIR=arch/arm/cpu/armv7
#obj在顶层目录的config.mk中定义,这里根据实际情况 
#OBJS就是 $(obj)/arch/arm/cpu/armv7/start.o  
#####################################

LIBS  = lib/libgeneric.o
LIBS += lib/lzma/liblzma.o
LIBS += lib/lzo/liblzo.o

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
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
ifndef CONFIG_S5P6450
LIBS += drivers/gpio/libgpio.o
endif
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/lib8xxx.o
endif
ifeq ($(CPU),mpc85xx)
LIBS += drivers/qe/libqe.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
LIBS += drivers/twserial/libtws.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/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

ifeq ($(SOC),omap3)
LIBS += $(CPUDIR)/omap-common/libomap-common.o
endif
ifeq ($(SOC),omap4)
LIBS += $(CPUDIR)/omap-common/libomap-common.o
endif

ifeq ($(SOC),s5pc1xx)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.o
endif
ifeq ($(SOC),s5pv210)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.o
endif
ifeq ($(SOC),s5pc2xx)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.o
endif
ifeq ($(SOC),s5pv310)
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变量指明了U-Boot需要的库文件,
#################################################################################

.PHONY : $(LIBS) $(TIMESTAMP_FILE) $(VERSION_FILE)

LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
################################################################################
#LIBBOARD为开发板相关库文件
#################################################################################

# 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
################################################################################
#GCC相关设置
#################################################################################

# 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 \
	$(shell $(LD) --version | \
	  sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')

ifeq ($(CONFIG_NAND_U_BOOT),y)
NAND_SPL = nand_spl
U_BOOT_NAND = $(obj)u-boot-nand.bin
endif

ifeq ($(CONFIG_ONENAND_U_BOOT),y)
ONENAND_IPL = onenand_ipl
U_BOOT_ONENAND = $(obj)u-boot-onenand.bin
ONENAND_BIN ?= $(obj)onenand_ipl/onenand-ipl-2k.bin
endif
##########################################################################################
#关于nand启动设置,先不考虑nand启动,假设CONFIG_NAND_U_BOOT与CONFIG_ONENAND_U_BOOT没定义
###########################################################################################
__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
################################################################################
#限定文件大小
#################################################################################


# Always append ALL so that arch config.mk's can add custom ones
ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND)
#########################################################################
#这里只关心$(obj)u-boot.bin,这是最后烧写到开发板上的二进制文件
#########################################################################

all:		$(ALL)

$(obj)u-boot.bin:	$(obj)u-boot
		$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
		$(BOARD_SIZE_CHECK)
################################################################################
##		arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
#################################################################################
		
$(obj)u-boot:	depend \
		$(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
		$(GEN_UBOOT)
################################################################################
GEN_UBOOT = \
		UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \
		sed  -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
		cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
			--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
			-Map u-boot.map -o u-boot
#################################################################################
#下面是链接出u-boot文件的命令,这个u-boot是elf格式的
#
#UNDEF_SYM=`arm-linux-objdump -x board/samsung/tiny4412/libtiny4412.o 
#api/libapi.o arch/arm/cpu/armv7/exynos/libexynos.o arch/arm/cpu/armv7/libarmv7.o 
#arch/arm/cpu/armv7/s5p-common/libs5p-common.o arch/arm/lib/libarm.o 
#common/libcommon.o disk/libdisk.o drivers/bios_emulator/libatibiosemu.o 
#drivers/block/libblock.o drivers/dma/libdma.o drivers/fpga/libfpga.o 
#drivers/gpio/libgpio.o drivers/hwmon/libhwmon.o drivers/i2c/libi2c.o 
#drivers/input/libinput.o drivers/misc/libmisc.o drivers/mmc/libmmc.o 
#drivers/mtd/libmtd.o drivers/mtd/nand/libnand.o drivers/mtd/onenand/libonenand.o 
#drivers/mtd/spi/libspi_flash.o drivers/mtd/ubi/libubi.o drivers/net/libnet.o 
#drivers/net/phy/libphy.o drivers/pci/libpci.o drivers/pcmcia/libpcmcia.o 
#drivers/power/libpower.o drivers/rtc/librtc.o drivers/serial/libserial.o 
#drivers/spi/libspi.o drivers/twserial/libtws.o drivers/usb/gadget/libusb_gadget.o 
#drivers/usb/host/libusb_host.o drivers/usb/musb/libusb_musb.o drivers/usb/phy/libusb_phy.o 
#drivers/video/libvideo.o drivers/watchdog/libwatchdog.o fs/cramfs/libcramfs.o 
#fs/ext2/libext2fs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o 
#fs/reiserfs/libreiserfs.o fs/ubifs/libubifs.o fs/yaffs2/libyaffs2.o 
#lib/libfdt/libfdt.o lib/libgeneric.o lib/lzma/liblzma.o 
#lib/lzo/liblzo.o net/libnet.o post/libpost.o | 
#sed  -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`; 
#定义了一个变量UNDEF_SYM ,
#这个变量实际上就是把中间这一群的静态库里面__u_boot_cmd_开头的symbol都提取出来,
#并在每个的开头加上了-u,以备后用
#
#cd /work/4412/uboot_tiny4412 && 
#
#arm-linux-ld -Bstatic -T u-boot.lds  -pie -Ttext 0xc3e00000 $UNDEF_SYM arch/arm/cpu/armv7/start.o 
#-Bstatic 表示静态链接
#-T u-boot.lds 表示使用u-boot.lds,linker script来链接
#-pie不知道是啥
#-Ttext 0xc3e00000 表示将text段,放到绝对地址为0xc3e00000的地方。
#$UNDEF_SYM 上面的静态变量
#
#--start-group api/libapi.o arch/arm/cpu/armv7/exynos/libexynos.o 
#arch/arm/cpu/armv7/libarmv7.o arch/arm/cpu/armv7/s5p-common/libs5p-common.o 
#arch/arm/lib/libarm.o common/libcommon.o disk/libdisk.o 
#drivers/bios_emulator/libatibiosemu.o drivers/block/libblock.o 
#drivers/dma/libdma.o drivers/fpga/libfpga.o drivers/gpio/libgpio.o 
#drivers/hwmon/libhwmon.o drivers/i2c/libi2c.o drivers/input/libinput.o 
#drivers/misc/libmisc.o drivers/mmc/libmmc.o drivers/mtd/libmtd.o drivers/mtd/nand/libnand.o 
#drivers/mtd/onenand/libonenand.o drivers/mtd/spi/libspi_flash.o drivers/mtd/ubi/libubi.o 
#drivers/net/libnet.o drivers/net/phy/libphy.o drivers/pci/libpci.o drivers/pcmcia/libpcmcia.o 
#drivers/power/libpower.o drivers/rtc/librtc.o drivers/serial/libserial.o drivers/spi/libspi.o 
#drivers/twserial/libtws.o drivers/usb/gadget/libusb_gadget.o drivers/usb/host/libusb_host.o 
#drivers/usb/musb/libusb_musb.o drivers/usb/phy/libusb_phy.o drivers/video/libvideo.o 
#drivers/watchdog/libwatchdog.o fs/cramfs/libcramfs.o fs/ext2/libext2fs.o fs/fat/libfat.o 
#fs/fdos/libfdos.o fs/jffs2/libjffs2.o fs/reiserfs/libreiserfs.o fs/ubifs/libubifs.o 
#fs/yaffs2/libyaffs2.o lib/libfdt/libfdt.o lib/libgeneric.o lib/lzma/liblzma.o lib/lzo/liblzo.o 
#net/libnet.o post/libpost.o board/samsung/tiny4412/libtiny4412.o --end-group 
#--start-group --end-group 之间列出了所有的archives.
#
#/work/4412/uboot_tiny4412/arch/arm/lib/eabi_compat.o 
#-L /work/4412/opt/FriendlyARM/toolschain/4.5.1/bin/../lib/gcc/arm-none-linux-gnueabi/4.5.1 
#-lgcc -Map u-boot.map -o u-boot
#-Map u-boot.map   可生成..map 文件
#在u-boot中,就有一种快速方法“从众多的同名函数中找到与我们相关的那一个”:
#编译出来完的uboot会生成一个u-boot.map文件,你只要以这个“函数的名字”为关键字去u-boot.map中查找,
#就能找到编译出来的uboot映像,使用的是哪个文件中的函数了。
#################################################################################


################################################################################
			
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
	@$(MKCONFIG) -A $(@:_config=)
#########################################################################
#%是个通配符,make xxx_config都是这个目标.目标的依赖是unconfig,
#unconfig的命令是删除一些文件,而这些文件正是从make xxx_config过程中产生的.unconfig就是清理配置的.
#我们来看@$(MKCONFIG) -A $(@:_config=)
#MKCONFIG在Makefile中定义为顶层目录中的mkconfig脚本
#$(@:_config=)是变量的替换引用
#格式为“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是:替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。
#所以tiny4412_config末尾的_config去除了.
#下面就是执行mkconfig脚本了,mkconfig -A tiny4412
#########################################################################
depend dep:	$(TIMESTAMP_FILE) $(VERSION_FILE) \
		$(obj)include/autoconf.mk \
		$(obj)include/generated/generic-asm-offsets.h
		for dir in $(SUBDIRS) $(CPUDIR) $(dir $(LDSCRIPT)) ; do \
			$(MAKE) -C $$dir _depend ; done
################################################################################


$(TIMESTAMP_FILE):
		@LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"' > $@
		@LC_ALL=C date +'#define U_BOOT_TIME "%T"' >> $@
################################################################################
		
$(VERSION_FILE):
		@( printf '#define U_BOOT_VERSION "U-Boot %s%s"\n' "$(U_BOOT_VERSION)" \
		 '$(shell $(TOPDIR)/tools/setlocalversion $(TOPDIR))' ) > $@.tmp
		@cmp -s $@ $@.tmp && rm -f $@.tmp || mv -f $@.tmp $@
################################################################################
	
$(SUBDIRS):	depend
		$(MAKE) -C $@ all
################################################################################
	
$(OBJS):	depend
		$(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))
################################################################################
	
$(LIBS):	depend $(SUBDIRS)
		$(MAKE) -C $(dir $(subst $(obj),,$@))
################################################################################
		
$(LIBBOARD):	depend $(LIBS)
		$(MAKE) -C $(dir $(subst $(obj),,$@))		
################################################################################
	
$(LDSCRIPT):	depend
		$(MAKE) -C $(dir $@) $(notdir $@)
################################################################################

$(obj)u-boot.lds: $(LDSCRIPT)
		$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@
################################################################################

$(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 $(HOSTCFLAGS) $(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 $@
################################################################################

$(obj)include/generated/generic-asm-offsets.h:	$(obj)include/autoconf.mk.dep \
	$(obj)lib/asm-offsets.s
	@$(XECHO) Generating $@
	tools/scripts/make-asm-offsets $(obj)lib/asm-offsets.s $@
################################################################################

$(obj)lib/asm-offsets.s:	$(obj)include/autoconf.mk.dep \
	$(src)lib/asm-offsets.c
	@mkdir -p $(obj)lib
	$(CC) -DDO_DEPS_ONLY \
		$(CFLAGS) $(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR)) \
		-o $@ $(src)lib/asm-offsets.c -c -S





  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值