您的位置:首页 > 其它

U-boot makefile 解读

2017-12-01 11:47 471 查看
自己写的bootloader可以引导kernel了,我以为曾经神秘的u-boot代码将变得毫无挑战,然事实表明u-boot作为优秀的开源代码,阅读起来还是很有挑战的,值得一读!

阅读碰到的头等问题:Makefile和shell脚本看不懂...

说起来做linux也很久了,Makefile和shell脚本都接触过,但真的都是略懂而已.因为公司的Makefile和shell简单的一眼望的对穿,很初级的写法,简单的应用.再随便在网上下个老外的开源代码,那个Makefile和shell复杂啊.一不留神想起来了qt的qmake根据工程文件生成的Makefile也是很简单,但qmake是人家老外写的.不说其他语言了,只看Makefile和shell,中外的差距就在那了.

这次准备移植u-boot到tq2440上,选用的u-boot版本是u-boot-2012.07.

下面是我对u-boot配置和编译的makefile mkconfig config.mk等文件的解读,有些解读我是在源档上添加文字注释的,有些是另外写的,解读难免有误,若有读者发现了,希望能够指出,在下感激不尽!

在编译u-boot的过程,就是make xxx_config和make两步

以make smdk2410_config为例:

当以smdk2410_config为目标时,makefile中前面一些变量的定义和其他文件的引用也是有的,这个在原档中添加了有关注释:

在makefile中有:

unconfig:

 @rm -f $(obj)include/config.h $(obj)include/config.mk \

  $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \

  $(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep

%_config:: unconfig

 echo $@

 $(MKCONFIG) -A $(@:_config=)

%是个通配符,make xxx_config都是这个目标.目标的依赖是unconfig,unconfig的命令是删除一些文件,而这些文件正是从make xxx_config过程中产生的.unconfig就是清理配置的.

我们来看@$(MKCONFIG) -A $(@:_config=)

其实执行的是mkconfig -A smdk2410

我们可以在该行上面添加一行:echo $@

则会输出smdk2410_config,因为$@就是指目标

$(@:_config=)是变量的替换引用

格式为“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是:替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。

所以smdk2410_config末尾的_config去除了.

下面就是执行mkconfig脚本了,mkconfig -A smdk2410

给出添加注释的mkconfig文件:

#!/bin/sh -e

# Script to create header files and links to configure

# U-Boot for a specific board.

#

# Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]

#

# (C) 2002-2010 DENX Software Engineering, Wolfgang Denk <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}

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

#我们
19759
执行脚本的命令是mkconfig -A smdk2410,$#表示的是参数的个数,$1表示的是第一个参数

#line 就是在boards.cfg文件中smdk2410的那行,而-i表示忽略大小写

#在boards.cfg文件中,有

#Target                    ARCH        CPU        Board name          Vendor        SoC        Options

#smdk2410                    arm        arm920t    -                  samsung        s3c24x0

#  set ${line}

#  set也可用于在脚本内部给出其运行参数,所以这个时候参数就变为"smdk2410 arm arm920t - samsung s3c24x0"

#这个时候参数个数就变成6个了

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

elif [ "${MAKEFLAGS+set}${MAKELEVEL+set}" = "setset" ] ; then

 # only warn when using a config target in the Makefile

 cat <<-EOF

 warning: Please migrate to boards.cfg.  Failure to do so will

          mean removal of your board in the next release.

 EOF

 sleep 5

fi

echo $1

while [ $# -gt 0 ] ; do

 case "$1" in

 --) shift ; break ;;

 -a) shift ; APPEND=yes ;;

 -n) shift ; BOARD_NAME="${1%_config}" ; shift ;;

 -t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;

 *)  break ;;

 esac

done

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

#因为$1的值为smdk2410,所以case找不到对应的

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

