编译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