GNU ARM 어 셈 블 리 -- (17) u - boot 의 makefile 과 mkconfig 해석

43792 단어
        자신 이 쓴 bootloader 는 kernel 을 유도 할 수 있 습 니 다. 저 는 신비 로 웠 던 U - boot 코드 가 도전 하지 않 을 것 이 라 고 생각 합 니 다. 그러나 사실은 U - boot 가 우수한 오픈 소스 코드 로 서 읽 기 에 도전 적 이 고 읽 을 만 한 가치 가 있 습 니 다!
        첫 번 째 문제 읽 기: Makefile 과 셸 스 크 립 트 를 읽 을 수 없습니다.
        말하자면 Liux 를 한 지 오래 되 었 습 니 다. Makefile 과 셸 스 크 립 트 를 모두 접 한 적 이 있 습 니 다. 하지만 정말 다 알 고 있 을 뿐 입 니 다. 회사 의 Makefile 과 셸 은 한눈 에 바라 보 는 맞 춤 법, 초급 쓰기, 간단 한 응용 프로그램 이기 때 문 입 니 다. 아무리 인터넷 에서 오래된 소스 코드 를 마음대로 사용 해도 Makefile 과 셸 은 복잡 합 니 다. 조심 하지 않 아 qt 의 qmake 가 프로젝트 파일 에 따라 생 성 된 Makefile 도 간단 합 니 다.그러나 qmake 는 남 의 외국인 이 쓴 것 이다. 다른 언어 는 말 하지 않 고 Makefile 과 셸 만 보면 중국 과 외국 의 차이 가 바로 거기에 있다.
        이번에 u - boot 를 tq 2440 에 이식 하려 고 합 니 다. 선택 한 u - boot 버 전 은 u - boot - 2012.07 입 니 다.
        다음은 U - boot 설정 과 컴 파일 된 Makefile mkconfig config. mk 등 파일 에 대한 해석 입 니 다. 어떤 해석 은 제 가 원본 파일 에 문자 주석 을 추가 한 것 입 니 다. 어떤 해석 은 따로 쓴 것 입 니 다. 해석 에 오류 가 있 을 수 있 습 니 다. 만약 에 독자 가 발견 하면 지적 해 주시 기 바 랍 니 다. 감사합니다.
        u - boot 를 컴 파일 하 는 과정 에서 make xxxconfig 와 make 두 단계
        make smdk 2410 로config 예:
        smdk 2410config 가 목표 일 때 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 xxxconfig 는 모두 이 목표 입 니 다. 목표 의 의존 도 는 unconfig 입 니 다. unconfig 의 명령 은 일부 파일 을 삭제 하 는 것 입 니 다. 이 파일 들 은 바로 make xxx 입 니 다.config 과정 에서 발생 하 는. unconfig 는 설정 을 정리 하 는 것 입 니 다.
        @ $(MK CONFIG) - A $(@: config =)        사실 mkconfig - A smdk 2410 을 실 행 했 습 니 다.        이 줄 에 한 줄 을 추가 할 수 있 습 니 다: echo $@        smdk 2410 을 출력 합 니 다.config, $@ 은 목 표를 가리 키 기 때 문 입 니 다.        $(@: config =) 변수의 대체 참조 입 니 다.        형식 은 "$(VAR: A = B)"(또는 "${VAR: A = B}") 입 니 다. 변수 "VAR"의 모든 "A"문자 가 끝 나 는 글 자 를 "B"로 바 꾸 는 것 을 의미 합 니 다.그래서 smdk 2410config 끝의config 가 제거 되 었 습 니 다.
        다음은 mkconfig 스 크 립 트 를 실행 합 니 다. mkconfig - A smdk 2410
        주석 을 추가 한 mkconfig 파일 을 보 여 줍 니 다:
#!/bin/sh -e

# Script to create header files and links to configure
# U-Boot for a specific board.
#
# Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]
#
# (C) 2002-2010 DENX Software Engineering, Wolfgang Denk <[email protected]>
#

APPEND=no	# Default: Create new config file
BOARD_NAME=""	# Name to print in make output
TARGETS=""

arch=""
cpu=""
board=""
vendor=""
soc=""
options=""

echo $#
if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
	# Automatic mode
	line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
		echo "make: *** No rule to make target \`$2_config'.  Stop." >&2
		exit 1
	}

	set ${line}
	echo ${line}
	echo $#
	# add default board name if needed
	[ $# = 3 ] && set ${line} ${1}
#####################################
#我们执行脚本的命令是mkconfig -A smdk2410,$#表示的是参数的个数,$1表示的是第一个参数
#line 就是在boards.cfg文件中smdk2410的那行,而-i表示忽略大小写
#在boards.cfg文件中,有
#Target                     ARCH        CPU         Board name          Vendor	        SoC         Options
#smdk2410                     arm         arm920t     -                   samsung        s3c24x0
#  set ${line}
#  set也可用于在脚本内部给出其运行参数,所以这个时候参数就变为"smdk2410 arm arm920t - samsung s3c24x0"
#这个时候参数个数就变成6个了
######################################
elif [ "${MAKEFLAGS+set}${MAKELEVEL+set}" = "setset" ] ; then
	# only warn when using a config target in the Makefile
	cat <<-EOF

	warning: Please migrate to boards.cfg.  Failure to do so will
	         mean removal of your board in the next release.

	EOF
	sleep 5
fi

echo $1
while [ $# -gt 0 ] ; do
	case "$1" in
	--) shift ; break ;;
	-a) shift ; APPEND=yes ;;
	-n) shift ; BOARD_NAME="${1%_config}" ; shift ;;
	-t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;
	*)  break ;;
	esac