[ $# -lt 4 ] && exit 1

[ $# -gt 7 ] && exit 1

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

#对参数个数做检查,小于4个或大于7个就退出

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

# Strip all options and/or _config suffixes

CONFIG_NAME="${1%_config}"

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

#CONFIG_NAME的值为smdk2410

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

echo config_

echo ${CONFIG_NAME}

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

echo board

echo ${BOARD_NAME}

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

#如果BOARD_NAME在之前已经被设定了,就不做任何动作;如果为空,就设定为smdk2410.这里设定为smdk2410

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

arch="$2"

cpu="$3"

if [ "$4" = "-" ] ; then

 board=${BOARD_NAME}

else

 board="$4"

fi

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

#设定arch变量的值为arm

#cpu变量的值为arm920t

#因为第四个变量为"-",所以board变量的值为smdk2410

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

[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"

[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"

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

#设定verdor变量的值为samsung

#设定soc变量的值为s3c24x0

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

[ $# -gt 6 ] && [ "$7" != "-" ] && {

 # check if we have a board config name in the options field

 # the options field mave have a board config name and a list

 # of options, both separated by a colon (':'); the options are

 # separated by commas (',').

 #

 # Check for board name

 tmp="${7%:*}"

 if [ "$tmp" ] ; then

  CONFIG_NAME="$tmp"

 fi

 # Check if we only have a colon...

 if [ "${tmp}" != "$7" ] ; then

  options=${7#*:}

  TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}"

 fi

}

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

#因为我们的变量个数就是6个,这一段不执行

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

echo ${ARCH}

echo ${arch}

if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then

 echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2

 exit 1

fi

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

#ARCH是在顶层makefile中定义的,在此刻还是为空的。

#如果ARCH已经有值了,那么就检测ARCH和arch是否匹配了.

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

if [ "$options" ] ; then

 echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"

else

 echo "Configuring for ${BOARD_NAME} board..."

fi

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

#我们没有定义options变量,所以输出Configuring for smdk2410 board...

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

#

# Create link to architecture specific headers

#

echo ${SRCTREE}

echo ${OBJTREE}

if [ "$SRCTREE" != "$OBJTREE" ] ; then

 mkdir -p ${OBJTREE}/include

 mkdir -p ${OBJTREE}/include2

 cd ${OBJTREE}/include2

 rm -f asm

 ln -s ${SRCTREE}/arch/${arch}/include/asm asm

 LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/

 cd ../include

 mkdir -p asm

else

 cd ./include

 rm -f asm

 ln -s ../arch/${arch}/include/asm asm

fi

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

#在makefile中我们已经知道SRCTREE和OBJTREE都是当前目录,所以这里执行else

#进入./include目录,删除asm链接,并重新建立链接asm,指向arch/arm/include/asm

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

rm -f asm/arch

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

#删除include目录下的asm下的arch链接文件

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

ss=

echo ${ss}

if [ -z "${ss}" ] ; then

 echo "null"

else

 echo "not null"

fi

echo ${LNPREFIX}

if [ -z "${soc}" ] ; then

 ln -s ${LNPREFIX}arch-${cpu} asm/arch

else

 ln -s ${LNPREFIX}arch-${soc} asm/arch

fi

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

#-z用来检测字符串是否为空,为空返回真

#这里我们的soc不为空,执行else

#将asm/arch链向arch-s3c24x0,看一下arch-s3c24x0目录,里面都是s3c24x0相关的头文件

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

if [ "${arch}" = "arm" ] ; then

 rm -f asm/proc

 ln -s ${LNPREFIX}proc-armv asm/proc

fi

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

#删除asm/proc链接文件

#将asm/proc链向proc-armv目录,该目录下是四个头文件:domain.h\processor.h\ptrace.h\system.h

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

#

# Create include file for Make

#

echo "ARCH  = ${arch}"  >  config.mk

echo "CPU    = ${cpu}"  >> config.mk

echo "BOARD  = ${board}" >> config.mk

[ "${vendor}" ] && echo "VENDOR = ${vendor}" >> config.mk

[ "${soc}"    ] && echo "SOC    = ${soc}"    >> config.mk

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

#上面几句的作用在注释中描述的很清楚

#include/config.mk的文件如下:

#ARCH  = arm

#CPU    = arm920t

#BOARD  = smdk2410

#VENDOR = samsung

#SOC    = s3c24x0

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

# Assign board directory to BOARDIR variable

if [ -z "${vendor}" ] ; then

    BOARDDIR=${board}

else

    BOARDDIR=${vendor}/${board}

fi

echo ${BOARDDIR}

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

#因为vendor变量不为空,所以执行else

#BOARDDIR的值为samsung/s3c24x0

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

#

# Create board specific header file

#

if [ "$APPEND" = "yes" ] # Append to existing config file

then

 echo >> config.h

else

 > config.h  # Create new config file

fi

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

#在文件的最开头可以看到APPEND为no,所以这里我们在include文件夹下建立config.h文件

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

echo "/* Automatically generated - do not edit */" >>config.h

echo ${TARGETS}

for i in ${TARGETS} ; do

 i="`echo ${i} | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'`"

 echo "#define CONFIG_${i}" >>config.h ;

done

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

#这里我们TARGETS为空,上面不执行了

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

echo "#define CONFIG_SYS_ARCH  \"${arch}\""  >> config.h

echo "#define CONFIG_SYS_CPU  \"${cpu}\""  >> config.h

echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h

[ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h

[ "${soc}"    ] && echo "#define CONFIG_SYS_SOC    \"${soc}\""    >> config.h

cat << EOF >> config.h

#define CONFIG_BOARDDIR board/$BOARDDIR

#include <config_cmd_defaults.h>

#include <config_defaults.h>

#include <configs/${CONFIG_NAME}.h>

#include <asm/config.h>

#include <config_fallbacks.h>

EOF

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

#生成config.h文件如下:

# /* Automatically generated - do not edit */

# #define CONFIG_SYS_ARCH  "arm"

# #define CONFIG_SYS_CPU  "arm920t"

# #define CONFIG_SYS_BOARD "smdk2410"

# #define CONFIG_SYS_VENDOR "samsung"

# #define CONFIG_SYS_SOC    "s3c24x0"

# #define CONFIG_BOARDDIR board/samsung/smdk2410

# #include <config_cmd_defaults.h>

# #include <config_defaults.h>

# #include <configs/smdk2410.h>

# #include <asm/config.h>

# #include <config_fallbacks.h>

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

exit 0

make xxx_config后,主要的变化是多了几个文件:

1.include/asm    -->    arch/arm/include/arm

2.include/asm/arch  -->  arch-s3c24x0

3.include/asm/proc  -->  proc-armv

4.在include目录下新建了config.mk文件,文件内容是ARCH CPU BOARD VENDOR SOC的定义

5.在include目录下新建了config.h文件

接着看make:

给出部分makefile中的注释,主要是一些变量的定义:

VERSION = 2012

PATCHLEVEL = 07

SUBLEVEL =

EXTRAVERSION =

ifneq "$(SUBLEVEL)" ""

U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)

else

U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL)$(EXTRAVERSION)

endif

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

#定义U_BOOT_VERSION为2012.07

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

TIMESTAMP_FILE = $(obj)include/generated/timestamp_autogenerated.h

VERSION_FILE = $(obj)include/generated/version_autogenerated.h

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

#因为obj为空,所以定义TIMESTAMP_FILE为include/generated/timestamp_autogenerated.h

#定义VERSION_FILE为include/generated/version_autogenerated.h

#****************

HOSTARCH := $(shell uname -m | \

 sed -e s/i.86/x86/ \

    -e s/sun4u/sparc64/ \

    -e s/arm.*/arm/ \

    -e s/sa110/arm/ \

    -e s/ppc64/powerpc/ \

    -e s/ppc/powerpc/ \

    -e s/macppc/powerpc/\

    -e s/sh.*/sh/)

HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \

    sed -e 's/\(cygwin\).*/cygwin/')

# Set shell to bash if possible, otherwise fall back to sh

SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \

 else if [ -x /bin/bash ]; then echo /bin/bash; \

 else echo sh; fi; fi)

export HOSTARCH HOSTOS SHELL

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

#HOSTARCH为i686,HOSTOS为linux,SHELL为/bin/sh

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

# Deal with colliding definitions from tcsh etc.

VENDOR=

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

# Allow for silent builds

ifeq (,$(findstring s,$(MAKEFLAGS)))

XECHO = echo

else

XECHO = :

endif

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

#因为MAKEFLAGS变量的字符串为空,找不到s,所以ifeq为真,XECHO = echo

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

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

#

# U-boot build supports producing a object files to the separate external

# directory. Two use cases are supported:

#

# 1) Add O= to the make command line

# 'make O=/tmp/build all'

#

# 2) Set environement variable BUILD_DIR to point to the desired location

# 'export BUILD_DIR=/tmp/build'

# 'make'

#

# The second approach can also be used with a MAKEALL script

# 'export BUILD_DIR=/tmp/build'

# './MAKEALL'

#

# Command line 'O=' setting overrides BUILD_DIR environent variable.

#

# When none of the above methods is used the local build is performed and

# the object files are placed in the source directory.

#

ifdef O

ifeq ("$(origin O)", "command line")

BUILD_DIR := $(O)

endif

endif

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

#如果没有在make命令行中定义O=/tmp之类的,那么BUILD_DIR就为/tmp,否则为空。

#当使用make O=/tmp时,表明#ifdef O有定义,而$(origin O)返回的就是"command line"

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

ifneq ($(BUILD_DIR),)

saved-output := $(BUILD_DIR)

# Attempt to create a output directory.

$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})

# Verify if it was successful.

BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)

$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))

endif # ifneq ($(BUILD_DIR),)

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

#如果BUILD_DIR不为空,那么这几句就执行:

#首先,saved-output变量也是BUILD_DIR的值

#如果BUILD_DIR不存在,那么就创建BUILD_DIR目录

#检测BUILD_DIR目录是否成功建好了,如果有问题就输出错误信息

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

OBJTREE  := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))

SPLTREE  := $(OBJTREE)/spl

SRCTREE  := $(CURDIR)

TOPDIR  := $(SRCTREE)

LNDIR  := $(OBJTREE)

export TOPDIR SRCTREE OBJTREE SPLTREE

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

#如果BUILD_DIR有值,那么OBJTREE就是BUILD_DIR的值,如果BUILD_DIR为空,那么OBJTREE就是CURDIR的值,$(CURDIR)时GNU Make内嵌的变量,是当前目录。

#我们在make时候不加O=/tmp之类的参数,所以OBJTREE就是当前工作目录,SPLTREE是当前工作目录下的spl目录,SRCTREE时当前工作目录,TOPDIR也是当前目录,LNDIR也是当前目录。

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

MKCONFIG := $(SRCTREE)/mkconfig

export MKCONFIG

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

#MKCONFIG定义为当前工作目录下的mkconfig脚本,并export

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

ifneq ($(OBJTREE),$(SRCTREE))

REMOTE_BUILD := 1

export REMOTE_BUILD

endif

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

#在我们的执行中,OBJTREE和SRCTREE是相等的,所以不管了

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

# $(obj) and (src) are defined in config.mk but here in main Makefile

# we also need them before config.mk is included which is the case for

# some targets like unconfig, clean, clobber, distclean, etc.

ifneq ($(OBJTREE),$(SRCTREE))

obj := $(OBJTREE)/

src := $(SRCTREE)/

else

obj :=

src :=

endif

export obj src

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

#可以先看下上面的注释  因为两个路径相同,所以执行else

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

# Make sure CDPATH settings don't interfere

unexport CDPATH

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

# The "tools" are needed early, so put this first

# Don't include stuff already done in $(LIBS)

# The "examples" conditionally depend on U-Boot (say, when USE_PRIVATE_LIBGCC

# is "yes"), so compile examples after U-Boot is compiled.

SUBDIR_TOOLS = tools

SUBDIR_EXAMPLES = examples/standalone examples/api