done
################################################
#因为$1的值为smdk2410,所以case找不到对应的
#################################################

[ $# -lt 4 ] && exit 1
[ $# -gt 7 ] && exit 1
##################################################
#对参数个数做检查,小于4个或大于7个就退出
##################################################

# Strip all options and/or _config suffixes
CONFIG_NAME="${1%_config}"
####################
#CONFIG_NAME的值为smdk2410
#########################
echo config_
echo ${CONFIG_NAME}

[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"
echo board
echo ${BOARD_NAME}
###########################################
#如果BOARD_NAME在之前已经被设定了,就不做任何动作;如果为空,就设定为smdk2410.这里设定为smdk2410
############################################

arch="$2"
cpu="$3"
if [ "$4" = "-" ] ; then
	board=${BOARD_NAME}
else
	board="$4"
fi
######################################################
#设定arch变量的值为arm
#cpu变量的值为arm920t
#因为第四个变量为"-",所以board变量的值为smdk2410
#######################################################


[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6"
#############################################################
#设定verdor变量的值为samsung
#设定soc变量的值为s3c24x0
#############################################################
[ $# -gt 6 ] && [ "$7" != "-" ] && {
	# check if we have a board config name in the options field
	# the options field mave have a board config name and a list
	# of options, both separated by a colon (':'); the options are
	# separated by commas (',').
	#
	# Check for board name
	tmp="${7%:*}"
	if [ "$tmp" ] ; then
		CONFIG_NAME="$tmp"
	fi
	# Check if we only have a colon...
	if [ "${tmp}" != "$7" ] ; then
		options=${7#*:}
		TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}"
	fi
}
#################################################
#因为我们的变量个数就是6个,这一段不执行
#################################################
echo ${ARCH}
echo ${arch}
if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then
	echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2
	exit 1
fi
####################################################
#ARCH是在顶层makefile中定义的,在此刻还是为空的。
#如果ARCH已经有值了,那么就检测ARCH和arch是否匹配了.
####################################################

if [ "$options" ] ; then
	echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
	echo "Configuring for ${BOARD_NAME} board..."
fi
###########################################################################
#我们没有定义options变量,所以输出Configuring for smdk2410 board...
###########################################################################


#
# Create link to architecture specific headers
#
echo ${SRCTREE}
echo ${OBJTREE}
if [ "$SRCTREE" != "$OBJTREE" ] ; then
	mkdir -p ${OBJTREE}/include
	mkdir -p ${OBJTREE}/include2
	cd ${OBJTREE}/include2
	rm -f asm
	ln -s ${SRCTREE}/arch/${arch}/include/asm asm
	LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/
	cd ../include
	mkdir -p asm
else
	cd ./include
	rm -f asm
	ln -s ../arch/${arch}/include/asm asm
fi
#############################################################################
#在makefile中我们已经知道SRCTREE和OBJTREE都是当前目录,所以这里执行else
#进入./include目录,删除asm链接,并重新建立链接asm,指向arch/arm/include/asm
#############################################################################

rm -f asm/arch
#########################################################################
#删除include目录下的asm下的arch链接文件
########################################################################

ss=
echo ${ss}
if [ -z "${ss}" ] ; then
	echo "null"
else
	echo "not null"
fi

echo ${LNPREFIX}
if [ -z "${soc}" ] ; then
	ln -s ${LNPREFIX}arch-${cpu} asm/arch
else
	ln -s ${LNPREFIX}arch-${soc} asm/arch
fi
##########################################################
#-z用来检测字符串是否为空,为空返回真
#这里我们的soc不为空,执行else
#将asm/arch链向arch-s3c24x0,看一下arch-s3c24x0目录,里面都是s3c24x0相关的头文件
##########################################################

if [ "${arch}" = "arm" ] ; then
	rm -f asm/proc
	ln -s ${LNPREFIX}proc-armv asm/proc
fi
###########################################################
#删除asm/proc链接文件
#将asm/proc链向proc-armv目录,该目录下是四个头文件:domain.h\processor.h\ptrace.h\system.h
#############################################################

#
# Create include file for Make
#
echo "ARCH   = ${arch}"  >  config.mk
echo "CPU    = ${cpu}"   >> config.mk
echo "BOARD  = ${board}" >> config.mk

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

[ "${soc}"    ] && echo "SOC    = ${soc}"    >> config.mk
######################################################################
#上面几句的作用在注释中描述的很清楚
#include/config.mk的文件如下:
#ARCH   = arm
#CPU    = arm920t
#BOARD  = smdk2410
#VENDOR = samsung
#SOC    = s3c24x0
######################################################################

# Assign board directory to BOARDIR variable
if [ -z "${vendor}" ] ; then
    BOARDDIR=${board}
else
    BOARDDIR=${vendor}/${board}
fi
echo ${BOARDDIR}
#######################################################################
#因为vendor变量不为空,所以执行else
#BOARDDIR的值为samsung/s3c24x0
########################################################################
#
# Create board specific header file
#
if [ "$APPEND" = "yes" ]	# Append to existing config file
then
	echo >> config.h
else
	> config.h		# Create new config file
fi
########################################################################
#在文件的最开头可以看到APPEND为no,所以这里我们在include文件夹下建立config.h文件
#######################################################################
echo "/* Automatically generated - do not edit */" >>config.h

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

echo "#define CONFIG_SYS_ARCH  \"${arch}\""  >> config.h
echo "#define CONFIG_SYS_CPU   \"${cpu}\""   >> config.h
echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h

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

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

cat << EOF >> config.h
#define CONFIG_BOARDDIR board/$BOARDDIR
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/${CONFIG_NAME}.h>
#include <asm/config.h>
#include <config_fallbacks.h>
EOF
######################################################
#生成config.h文件如下:
#	/* Automatically generated - do not edit */
#	#define CONFIG_SYS_ARCH  "arm"
#	#define CONFIG_SYS_CPU   "arm920t"
#	#define CONFIG_SYS_BOARD "smdk2410"
#	#define CONFIG_SYS_VENDOR "samsung"
#	#define CONFIG_SYS_SOC    "s3c24x0"
#	#define CONFIG_BOARDDIR board/samsung/smdk2410
#	#include <config_cmd_defaults.h>
#	#include <config_defaults.h>
#	#include <configs/smdk2410.h>
#	#include <asm/config.h>
#	#include <config_fallbacks.h>
#####################################################
exit 0
        
        make xxx_config 이후 주요 변 화 는 파일 이 몇 개 더 생 겼 습 니 다.
        1.include/asm    -->     arch/arm/include/arm
        2.include/asm/arch  -->  arch-s3c24x0
        3.include/asm/proc  -->  proc-armv         4. include 디 렉 터 리 에 config. mk 파일 을 새로 만 들 었 습 니 다. 파일 내용 은 ARCH CPU BOARD VENDOR SOC 의 정의 입 니 다.
        5. include 디 렉 터 리 에 config. h 파일 을 새로 만 들 었 습 니 다.
        이어서 Make:
        일부 Makefile 의 설명 을 보 여 줍 니 다. 주로 변수의 정의 입 니 다.
VERSION = 2012
PATCHLEVEL = 07
SUBLEVEL =
EXTRAVERSION =
ifneq "$(SUBLEVEL)" ""
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
else
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL)$(EXTRAVERSION)
endif
################################
#定义U_BOOT_VERSION为2012.07
#####################################


TIMESTAMP_FILE = $(obj)include/generated/timestamp_autogenerated.h
VERSION_FILE = $(obj)include/generated/version_autogenerated.h
###############################
#因为obj为空,所以定义TIMESTAMP_FILE为include/generated/timestamp_autogenerated.h
#定义VERSION_FILE为include/generated/version_autogenerated.h
#****************

HOSTARCH := $(shell uname -m | \
	sed -e s/i.86/x86/ \
	    -e s/sun4u/sparc64/ \
	    -e s/arm.*/arm/ \
	    -e s/sa110/arm/ \
	    -e s/ppc64/powerpc/ \
	    -e s/ppc/powerpc/ \
	    -e s/macppc/powerpc/\
	    -e s/sh.*/sh/)

HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
	    sed -e 's/\(cygwin\).*/cygwin/')

# Set shell to bash if possible, otherwise fall back to sh
SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
	else if [ -x /bin/bash ]; then echo /bin/bash; \
	else echo sh; fi; fi)

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

# Deal with colliding definitions from tcsh etc.
VENDOR=

#########################################################################
# Allow for silent builds
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
###########################
#因为MAKEFLAGS变量的字符串为空,找不到s,所以ifeq为真,XECHO = echo
###########################


#########################################################################
#
# U-boot build supports producing a object files to the separate external
# directory. Two use cases are supported:
#
# 1) Add O= to the make command line
# 'make O=/tmp/build all'
#
# 2) Set environement variable BUILD_DIR to point to the desired location
# 'export BUILD_DIR=/tmp/build'
# 'make'
#
# The second approach can also be used with a MAKEALL script
# 'export BUILD_DIR=/tmp/build'
# './MAKEALL'
#
# Command line 'O=' setting overrides BUILD_DIR environent variable.
#
# When none of the above methods is used the local build is performed and
# the object files are placed in the source directory.
#

ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif
#################################
#如果没有在make命令行中定义O=/tmp之类的,那么BUILD_DIR就为/tmp,否则为空。
#当使用make O=/tmp时,表明#ifdef O有定义,而$(origin O)返回的就是"command line"
#################################

ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)

# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})

# Verify if it was successful.
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif # ifneq ($(BUILD_DIR),)
#################################
#如果BUILD_DIR不为空,那么这几句就执行:
#首先,saved-output变量也是BUILD_DIR的值
#如果BUILD_DIR不存在,那么就创建BUILD_DIR目录
#检测BUILD_DIR目录是否成功建好了,如果有问题就输出错误信息
#################################


OBJTREE		:= $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SPLTREE		:= $(OBJTREE)/spl
SRCTREE		:= $(CURDIR)
TOPDIR		:= $(SRCTREE)
LNDIR		:= $(OBJTREE)
export	TOPDIR SRCTREE OBJTREE SPLTREE
###########################################
#如果BUILD_DIR有值,那么OBJTREE就是BUILD_DIR的值,如果BUILD_DIR为空,那么OBJTREE就是CURDIR的值,$(CURDIR)时GNU Make内嵌的变量,是当前目录。
#我们在make时候不加O=/tmp之类的参数,所以OBJTREE就是当前工作目录,SPLTREE是当前工作目录下的spl目录,SRCTREE时当前工作目录,TOPDIR也是当前目录,LNDIR也是当前目录。
##########################################

MKCONFIG	:= $(SRCTREE)/mkconfig
export MKCONFIG
#############################################
#MKCONFIG定义为当前工作目录下的mkconfig脚本,并export
#############################################