SUBDIRS = $(SUBDIR_TOOLS)

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

#定义SUBDIR_TOOLS SUBDIR_EXAMPLES 和 SUBDIRS

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

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

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

#定义几个伪目标

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

ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))

# Include autoconf.mk before config.mk so that the config options are available

# to all top level build files.  We need the dummy all: target to prevent the

# dependency target in autoconf.mk.dep from being the default.

all:

sinclude $(obj)include/autoconf.mk.dep

sinclude $(obj)include/autoconf.mk

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

#包含auoconf.mk和autoconf.mk.dep文件

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

ifndef CONFIG_SANDBOX

SUBDIRS += $(SUBDIR_EXAMPLES)

endif

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

#追加SUBDIRS 为"tools  examples/standalone examples/api"

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

# load ARCH, BOARD, and CPU configuration

include $(obj)include/config.mk

export ARCH CPU BOARD VENDOR SOC

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

#包含include/config.mk文件,这个文件是在make xxx_config过程中产生的

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

# set default to nothing for native builds

ifeq ($(HOSTARCH),$(ARCH))

CROSS_COMPILE ?=

endif

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

#看看注释就知道了,但是很显示我们的HOSTARCH是x86的,目标时arm的

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

# load other configuration

include $(TOPDIR)/config.mk

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

#包含uboot顶层目录的config.mk文件

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

# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use

# that (or fail if absent).  Otherwise, search for a linker script in a

# standard location.

LDSCRIPT_MAKEFILE_DIR = $(dir $(LDSCRIPT))

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

#用等号赋值的变量是递归方式扩展的变量。变量定义时,变量值中对其他变量的引用不会被替换展开;

#而是变量在引用它的地方替换展开的同时,它所引用的其它变量才会被一同替换展开。

#其优点是:

#这种类型变量在定义时,可以引用其它的之前没有定义的变量(可能在后续部分定义,或者是通过make的命令行选项传递的变量)。

#LDSCRIPT变量就是后面才定义的

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

ifndef LDSCRIPT

 #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug

 ifdef CONFIG_SYS_LDSCRIPT

  # need to strip off double quotes

  LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))

 endif

endif

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

#如果定义了CONFIG_SYS_LDSCRIPT,将CONFIG_SYS_LDSCRIPT代表的字符串去掉双引号后赋值给LDSCRIPT变量

#这里我们并没有定义CONFIG_SYS_LDSCRIPT

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

# If there is no specified link script, we look in a number of places for it

ifndef LDSCRIPT

 ifeq ($(CONFIG_NAND_U_BOOT),y)

  LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds

  ifeq ($(wildcard $(LDSCRIPT)),)

   LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot-nand.lds

  endif

 endif

 ifeq ($(wildcard $(LDSCRIPT)),)

  LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds

 endif

 ifeq ($(wildcard $(LDSCRIPT)),)

  LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot.lds

 endif

 ifeq ($(wildcard $(LDSCRIPT)),)

  LDSCRIPT := $(TOPDIR)/arch/$(ARCH)/cpu/u-boot.lds

  # We don't expect a Makefile here

  LDSCRIPT_MAKEFILE_DIR =

 endif

 ifeq ($(wildcard $(LDSCRIPT)),)

$(error could not find linker script)

 endif

endif

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

#注释写的很明确,如果没有用CONFIG_SYS_LDSCRIPT指定LDSCRIPT,那么就在几个地方搜

#第一个地方:如果CONFIG_NAND_U_BOOT是y,就用u-boot-nand.lds        但是这里没有这个定义

#第一个地方没找到,就找第二个地方:u-boot-2012.07/board/samsung/smdk2410    这个目录没有u-boot.lds文件

#第二个地方没找到,就找第三个地方:其中CPUDIR是在顶层的config.mk中定义的,在arch/arm/cpu/arm920t中找    这个目录也没有

#第三个地方没找到,就找第四个地方:arch/arm/cpu/u-boot.lds,这里就找到了!!!!

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

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

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

OBJS  = $(CPUDIR)/start.o

ifeq ($(CPU),x86)

OBJS += $(CPUDIR)/start16.o

OBJS += $(CPUDIR)/resetvec.o

endif

ifeq ($(CPU),ppc4xx)

OBJS += $(CPUDIR)/resetvec.o

endif

ifeq ($(CPU),mpc85xx)

OBJS += $(CPUDIR)/resetvec.o

endif

OBJS := $(addprefix $(obj),$(OBJS))

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

#为OBJS增加前缀,其中obj在顶层目录的config.mk中定义,这里根据实际情况 OBJS就是 arch/arm/cpu/arm920t/start.o

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

LIBS  = lib/libgeneric.o

LIBS += lib/lzma/liblzma.o

LIBS += lib/lzo/liblzo.o

LIBS += lib/zlib/libz.o

ifeq ($(CONFIG_TIZEN),y)

LIBS += lib/tizen/libtizen.o

endif

LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \

 "board/$(VENDOR)/common/lib$(VENDOR).o"; fi)

LIBS += $(CPUDIR)/lib$(CPU).o

ifdef SOC

LIBS += $(CPUDIR)/$(SOC)/lib$(SOC).o

endif

ifeq ($(CPU),ixp)

LIBS += arch/arm/cpu/ixp/npe/libnpe.o

endif

ifeq ($(CONFIG_OF_EMBED),y)

LIBS += dts/libdts.o

endif

LIBS += arch/$(ARCH)/lib/lib$(ARCH).o

LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \

 fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \

 fs/ubifs/libubifs.o

LIBS += net/libnet.o

LIBS += disk/libdisk.o

LIBS += drivers/bios_emulator/libatibiosemu.o

LIBS += drivers/block/libblock.o

LIBS += drivers/dma/libdma.o

LIBS += drivers/fpga/libfpga.o

LIBS += drivers/gpio/libgpio.o

LIBS += drivers/hwmon/libhwmon.o

LIBS += drivers/i2c/libi2c.o

LIBS += drivers/input/libinput.o

LIBS += drivers/misc/libmisc.o

LIBS += drivers/mmc/libmmc.o

LIBS += drivers/mtd/libmtd.o

LIBS += drivers/mtd/nand/libnand.o

LIBS += drivers/mtd/onenand/libonenand.o

LIBS += drivers/mtd/ubi/libubi.o

LIBS += drivers/mtd/spi/libspi_flash.o

LIBS += drivers/net/libnet.o

LIBS += drivers/net/phy/libphy.o

LIBS += drivers/pci/libpci.o

LIBS += drivers/pcmcia/libpcmcia.o

LIBS += drivers/power/libpower.o

LIBS += drivers/spi/libspi.o

ifeq ($(CPU),mpc83xx)

LIBS += drivers/qe/libqe.o

LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o

LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o

endif

ifeq ($(CPU),mpc85xx)

LIBS += drivers/qe/libqe.o

LIBS += drivers/net/fm/libfm.o

LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o

LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o

endif

ifeq ($(CPU),mpc86xx)

LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o

LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o

endif

LIBS += drivers/rtc/librtc.o

LIBS += drivers/serial/libserial.o

ifeq ($(CONFIG_GENERIC_LPC_TPM),y)

LIBS += drivers/tpm/libtpm.o

endif

LIBS += drivers/twserial/libtws.o

LIBS += drivers/usb/eth/libusb_eth.o

LIBS += drivers/usb/gadget/libusb_gadget.o

LIBS += drivers/usb/host/libusb_host.o

LIBS += drivers/usb/musb/libusb_musb.o

LIBS += drivers/usb/phy/libusb_phy.o

LIBS += drivers/usb/ulpi/libusb_ulpi.o

LIBS += drivers/video/libvideo.o

LIBS += drivers/watchdog/libwatchdog.o

LIBS += common/libcommon.o

LIBS += lib/libfdt/libfdt.o

LIBS += api/libapi.o

LIBS += post/libpost.o

ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)

LIBS += $(CPUDIR)/omap-common/libomap-common.o

endif

ifeq ($(SOC),mx5)

LIBS += $(CPUDIR)/imx-common/libimx-common.o

endif

ifeq ($(SOC),mx6)

LIBS += $(CPUDIR)/imx-common/libimx-common.o

endif

ifeq ($(SOC),s5pc1xx)

LIBS += $(CPUDIR)/s5p-common/libs5p-common.o

endif

ifeq ($(SOC),exynos)

LIBS += $(CPUDIR)/s5p-common/libs5p-common.o

endif

LIBS := $(addprefix $(obj),$(sort $(LIBS)))

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

#将LIBS排序后为LIBS增加前缀

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

.PHONY : $(LIBS)

LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o

LIBBOARD := $(addprefix $(obj),$(LIBBOARD))

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

#为LIBBOARD增加前缀,LIBBOARD就是board/samsung/smdk2410/libsmdk2410.o

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

# Add GCC lib

ifdef USE_PRIVATE_LIBGCC

ifeq ("$(USE_PRIVATE_LIBGCC)", "yes")

PLATFORM_LIBGCC = $(OBJTREE)/arch/$(ARCH)/lib/libgcc.o

else

PLATFORM_LIBGCC = -L $(USE_PRIVATE_LIBGCC) -lgcc

endif

else

PLATFORM_LIBGCC := -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc

endif

PLATFORM_LIBS += $(PLATFORM_LIBGCC)

export PLATFORM_LIBS

# Special flags for CPP when processing the linker script.

# Pass the version down so we can handle backwards compatibility

# on the fly.

LDPPFLAGS += \

 -include $(TOPDIR)/include/u-boot/u-boot.lds.h \

 -DCPUDIR=$(CPUDIR) \

 $(shell $(LD) --version | \

  sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')

__OBJS := $(subst $(obj),,$(OBJS))

__LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))

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

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

ifneq ($(CONFIG_BOARD_SIZE_LIMIT),)