ifneq ($(OBJTREE),$(SRCTREE))
REMOTE_BUILD	:= 1
export REMOTE_BUILD
endif
####################################################################
#在我们的执行中,OBJTREE和SRCTREE是相等的,所以不管了
###################################################################

# $(obj) and (src) are defined in config.mk but here in main Makefile
# we also need them before config.mk is included which is the case for
# some targets like unconfig, clean, clobber, distclean, etc.
ifneq ($(OBJTREE),$(SRCTREE))
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
endif
export obj src
#######################################
#可以先看下上面的注释   因为两个路径相同,所以执行else
#########################################

# Make sure CDPATH settings don't interfere
unexport CDPATH

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

# The "tools" are needed early, so put this first
# Don't include stuff already done in $(LIBS)
# The "examples" conditionally depend on U-Boot (say, when USE_PRIVATE_LIBGCC
# is "yes"), so compile examples after U-Boot is compiled.
SUBDIR_TOOLS = tools
SUBDIR_EXAMPLES = examples/standalone examples/api
SUBDIRS = $(SUBDIR_TOOLS)
###############################################
#定义SUBDIR_TOOLS SUBDIR_EXAMPLES 和 SUBDIRS
###############################################

.PHONY : $(SUBDIRS) $(VERSION_FILE) $(TIMESTAMP_FILE)
########################
#定义几个伪目标
########################

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

# Include autoconf.mk before config.mk so that the config options are available
# to all top level build files.  We need the dummy all: target to prevent the
# dependency target in autoconf.mk.dep from being the default.
all:
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk
###################################################################################
#包含auoconf.mk和autoconf.mk.dep文件
###################################################################################
ifndef CONFIG_SANDBOX
SUBDIRS += $(SUBDIR_EXAMPLES)
endif
###################################
#追加SUBDIRS 为"tools  examples/standalone examples/api"
###################################

# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export	ARCH CPU BOARD VENDOR SOC
#######################################
#包含include/config.mk文件,这个文件是在make xxx_config过程中产生的
#######################################

# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif
#######################################
#看看注释就知道了,但是很显示我们的HOSTARCH是x86的,目标时arm的
########################################

# load other configuration
include $(TOPDIR)/config.mk
#######################################
#包含uboot顶层目录的config.mk文件
#######################################

# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
# that (or fail if absent).  Otherwise, search for a linker script in a
# standard location.
LDSCRIPT_MAKEFILE_DIR = $(dir $(LDSCRIPT))
##############################################################################
#用等号赋值的变量是递归方式扩展的变量。变量定义时,变量值中对其他变量的引用不会被替换展开;
#而是变量在引用它的地方替换展开的同时,它所引用的其它变量才会被一同替换展开。
#其优点是:
#这种类型变量在定义时,可以引用其它的之前没有定义的变量(可能在后续部分定义,或者是通过make的命令行选项传递的变量)。
#LDSCRIPT变量就是后面才定义的
##############################################################################

ifndef LDSCRIPT
	#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
	ifdef CONFIG_SYS_LDSCRIPT
		# need to strip off double quotes
		LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
	endif
endif
#######################################################################################
#如果定义了CONFIG_SYS_LDSCRIPT,将CONFIG_SYS_LDSCRIPT代表的字符串去掉双引号后赋值给LDSCRIPT变量
#这里我们并没有定义CONFIG_SYS_LDSCRIPT
#######################################################################################

# If there is no specified link script, we look in a number of places for it
ifndef LDSCRIPT
	ifeq ($(CONFIG_NAND_U_BOOT),y)
		LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
		ifeq ($(wildcard $(LDSCRIPT)),)
			LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot-nand.lds
		endif
	endif
	ifeq ($(wildcard $(LDSCRIPT)),)
		LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
	endif
	ifeq ($(wildcard $(LDSCRIPT)),)
		LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot.lds
	endif
	ifeq ($(wildcard $(LDSCRIPT)),)
		LDSCRIPT := $(TOPDIR)/arch/$(ARCH)/cpu/u-boot.lds
		# We don't expect a Makefile here
		LDSCRIPT_MAKEFILE_DIR =
	endif
	ifeq ($(wildcard $(LDSCRIPT)),)
$(error could not find linker script)
	endif
endif
##########################################################################################
#注释写的很明确,如果没有用CONFIG_SYS_LDSCRIPT指定LDSCRIPT,那么就在几个地方搜
#第一个地方:如果CONFIG_NAND_U_BOOT是y,就用u-boot-nand.lds         但是这里没有这个定义
#第一个地方没找到,就找第二个地方:u-boot-2012.07/board/samsung/smdk2410     这个目录没有u-boot.lds文件
#第二个地方没找到,就找第三个地方:其中CPUDIR是在顶层的config.mk中定义的,在arch/arm/cpu/arm920t中找    这个目录也没有
#第三个地方没找到,就找第四个地方:arch/arm/cpu/u-boot.lds,这里就找到了!!!!
##########################################################################################

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

OBJS  = $(CPUDIR)/start.o
ifeq ($(CPU),x86)
OBJS += $(CPUDIR)/start16.o
OBJS += $(CPUDIR)/resetvec.o
endif
ifeq ($(CPU),ppc4xx)
OBJS += $(CPUDIR)/resetvec.o
endif
ifeq ($(CPU),mpc85xx)
OBJS += $(CPUDIR)/resetvec.o
endif

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

LIBS  = lib/libgeneric.o
LIBS += lib/lzma/liblzma.o
LIBS += lib/lzo/liblzo.o
LIBS += lib/zlib/libz.o
ifeq ($(CONFIG_TIZEN),y)
LIBS += lib/tizen/libtizen.o
endif
LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \
	"board/$(VENDOR)/common/lib$(VENDOR).o"; fi)
LIBS += $(CPUDIR)/lib$(CPU).o
ifdef SOC
LIBS += $(CPUDIR)/$(SOC)/lib$(SOC).o
endif
ifeq ($(CPU),ixp)
LIBS += arch/arm/cpu/ixp/npe/libnpe.o
endif
ifeq ($(CONFIG_OF_EMBED),y)
LIBS += dts/libdts.o
endif
LIBS += arch/$(ARCH)/lib/lib$(ARCH).o
LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \
	fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \
	fs/ubifs/libubifs.o
LIBS += net/libnet.o
LIBS += disk/libdisk.o
LIBS += drivers/bios_emulator/libatibiosemu.o
LIBS += drivers/block/libblock.o
LIBS += drivers/dma/libdma.o
LIBS += drivers/fpga/libfpga.o
LIBS += drivers/gpio/libgpio.o
LIBS += drivers/hwmon/libhwmon.o
LIBS += drivers/i2c/libi2c.o
LIBS += drivers/input/libinput.o
LIBS += drivers/misc/libmisc.o
LIBS += drivers/mmc/libmmc.o
LIBS += drivers/mtd/libmtd.o
LIBS += drivers/mtd/nand/libnand.o
LIBS += drivers/mtd/onenand/libonenand.o
LIBS += drivers/mtd/ubi/libubi.o
LIBS += drivers/mtd/spi/libspi_flash.o
LIBS += drivers/net/libnet.o
LIBS += drivers/net/phy/libphy.o
LIBS += drivers/pci/libpci.o
LIBS += drivers/pcmcia/libpcmcia.o
LIBS += drivers/power/libpower.o
LIBS += drivers/spi/libspi.o
ifeq ($(CPU),mpc83xx)
LIBS += drivers/qe/libqe.o
LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
endif
ifeq ($(CPU),mpc85xx)
LIBS += drivers/qe/libqe.o
LIBS += drivers/net/fm/libfm.o
LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
endif
ifeq ($(CPU),mpc86xx)
LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
endif
LIBS += drivers/rtc/librtc.o
LIBS += drivers/serial/libserial.o
ifeq ($(CONFIG_GENERIC_LPC_TPM),y)
LIBS += drivers/tpm/libtpm.o
endif
LIBS += drivers/twserial/libtws.o
LIBS += drivers/usb/eth/libusb_eth.o
LIBS += drivers/usb/gadget/libusb_gadget.o
LIBS += drivers/usb/host/libusb_host.o
LIBS += drivers/usb/musb/libusb_musb.o
LIBS += drivers/usb/phy/libusb_phy.o
LIBS += drivers/usb/ulpi/libusb_ulpi.o
LIBS += drivers/video/libvideo.o
LIBS += drivers/watchdog/libwatchdog.o
LIBS += common/libcommon.o
LIBS += lib/libfdt/libfdt.o
LIBS += api/libapi.o
LIBS += post/libpost.o

ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
LIBS += $(CPUDIR)/omap-common/libomap-common.o
endif

ifeq ($(SOC),mx5)
LIBS += $(CPUDIR)/imx-common/libimx-common.o
endif
ifeq ($(SOC),mx6)
LIBS += $(CPUDIR)/imx-common/libimx-common.o
endif

ifeq ($(SOC),s5pc1xx)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.o
endif
ifeq ($(SOC),exynos)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.o
endif

LIBS := $(addprefix $(obj),$(sort $(LIBS)))
########################################
#将LIBS排序后为LIBS增加前缀
#########################################
.PHONY : $(LIBS)

LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
###########################################
#为LIBBOARD增加前缀,LIBBOARD就是board/samsung/smdk2410/libsmdk2410.o
###########################################

# Add GCC lib
ifdef USE_PRIVATE_LIBGCC
ifeq ("$(USE_PRIVATE_LIBGCC)", "yes")
PLATFORM_LIBGCC = $(OBJTREE)/arch/$(ARCH)/lib/libgcc.o
else
PLATFORM_LIBGCC = -L $(USE_PRIVATE_LIBGCC) -lgcc
endif
else
PLATFORM_LIBGCC := -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
endif
PLATFORM_LIBS += $(PLATFORM_LIBGCC)
export PLATFORM_LIBS

# Special flags for CPP when processing the linker script.
# Pass the version down so we can handle backwards compatibility
# on the fly.
LDPPFLAGS += \
	-include $(TOPDIR)/include/u-boot/u-boot.lds.h \
	-DCPUDIR=$(CPUDIR) \
	$(shell $(LD) --version | \
	  sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')

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

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

ifneq ($(CONFIG_BOARD_SIZE_LIMIT),)
BOARD_SIZE_CHECK = \
	@actual=`wc -c $@ | 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, [email protected].
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#

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

ifeq ($(CURDIR),$(SRCTREE))
dir :=
else
dir := $(subst $(SRCTREE)/,,$(CURDIR))
endif
###########################################################################
#在顶层makefile中已经分析了CURDIR和SRCTREE都是当前目录,所以这里dir暂时为空
###########################################################################
ifneq ($(OBJTREE),$(SRCTREE))
# Create object files for SPL in a separate directory
ifeq ($(CONFIG_SPL_BUILD),y)
obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)
else
obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/)
endif
src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/)

$(shell mkdir -p $(obj))
else
# Create object files for SPL in a separate directory
ifeq ($(CONFIG_SPL_BUILD),y)
obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)

$(shell mkdir -p $(obj))
else
obj :=
endif
src :=
endif
########################################################################################
#首先OBJTREE和SRCTREE都是当前目录,所以执行else
#查找CONFIG_SPL_BUILD是否定义为y,在autoconf.mk中,并没有这个定义,所以obj和src暂时也为空
########################################################################################

# clean the slate ...
PLATFORM_RELFLAGS =
PLATFORM_CPPFLAGS =
PLATFORM_LDFLAGS =

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

HOSTCFLAGS	= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer \
		  $(HOSTCPPFLAGS)
HOSTSTRIP	= strip

#
# Mac OS X / Darwin's C preprocessor is Apple specific.  It
# generates numerous errors and warnings.  We want to bypass it
# and use GNU C's cpp.	To do this we pass the -traditional-cpp
# option to the compiler.  Note that the -traditional-cpp flag
# DOES NOT have the same semantics as GNU C's flag, all it does
# is invoke the GNU preprocessor in stock ANSI/ISO C fashion.
#
# Apple's linker is similar, thanks to the new 2 stage linking
# multiple symbol definitions are treated as errors, hence the
# -multiply_defined suppress option to turn off this error.
#

ifeq ($(HOSTOS),darwin)
# get major and minor product version (e.g. '10' and '6' for Snow Leopard)
DARWIN_MAJOR_VERSION	= $(shell sw_vers -productVersion | cut -f 1 -d '.')
DARWIN_MINOR_VERSION	= $(shell sw_vers -productVersion | cut -f 2 -d '.')

os_x_before	= $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \
	$(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;)

# Snow Leopards build environment has no longer restrictions as described above
HOSTCC		 = $(call os_x_before, 10, 5, "cc", "gcc")
HOSTCFLAGS	+= $(call os_x_before, 10, 4, "-traditional-cpp")
HOSTLDFLAGS	+= $(call os_x_before, 10, 5, "-multiply_defined suppress")
else
HOSTCC		= gcc
endif

ifeq ($(HOSTOS),cygwin)
HOSTCFLAGS	+= -ansi
endif

# We build some files with extra pedantic flags to try to minimize things
# that won't build on some weird host compiler -- though there are lots of
# exceptions for files that aren't complaint.

HOSTCFLAGS_NOPED = $(filter-out -pedantic,$(HOSTCFLAGS))
HOSTCFLAGS	+= -pedantic
############################################################
#HOSTCFLAGS_NOPED是利用filter-out函数从HOSTCFLAGS中过滤掉-pedantic选项
#而HOSTCFLAGS追加上-pedantic选项
############################################################

#########################################################################
#
# Option checker, gcc version (courtesy linux kernel) to ensure
# only supported compiler options are used
#
CC_OPTIONS_CACHE_FILE := $(OBJTREE)/include/generated/cc_options.mk
CC_TEST_OFILE := $(OBJTREE)/include/generated/cc_test_file.o

-include $(CC_OPTIONS_CACHE_FILE)
#############################################################################
#定义编译选项
#在cc_options.mk中有如下选项:
#	CC_OPTIONS += -marm
#	CC_OPTIONS += -mno-thumb-interwork
#	CC_OPTIONS += -mapcs-32
#	CC_OPTIONS += -malignment-traps
#	CC_OPTIONS += -Wno-format-nonliteral
#	CC_OPTIONS += -Wno-format-security
#	CC_OPTIONS += -mabi=apcs-gnu
#	CC_OPTIONS += -mabi=aapcs-linux
#############################################################################

cc-option-sys = $(shell mkdir -p $(dir $(CC_TEST_OFILE)); \
		if $(CC) $(CFLAGS) $(1) -S -xc /dev/null -o $(CC_TEST_OFILE) \
		> /dev/null 2>&1; then \
		echo 'CC_OPTIONS += $(strip $1)' >> $(CC_OPTIONS_CACHE_FILE); \
		echo "$(1)"; fi)

ifeq ($(CONFIG_CC_OPT_CACHE_DISABLE),y)
cc-option = $(strip $(if $(call cc-option-sys,$1),$1,$2))
else
cc-option = $(strip $(if $(findstring $1,$(CC_OPTIONS)),$1,\
		$(if $(call cc-option-sys,$1),$1,$2)))
endif
###########################################################################################
#定义两个函数,cc-option-sys被cc-option调用
#cc-option被后面的函数调用
############################################################################################

# cc-version
# Usage gcc-ver := $(call cc-version)
cc-version = $(shell $(SHELL) $(SRCTREE)/tools/gcc-version.sh $(CC))
##########################################################################################
#使用tools/gcc-version.sh脚本来获取编译器的版本
#在顶层makefile中,有调用cc-version函数
##########################################################################################
#
# Include the make variables (CC, etc...)
#
AS	= $(CROSS_COMPILE)as
LD	= $(CROSS_COMPILE)ld
CC	= $(CROSS_COMPILE)gcc
CPP	= $(CC) -E
AR	= $(CROSS_COMPILE)ar
NM	= $(CROSS_COMPILE)nm
LDR	= $(CROSS_COMPILE)ldr
STRIP	= $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB	= $(CROSS_COMPILE)RANLIB
DTC	= dtc
#########################################################################
#定义汇编器,连接器,编译器,打包工具,反汇编工具,值的注意的RANLIB的作用是在静态库有添加新的.o后,负责更新索引.
#########################################################################

# Load generated board configuration
sinclude $(OBJTREE)/include/autoconf.mk
sinclude $(OBJTREE)/include/config.mk
################################################################################################
#包上配置编译时产生的autoconf.mk和config.mk文件
################################################################################################

# Some architecture config.mk files need to know what CPUDIR is set to,
# so calculate CPUDIR before including ARCH/SOC/CPU config.mk files.
# Check if arch/$ARCH/cpu/$CPU exists, otherwise assume arch/$ARCH/cpu contains
# CPU-specific code.
CPUDIR=arch/$(ARCH)/cpu/$(CPU)
ifneq ($(SRCTREE)/$(CPUDIR),$(wildcard $(SRCTREE)/$(CPUDIR)))
CPUDIR=arch/$(ARCH)/cpu
endif
#################################################################################################
#定义CPUDIR为arch/arm/cpu/arm920t
#################################################################################################

sinclude $(TOPDIR)/arch/$(ARCH)/config.mk	# include architecture dependend rules
sinclude $(TOPDIR)/$(CPUDIR)/config.mk		# include  CPU	specific rules
##################################################################################################
#包上arch/arm/config.mk和/arch/arm/cpu/arm920t/config.mk文件
##################################################################################################

ifdef	SOC
sinclude $(TOPDIR)/$(CPUDIR)/$(SOC)/config.mk	# include  SoC	specific rules
endif
######################################################################
#包上arch/arm/cpu/arm920t/s3c24x0/config.mk文件
#####################################################################
ifdef	VENDOR
BOARDDIR = $(VENDOR)/$(BOARD)
else
BOARDDIR = $(BOARD)
endif
ifdef	BOARD
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk	# include board specific rules
endif
######################################################################################
#包上board/samsung/smdk2410/config.mk文件
######################################################################################

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

# We don't actually use $(ARFLAGS) anywhere anymore, so catch people
# who are porting old code to latest mainline but not updating $(AR).
ARFLAGS = $(error update your Makefile to use cmd_link_o_target and not AR)
RELFLAGS= $(PLATFORM_RELFLAGS)
DBGFLAGS= -g # -DDEBUG
OPTFLAGS= -Os #-fomit-frame-pointer

OBJCFLAGS += --gap-fill=0xff

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

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

# Enable garbage collection of un-used sections for SPL
ifeq ($(CONFIG_SPL_BUILD),y)
CPPFLAGS += -ffunction-sections -fdata-sections
LDFLAGS_FINAL += --gc-sections
endif

ifneq ($(CONFIG_SYS_TEXT_BASE),)
CPPFLAGS += -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE)
endif

ifneq ($(CONFIG_SPL_TEXT_BASE),)
CPPFLAGS += -DCONFIG_SPL_TEXT_BASE=$(CONFIG_SPL_TEXT_BASE)
endif

ifneq ($(CONFIG_SPL_PAD_TO),)
CPPFLAGS += -DCONFIG_SPL_PAD_TO=$(CONFIG_SPL_PAD_TO)
endif

ifeq ($(CONFIG_SPL_BUILD),y)
CPPFLAGS += -DCONFIG_SPL_BUILD
endif

ifneq ($(RESET_VECTOR_ADDRESS),)
CPPFLAGS += -DRESET_VECTOR_ADDRESS=$(RESET_VECTOR_ADDRESS)
endif

ifneq ($(OBJTREE),$(SRCTREE))
CPPFLAGS += -I$(OBJTREE)/include2 -I$(OBJTREE)/include
endif

CPPFLAGS += -I$(TOPDIR)/include
CPPFLAGS += -fno-builtin -ffreestanding -nostdinc	\
	-isystem $(gccincdir) -pipe $(PLATFORM_CPPFLAGS)

ifdef BUILD_TAG
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes \
	-DBUILD_TAG='"$(BUILD_TAG)"'
else
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
endif

CFLAGS_SSP := $(call cc-option,-fno-stack-protector)
CFLAGS += $(CFLAGS_SSP)
# Some toolchains enable security related warning flags by default,
# but they don't make much sense in the u-boot world, so disable them.
CFLAGS_WARN := $(call cc-option,-Wno-format-nonliteral) \
	       $(call cc-option,-Wno-format-security)
CFLAGS += $(CFLAGS_WARN)

# Report stack usage if supported
CFLAGS_STACK := $(call cc-option,-fstack-usage)
CFLAGS += $(CFLAGS_STACK)

# $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g<format>
# option to the assembler.
AFLAGS_DEBUG :=

# turn jbsr into jsr for m68k
ifeq ($(ARCH),m68k)
ifeq ($(findstring 3.4,$(shell $(CC) --version)),3.4)
AFLAGS_DEBUG := -Wa,-gstabs,-S
endif
endif

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

LDFLAGS += $(PLATFORM_LDFLAGS)
LDFLAGS_FINAL += -Bstatic

LDFLAGS_u-boot += -T $(obj)u-boot.lds $(LDFLAGS_FINAL)
ifneq ($(CONFIG_SYS_TEXT_BASE),)
LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
endif

LDFLAGS_u-boot-spl += -T $(obj)u-boot-spl.lds $(LDFLAGS_FINAL)
ifneq ($(CONFIG_SPL_TEXT_BASE),)
LDFLAGS_u-boot-spl += -Ttext $(CONFIG_SPL_TEXT_BASE)
endif

# Location of a usable BFD library, where we define "usable" as
# "built for ${HOST}, supports ${TARGET}".  Sensible values are
# - When cross-compiling: the root of the cross-environment
# - Linux/ppc (native): /usr
# - NetBSD/ppc (native): you lose ... (must extract these from the
#   binutils build directory, plus the native and U-Boot include
#   files don't like each other)
#
# So far, this is used only by tools/gdb/Makefile.

ifeq ($(HOSTOS),darwin)
BFD_ROOT_DIR =		/usr/local/tools
else
ifeq ($(HOSTARCH),$(ARCH))
# native
BFD_ROOT_DIR =		/usr
else
#BFD_ROOT_DIR =		/LinuxPPC/CDK		# Linux/i386
#BFD_ROOT_DIR =		/usr/pkg/cross		# NetBSD/i386
BFD_ROOT_DIR =		/opt/powerpc
endif
endif

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

export	HOSTCC HOSTCFLAGS HOSTLDFLAGS PEDCFLAGS HOSTSTRIP CROSS_COMPILE \
	AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP MAKE
export	CONFIG_SYS_TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS

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

# Allow boards to use custom optimize flags on a per dir/file basis
BCURDIR = $(subst $(SRCTREE)/,,$(CURDIR:$(obj)%=%))
ALL_AFLAGS = $(AFLAGS) $(AFLAGS_$(BCURDIR)/$(@F)) $(AFLAGS_$(BCURDIR))
ALL_CFLAGS = $(CFLAGS) $(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR))
EXTRA_CPPFLAGS = $(CPPFLAGS_$(BCURDIR)/$(@F)) $(CPPFLAGS_$(BCURDIR))
ALL_CFLAGS += $(EXTRA_CPPFLAGS)

# The _DEP version uses the $< file target (for dependency generation)
# See rules.mk
EXTRA_CPPFLAGS_DEP = $(CPPFLAGS_$(BCURDIR)/$(addsuffix .o,$(basename $<))) \
		$(CPPFLAGS_$(BCURDIR))
$(obj)%.s:	%.S
	$(CPP) $(ALL_AFLAGS) -o $@ $<
$(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 > [email protected] && \
	mv [email protected] $@
        첫 번 째 는 include/autoconf. mk 의존 파일 생 성 입 니 다.
        두 번 째 는 include/config. h 의 파일 내용 에 따라 tools/scripts/define2mk. sed 스 크 립 트 를 이용 하여 모든 CONFIG 를 autoconf. mk 파일 로 추출 합 니 다.
        최종 목 표 는: ALL - y + = $(obj) u - boot. srec $(obj) u - boot. bin $(obj) System. map
        u - boot. srec 도 u - boot 가 object copy 도구 로 만 든 것 으로 어떤 역할 을 하 는 지 모 르 겠 습 니 다.
        u - boot. bin 도 u - boot 에서 object copy 도구 로 만 든 것 으로 최종 적 으로 태 워 쓴 바 이 너 리 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) 를 보십시오.
         도구 디 렉 터 리
c. $(OBJS) 보기:
$(OBJS):
depend
$(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))
$(if $(REMOTE BUILD), $@, $(notdir $@) 를 보십시오.
$(REMOTE BUILD) 가 비어 있 기 때문에 $(notdir $@) 의 값 을 되 돌려 줍 니 다.
$@ 은 규칙 의 목 표를 가리 키 기 때문에 $(OBJS) 이 고 $(OBJS) 는 arch/arm/cpu/arm 920 t/start. o 입 니 다.
notdir 내장 함수 가 되 돌아 오 는 파일 이름;그래서 start. o 로 돌아 갑 니 다.
makec - C arch/arm/cpu/arm 920 t start. o 실행
d.$(LIBBOARD)
$(LIBBOARD):
depend $(LIBS)
$(MAKE) -C $(dir $(subst $(obj),,$@))
make - C 보드/samsung/smdk 2410 실행
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 u - boot. lds 실행 이 디 렉 터 리 에 Makefile 이 없다 는 게 무슨 소리 야?!!
g.$(obj)u-boot.lds
$(obj)u-boot.lds: $(LDSCRIPT)
$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@
       이것들 은 바로 uboot 를 컴 파일 하 는 규칙 으로 분석 이 비교적 거 칠 고 이식 과정 에서 다양한 문제 가 발생 할 것 이 며 이식 과정 에서 더욱 깊이 있 게 수정 할 것 이다.
        

좋은 웹페이지 즐겨찾기