BOARD_SIZE_CHECK = \

 @actual=`wc -c $@ | 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中已经分析了CURDIR和SRCTREE都是当前目录,所以这里dir暂时为空

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

ifneq ($(OBJTREE),$(SRCTREE))

# Create object files for SPL in a separate directory

ifeq ($(CONFIG_SPL_BUILD),y)

obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)

else

obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/)

endif

src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/)

$(shell mkdir -p $(obj))

else

# Create object files for SPL in a separate directory

ifeq ($(CONFIG_SPL_BUILD),y)

obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)

$(shell mkdir -p $(obj))

else

obj :=

endif

src :=

endif

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

#首先OBJTREE和SRCTREE都是当前目录,所以执行else

#查找CONFIG_SPL_BUILD是否定义为y,在autoconf.mk中,并没有这个定义,所以obj和src暂时也为空

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

# clean the slate ...

PLATFORM_RELFLAGS =

PLATFORM_CPPFLAGS =

PLATFORM_LDFLAGS =

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

HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer \

    $(HOSTCPPFLAGS)

HOSTSTRIP = strip

#

# Mac OS X / Darwin's C preprocessor is Apple specific.  It

# generates numerous errors and warnings.  We want to bypass it

# and use GNU C's cpp. To do this we pass the -traditional-cpp

# option to the compiler.  Note that the -traditional-cpp flag

# DOES NOT have the same semantics as GNU C's flag, all it does

# is invoke the GNU preprocessor in stock ANSI/ISO C fashion.

#

# Apple's linker is similar, thanks to the new 2 stage linking

# multiple symbol definitions are treated as errors, hence the

# -multiply_defined suppress option to turn off this error.

#

ifeq ($(HOSTOS),darwin)

# get major and minor product version (e.g. '10' and '6' for Snow Leopard)

DARWIN_MAJOR_VERSION = $(shell sw_vers -productVersion | cut -f 1 -d '.')

DARWIN_MINOR_VERSION = $(shell sw_vers -productVersion | cut -f 2 -d '.')

os_x_before = $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \

 $(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;)

# Snow Leopards build environment has no longer restrictions as described above

HOSTCC  = $(call os_x_before, 10, 5, "cc", "gcc")

HOSTCFLAGS += $(call os_x_before, 10, 4, "-traditional-cpp")

HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress")

else

HOSTCC  = gcc

endif

ifeq ($(HOSTOS),cygwin)

HOSTCFLAGS += -ansi

endif

# We build some files with extra pedantic flags to try to minimize things

# that won't build on some weird host compiler -- though there are lots of

# exceptions for files that aren't complaint.

HOSTCFLAGS_NOPED = $(filter-out -pedantic,$(HOSTCFLAGS))

HOSTCFLAGS += -pedantic

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

#HOSTCFLAGS_NOPED是利用filter-out函数从HOSTCFLAGS中过滤掉-pedantic选项

#而HOSTCFLAGS追加上-pedantic选项

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

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

#

# Option checker, gcc version (courtesy linux kernel) to ensure

# only supported compiler options are used

#

CC_OPTIONS_CACHE_FILE := $(OBJTREE)/include/generated/cc_options.mk

CC_TEST_OFILE := $(OBJTREE)/include/generated/cc_test_file.o

-include $(CC_OPTIONS_CACHE_FILE)

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

#定义编译选项

#在cc_options.mk中有如下选项:

# CC_OPTIONS += -marm

# CC_OPTIONS += -mno-thumb-interwork

# CC_OPTIONS += -mapcs-32

# CC_OPTIONS += -malignment-traps

# CC_OPTIONS += -Wno-format-nonliteral

# CC_OPTIONS += -Wno-format-security

# CC_OPTIONS += -mabi=apcs-gnu

# CC_OPTIONS += -mabi=aapcs-linux

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

cc-option-sys = $(shell mkdir -p $(dir $(CC_TEST_OFILE)); \

  if $(CC) $(CFLAGS) $(1) -S -xc /dev/null -o $(CC_TEST_OFILE) \

  > /dev/null 2>&1; then \

  echo 'CC_OPTIONS += $(strip $1)' >> $(CC_OPTIONS_CACHE_FILE); \

  echo "$(1)"; fi)

ifeq ($(CONFIG_CC_OPT_CACHE_DISABLE),y)

cc-option = $(strip $(if $(call cc-option-sys,$1),$1,$2))

else

cc-option = $(strip $(if $(findstring $1,$(CC_OPTIONS)),$1,\

  $(if $(call cc-option-sys,$1),$1,$2)))

endif

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

#定义两个函数,cc-option-sys被cc-option调用

#cc-option被后面的函数调用

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

# cc-version

# Usage gcc-ver := $(call cc-version)

cc-version = $(shell $(SHELL) $(SRCTREE)/tools/gcc-version.sh $(CC))

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

#使用tools/gcc-version.sh脚本来获取编译器的版本

#在顶层makefile中,有调用cc-version函数

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

#

# Include the make variables (CC, etc...)

#

AS = $(CROSS_COMPILE)as

LD = $(CROSS_COMPILE)ld

CC = $(CROSS_COMPILE)gcc

CPP = $(CC) -E

AR = $(CROSS_COMPILE)ar

NM = $(CROSS_COMPILE)nm

LDR = $(CROSS_COMPILE)ldr

STRIP = $(CROSS_COMPILE)strip

OBJCOPY = $(CROSS_COMPILE)objcopy

OBJDUMP = $(CROSS_COMPILE)objdump

RANLIB = $(CROSS_COMPILE)RANLIB

DTC = dtc

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

#定义汇编器,连接器,编译器,打包工具,反汇编工具,值的注意的RANLIB的作用是在静态库有添加新的.o后,负责更新索引.

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

# Load generated board configuration

sinclude $(OBJTREE)/include/autoconf.mk

sinclude $(OBJTREE)/include/config.mk

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

#包上配置编译时产生的autoconf.mk和config.mk文件

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

# Some architecture config.mk files need to know what CPUDIR is set to,

# so calculate CPUDIR before including ARCH/SOC/CPU config.mk files.

# Check if arch/$ARCH/cpu/$CPU exists, otherwise assume arch/$ARCH/cpu contains

# CPU-specific code.

CPUDIR=arch/$(ARCH)/cpu/$(CPU)

ifneq ($(SRCTREE)/$(CPUDIR),$(wildcard $(SRCTREE)/$(CPUDIR)))

CPUDIR=arch/$(ARCH)/cpu

endif

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

#定义CPUDIR为arch/arm/cpu/arm920t

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

sinclude $(TOPDIR)/arch/$(ARCH)/config.mk # include architecture dependend rules

sinclude $(TOPDIR)/$(CPUDIR)/config.mk  # include  CPU specific rules

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

#包上arch/arm/config.mk和/arch/arm/cpu/arm920t/config.mk文件

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

ifdef SOC

sinclude $(TOPDIR)/$(CPUDIR)/$(SOC)/config.mk # include  SoC specific rules

endif

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

#包上arch/arm/cpu/arm920t/s3c24x0/config.mk文件

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

ifdef VENDOR

BOARDDIR = $(VENDOR)/$(BOARD)

else

BOARDDIR = $(BOARD)

endif

ifdef BOARD

sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules

endif

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

#包上board/samsung/smdk2410/config.mk文件

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

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

# We don't actually use $(ARFLAGS) anywhere anymore, so catch people

# who are porting old code to latest mainline but not updating $(AR).

ARFLAGS = $(error update your Makefile to use cmd_link_o_target and not AR)

RELFLAGS= $(PLATFORM_RELFLAGS)

DBGFLAGS= -g # -DDEBUG

OPTFLAGS= -Os #-fomit-frame-pointer

OBJCFLAGS += --gap-fill=0xff

gccincdir := $(shell $(CC) -print-file-name=include)

CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS)  \

 -D__KERNEL__

# Enable garbage collection of un-used sections for SPL

ifeq ($(CONFIG_SPL_BUILD),y)

CPPFLAGS += -ffunction-sections -fdata-sections

LDFLAGS_FINAL += --gc-sections

endif

ifneq ($(CONFIG_SYS_TEXT_BASE),)

CPPFLAGS += -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE)

endif

ifneq ($(CONFIG_SPL_TEXT_BASE),)

CPPFLAGS += -DCONFIG_SPL_TEXT_BASE=$(CONFIG_SPL_TEXT_BASE)

endif

ifneq ($(CONFIG_SPL_PAD_TO),)

CPPFLAGS += -DCONFIG_SPL_PAD_TO=$(CONFIG_SPL_PAD_TO)

endif

ifeq ($(CONFIG_SPL_BUILD),y)

CPPFLAGS += -DCONFIG_SPL_BUILD

endif

ifneq ($(RESET_VECTOR_ADDRESS),)

CPPFLAGS += -DRESET_VECTOR_ADDRESS=$(RESET_VECTOR_ADDRESS)

endif

ifneq ($(OBJTREE),$(SRCTREE))

CPPFLAGS += -I$(OBJTREE)/include2 -I$(OBJTREE)/include

endif

CPPFLAGS += -I$(TOPDIR)/include

CPPFLAGS += -fno-builtin -ffreestanding -nostdinc \

 -isystem $(gccincdir) -pipe $(PLATFORM_CPPFLAGS)

ifdef BUILD_TAG

CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes \

 -DBUILD_TAG='"$(BUILD_TAG)"'

else

CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes

endif

CFLAGS_SSP := $(call cc-option,-fno-stack-protector)

CFLAGS += $(CFLAGS_SSP)

# Some toolchains enable security related warning flags by default,

# but they don't make much sense in the u-boot world, so disable them.

CFLAGS_WARN := $(call cc-option,-Wno-format-nonliteral) \

        $(call cc-option,-Wno-format-security)

CFLAGS += $(CFLAGS_WARN)

# Report stack usage if supported

CFLAGS_STACK := $(call cc-option,-fstack-usage)

CFLAGS += $(CFLAGS_STACK)

# $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g<format>

# option to the assembler.

AFLAGS_DEBUG :=

# turn jbsr into jsr for m68k

ifeq ($(ARCH),m68k)

ifeq ($(findstring 3.4,$(shell $(CC) --version)),3.4)

AFLAGS_DEBUG := -Wa,-gstabs,-S

endif

endif

AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS)

LDFLAGS += $(PLATFORM_LDFLAGS)

LDFLAGS_FINAL += -Bstatic

LDFLAGS_u-boot += -T $(obj)u-boot.lds $(LDFLAGS_FINAL)

ifneq ($(CONFIG_SYS_TEXT_BASE),)

LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)

endif

LDFLAGS_u-boot-spl += -T $(obj)u-boot-spl.lds $(LDFLAGS_FINAL)

ifneq ($(CONFIG_SPL_TEXT_BASE),)

LDFLAGS_u-boot-spl += -Ttext $(CONFIG_SPL_TEXT_BASE)

endif

# Location of a usable BFD library, where we define "usable" as

# "built for ${HOST}, supports ${TARGET}".  Sensible values are

# - When cross-compiling: the root of the cross-environment

# - Linux/ppc (native): /usr

# - NetBSD/ppc (native): you lose ... (must extract these from the

#  binutils build directory, plus the native and U-Boot include

#  files don't like each other)

#

# So far, this is used only by tools/gdb/Makefile.

ifeq ($(HOSTOS),darwin)

BFD_ROOT_DIR =  /usr/local/tools

else

ifeq ($(HOSTARCH),$(ARCH))

# native

BFD_ROOT_DIR =  /usr

else

#BFD_ROOT_DIR =  /LinuxPPC/CDK  # Linux/i386

#BFD_ROOT_DIR =  /usr/pkg/cross  # NetBSD/i386

BFD_ROOT_DIR =  /opt/powerpc

endif

endif

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

export HOSTCC HOSTCFLAGS HOSTLDFLAGS PEDCFLAGS HOSTSTRIP CROSS_COMPILE \

 AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP MAKE

export CONFIG_SYS_TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS

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

# Allow boards to use custom optimize flags on a per dir/file basis

BCURDIR = $(subst $(SRCTREE)/,,$(CURDIR:$(obj)%=%))

ALL_AFLAGS = $(AFLAGS) $(AFLAGS_$(BCURDIR)/$(@F)) $(AFLAGS_$(BCURDIR))

ALL_CFLAGS = $(CFLAGS) $(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR))

EXTRA_CPPFLAGS = $(CPPFLAGS_$(BCURDIR)/$(@F)) $(CPPFLAGS_$(BCURDIR))

ALL_CFLAGS += $(EXTRA_CPPFLAGS)

# The _DEP version uses the $< file target (for dependency generation)

# See rules.mk

EXTRA_CPPFLAGS_DEP = $(CPPFLAGS_$(BCURDIR)/$(addsuffix .o,$(basename $<))) \

  $(CPPFLAGS_$(BCURDIR))

$(obj)%.s: %.S

 $(CPP) $(ALL_AFLAGS) -o $@ $<

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

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

主要是一些变量和函数的定义,编译链接的参数设置以及依赖规则.

最后分析下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的依赖文件

第二个是根据include/config.h的文件内容,利用tools/scripts/define2mk.sed脚本将所有的CONFIG提取到autoconf.mk文件中

终极目标是:ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map

u-boot.srec也是根据u-boot用objcopy工具搞出来的,不知的什么作用

u-boot.bin也是根据u-boot用objcopy工具搞出来的,最终烧写的二进制bin档

System.map是符号列表

$(obj)u-boot.bin: $(obj)u-boot

  $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@

  $(BOARD_SIZE_CHECK)

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

#要得到最后的u-boot.bin,必须得到u-boot.u-boot.bin是最后要烧写到板子上的二进制bin档

#利用objcopy来得到这个二进制文件($@是规则的目标文件名,$<是规则的第一个依赖文件名)

#调用BOARD_SIZE_CHECK

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

u-boot的依赖分析:

$(obj)u-boot: depend \

$(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds

$(GEN_UBOOT)

u-boot 依赖depend $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds

然后用$(GEN_UBOOT)生成最后的u-boot,GEN_UBOOT就是用ld链接的过程

a.看一下depend:

depend dep: $(TIMESTAMP_FILE) $(VERSION_FILE) \

$(obj)include/autoconf.mk \

$(obj)include/generated/generic-asm-offsets.h \

$(obj)include/generated/asm-offsets.h

for dir in $(SUBDIRS) $(CPUDIR) $(LDSCRIPT_MAKEFILE_DIR) ; do \

$(MAKE) -C $$dir _depend ; done

对$(SUBDIRS) $(CPUDIR) $(LDSCRIPT_MAKEFILE_DIR)目录生成depend依赖文件;

而_depend是在rules.mk中定义的,利用CC的-M选项生成依赖文件.

b.看一下$(SUBDIR_TOOLS):

        tools目录

c.看一下$(OBJS):

$(OBJS): depend

$(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))

看下$(if $(REMOTE_BUILD),$@,$(notdir $@))

因为$(REMOTE_BUILD)为空,所以返回的是$(notdir $@)的值;

因为$@指的是规则的目标,所以就是$(OBJS),而$(OBJS)就是arch/arm/cpu/arm920t/start.o

notdir内嵌函数返回的文件名;所以返回start.o

执行makc -C arch/arm/cpu/arm920t start.o

d.$(LIBBOARD)

$(LIBBOARD): depend $(LIBS)

$(MAKE) -C $(dir $(subst $(obj),,$@))

执行make -C board/samsung/smdk2410

e.$(LIBS)

$(LIBS): depend $(SUBDIR_TOOLS)

$(MAKE) -C $(dir $(subst $(obj),,$@))

进入到LIBS包含的很多目录,执行make,生成很多.a文件.

f.$(LDSCRIPT)

$(LDSCRIPT): depend

$(MAKE) -C $(dir $@) $(notdir $@)

在前面找链接脚本时已然知晓LDSCRIPT就是arch/arm/cpu/u-boot.lds

执行make -C arch/arm/cpu u-boot.lds  这个目录没有makefile,这什么意思?!!!

g.$(obj)u-boot.lds

$(obj)u-boot.lds: $(LDSCRIPT)

$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@

      这些就是编译uboot的规则,分析的比较粗糙,在移植的过程中肯定还会遇到各式各样的问题,在移植过程中再进一步深入并修正.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: