uboot-2012.04.01配置与编译分析(二)

前言:作为一个初学者,只是为了记笔记,如果有什么地方分析的不对,请各位大佬指出来。

这篇文章接着分析uboot-2012.04.01编译的第二步骤make all,主要分析顶层的makefile文件:

第一部分

VERSION = 2012              //主版本号
PATCHLEVEL = 04             //修补版本号
SUBLEVEL = 01               //次版本号
EXTRAVERSION =              ///附加信息,一般默认为空,我们可以自己设置
ifneq "$(SUBLEVEL)" ""
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)   //2012.04.01
else
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL)$(EXTRAVERSION)
endif
TIMESTAMP_FILE = $(obj)include/generated/timestamp_autogenerated.h
VERSION_FILE = $(obj)include/generated/version_autogenerated.h

HOSTARCH := $(shell uname -m | \           //uname -m是读取机器硬件,我们这台机器是64位,读取结果是i686
	sed -e s/i.86/x86/ \                   //sed -e s/123/abc xxx    将字符串xxx中的123替换成abc
	    -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:]' | \       //uname -s读取操作系统,我们这里是Linux
	    sed -e 's/\(cygwin\).*/cygwin/')		//tr ‘[:upper:]’’[:lower:]’表示将结果里面的大写字符全部换成小写字符

SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \    //-x判断文件是否可执行的,这里执行else语句SHELLE:=/bin/bash
	else if [ -x /bin/bash ]; then echo /bin/bash; \
	else echo sh; fi; fi)

export	HOSTARCH HOSTOS SHELL   //导出这三个变量,供其它文件使用
VENDOR=

这一部分主要定义了uboot版本号和HOSTARCH HOSTOS SHELL这三个变量,我的环境下这些变量的值都写在了注释了。

第二部分

这一部分代码规定了该make是非静默编译还是静默编译,这里我们的编译未加任何标志,所以MAKEFLAGS变量为空,If$( findstring string,text )表示从text中寻找string字样,如果找到了则返回text,如果没找到就返回空,这里我们不加-s编译,findstrin返回空,ifeq条件成立,XECHO=echo,所以会打印相关编译信息。加上-s,会执行静默编译。

ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif

第三部分

该部分是分析uboot的编译目录是什么,我们执行make all是默认在当前目录生成编译文件,但是这样会破坏uboot原有的文件,所以编译的时候加上-O参数的话,-O后面跟的目录即为编译输出目录。

ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif

这里介绍一下$(origin variable),origin函数不像其它函数。他并不直接操作变量的值,只是通过返回值来告诉我们这个变量时从哪来的。返回值有以下几个:
(1)返回值为"undefine"时,这个变量没有被定义过;
(2)返回值为“command line”时,这个变量是被命令行定义的;
(3)返回值为“environment”时,这个变量是定义为环境变量;
(4)返回值为“file”时,这个变量是定义在Makefile中;
(5)返回值为“default”时,变量是默认定义的;
(6)返回值为“override”时,被override指示符重新定义
(7)返回值为“automatic”时,是一个命令运行中自动化变量
下面接着分析如果带了-O参数,会进行什么处理:

ifneq ($(BUILD_DIR),)          //如果BUILD_DIR不为空,即加了-O /xxx/xxx 编译参数的话,执行下列部分
saved-output := $(BUILD_DIR)   //saved-output=/xxx/xxx
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}) //判断BUILD_DIR是否是个目录,是的话创建这个目录
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)   //进入创建好的目录,将绝对路径赋值给BUILD_DIR 
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist)) //判断路径是否存在
endif # ifneq ($(BUILD_DIR),)   //因为我这里为使用-O 参数,所以以上部分未执行

OBJTREE		:= $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR)) //CURDIR是当前路径的意思,我们这里BUILD_DIR为空,OBJTREE=$(CURDIR)
SPLTREE		:= $(OBJTREE)/spl                            //SPLTREE=	$(CURDIR)/spl   
SRCTREE		:= $(CURDIR)								//SRCTREE=$(CURDIR)		
TOPDIR		:= $(SRCTREE)                               //TOPDIR=$(CURDIR)	
LNDIR		:= $(OBJTREE)								//LNDIR=$(CURDIR)
export	TOPDIR SRCTREE OBJTREE SPLTREE                  //导出变量供其它文件使用

MKCONFIG	:= $(SRCTREE)/mkconfig                     //MKCONFIG=$(CURDIR)/mkconfig,这个文件就是我们第一篇分析的文件
export MKCONFIG
ifneq ($(OBJTREE),$(SRCTREE))   //我这里的这两个变量都等于当前目录,所以没有进行REMOTE_BUILD=1的标记。
REMOTE_BUILD	:= 1
export REMOTE_BUILD
endif

ifneq ($(OBJTREE),$(SRCTREE))   
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
endif
export obj src             //我这里这两个变量为空

以上部分就是makefile中对编译目录的定义部分,由于我这次编译未采用-O参数来指定编译目录,所以程序里大部分未执行,但是也在注释里都仔细分析了下。

第四部分

这里先定义了三个伪目标

SUBDIR_TOOLS = tools
SUBDIR_EXAMPLES = examples/standalone examples/api
SUBDIRS = $(SUBDIR_TOOLS)

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

接下来是一个判断,判断config.mk是否存在,如果存在,执行下面的内容,不存在,后面再分析。

ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
all:
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk

这里出现了一个目标all,但是没有依赖跟规则,如果继续往下看的话,还会有一个伪目标all
(all: $(ALL-y) $(SUBDIR_EXAMPLES)),这里大概说一下这俩个all的不同作用,首先解释几个概念:

1.当makefile中有两个相同目标的时候,会执行后一个目标。因为后一个目标会重载前一个。
比如:

all:

echo all1

all:

echo all2

执行make 会输出后一个all2

2.空命令

可以存在依赖文件,但是没有命令行。

比如

all:

或者

all: $(obj)

空命令的唯一作用是防止make在执行时,试图为重建这个目标去查找隐含命令,这里可能不是很好理解,之后会继续介绍。

3.makefile的执行规则和include
makefile首先被解析。遇到include。先去解析include的文件(假设为inc.mk),解析完毕以后再回头来解析原makefile。关键点是如果这个inc.mk不存在。make不会退出。而是先提出一个警告,继续处理原makefile的内容。等到原makefile的内容处理完毕以后。会尝试使用规则来重建这个inc.mk文件,也就是尝试将这个inc.mk文件当做一个目标来执行。如果不能重建出这个inc.mk。那么报告一个错误,make退出。如果这个inc.mk重建成功了。那么将原makefile的状态重置,重新开始执行这个makefile。

这里来分析一下我们的uboot:
假如我们第一次执行make xxx_conifig后,再次执行make命令,我们首先遇到的就是:

all:

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

这里我们先假设如果没有第一个all目标(注释掉这一目标行),会怎么运行:
由于两个mk文件都不存在,但根据makefile执行规则这时候并不会退出,而是先执行完整个makefile,再回头来看include的文件。然后回过头将include/autoconf.mk以及 include/autoconf.mk.dep当做一个目标执行。因此才会有Generating include/autoconf.mk
Generating include/autoconf.mk.dep的输出。完毕后重置makefile状态。重新执行makefile。此时autoconf.mk和autoconf.mk.dep都有了。

但这个时候并没有编译uboot, 因为我们执行的命令是make 。后面没有带参数,因此makefile会编译默认遇到的第一个目标。因为我们注释了第一个all:所以直接执行了include。打开autoconf.mk.dep看到第一行就是include/autoconf.mk: include/common.h 。这就是makefile遇到的第一个目标include/autoconf.mk。因此将include/autoconf.mk当做终极目标执行了。此时的include/autoconf.mk是前一次刚产生的,所以是最新的。makefile认为没有必要重新执行。因此什么都不做,最后输出了make: `include/autoconf.mk’ is up to date.这里也就理解了前面的第三条 空命令的唯一作用是防止make在执行时,试图为重建这个目标去查找隐含命令,这个隐含的命令就是执行第一个遇到的目标。

如果有第一个all:的话。makefile就知道需要执行的终极目标是 all。而不是include的autoconf.mk.dep里面的include/autoconf.mk。
继续执行到遇到后面的all: 后面的all将覆盖前面的all。执行这里的操作。所以最终执行的是第二个all
因此第一个all:的含义就是:
如果你 执行make的时候没有带任何其他目标。单独的一个make。可以避免以autoconf.mk.dep里面的include/autoconf.mk作为错误目标。
如果你执行make的时候带了目标。这个all:有不有都无所谓。

第五部分

如果主板代码显式地指定了LDSCRIPT或CONFIG_SYS_LDSCRIPT,则使用它(如果没有,则失败)。否则,在标准位置搜索链接器脚本。

LDSCRIPT_MAKEFILE_DIR = $(dir $(LDSCRIPT))

ifndef LDSCRIPT    //如果没有定义LDSCRIPT
	#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
	ifdef CONFIG_SYS_LDSCRIPT   //如果定义了CONFIG_SYS_LDSCRIPT
		# need to strip off double quotes
		LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
	endif
endif
ifndef LDSCRIPT   //如果没有定义LDSCRIPT,构建自己的lds
	ifeq ($(CONFIG_NAND_U_BOOT),y)      
		LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds  
	//CONFIG_NAND_U_BOOT=y,LDSCRIPT	LDSCRIPT= $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds 
			LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot-nand.lds
	//如果LDSCRIPT为空,即上面的 $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds 不存在,使用$(TOPDIR)/$(CPUDIR)/u-boot-nand.lds
		endif
	endif
	ifeq ($(wildcard $(LDSCRIPT)),)  //如果CONFIG_NAND_U_BOOT不等于y,这个时候LDSCRIPT为空
		LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds //
	endif
	ifeq ($(wildcard $(LDSCRIPT)),)   //如果 $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds不存在
		LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot.lds
	endif
	ifeq ($(wildcard $(LDSCRIPT)),) //如果LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot.lds不存在
		LDSCRIPT := $(TOPDIR)/arch/$(ARCH)/cpu/u-boot.lds
		# We don't expect a Makefile here
		LDSCRIPT_MAKEFILE_DIR =
	endif
	ifeq ($(wildcard $(LDSCRIPT)),)  //如果$(TOPDIR)/arch/$(ARCH)/cpu/u-boot.lds也不存在报错,找不到链接脚本
$(error could not find linker script)
	endif
endif

这一部分主要就是说如果没有定义自己特殊的连接脚本,就使用默认的连接脚本,使用哪一个根据配置来。这里我也不知道使用哪一个,但是可以通过make时的输出信息来找一下,我这里找到应该是/u-boot-2012.04.01/arch/arm/cpu/u-boot.lds,即LDSCRIPT := ( T O P D I R ) / a r c h / (TOPDIR)/arch/ (TOPDIR)/arch/(ARCH)/cpu/u-boot.lds。
这里makefile中链接脚本的使用分析完了,我们接着分析。

第六部分

这一部分是定义OBJS与LIBS,根据之前导出的五个变量ARCH CPU BOARD VENDOR SOC来自动加载LIBS与OBJS,这里就不详细解释这一部分代码了。

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

LIBS  = lib/libgeneric.o
LIBS += lib/lzma/liblzma.o
LIBS += lib/lzo/liblzo.o
LIBS += lib/zlib/libz.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
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)))
.PHONY : $(LIBS)

LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))

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

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

第七部分

接下来我们分析all目标:

all:		$(ALL-y) $(SUBDIR_EXAMPLES)
ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map

我们这里重点分析u-boot.bin的生成:

$(obj)u-boot.bin:	$(obj)u-boot  //这个u-boot是elf格式的文件
		$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
		$(BOARD_SIZE_CHECK)
$(obj)u-boot:	depend \
		$(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
		$(GEN_UBOOT)
ifeq ($(CONFIG_KALLSYMS),y)
		smap=`$(call SYSTEM_MAP,u-boot) | \
			awk '$$2 ~ /[tTwW]/ {printf $$1 $$3 "\\\\000"}'` ; \
		$(CC) $(CFLAGS) -DSYSTEM_MAP="\"$${smap}\"" \
			-c common/system_map.c -o $(obj)common/system_map.o
		$(GEN_UBOOT) $(obj)common/system_map.o
endif

第一个依赖: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

CPUDIR=arch/ ( A R C H ) / c p u / (ARCH)/cpu/ (ARCH)/cpu/(CPU)
因此,depend会去这些目录(也就是目录tools [examples/standalone、examples/api] arch/arm/cpu/armv7/)执行_depend目标。

第二个依赖$(SUBDIR_TOOLS)

因为之前定义过:

SUBDIR_TOOLS=tools
SUBDIRS = $(SUBDIR_TOOLS)
$(SUBDIRS):	depend
		$(MAKE) -C $@ all

所以该部分就是去tools目录执行目标all

第三个依赖OBJS

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

其实就是构建arch/arm/cpu/armv7/start.o

第四个依赖LIBBOARD

$(LIBBOARD):	depend $(LIBS)
		$(MAKE) -C $(dir $(subst $(obj),,$@)

这个目标的依赖文件有LIBS,所以说其实是LIBS这个目标,即第五个目标先被执行,
上面有定义过

LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o   
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))

之前在跟目录下的MKconigi文件中,有过如下定义:

if [ -z "${vendor}" ] ; then
    BOARDDIR=${board}
else
    BOARDDIR=${vendor}/${board}
fi

所以我们这里BOARDDIR=samsung/smdk2410,所以这里就是构建board/samsung/smdk2410中的makefile。

第五个依赖LIBS

$(LIBS):    depend $(SUBDIR_TOOLS)                                              
        $(MAKE) -C $(dir $(subst $(obj),,$@)) 

大部分文件的编译都在这一步了。这些就是上面添加的LIBS相关的库。

第六个依赖LDSCRIPT

$(LDSCRIPT):    depend                                                          
        $(MAKE) -C $(dir $@) $(notdir $@)

这个目标就是我们上面定义的LDSCRIPT,但是这个目录下没有makefile

第七个依赖u-boot.lds

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

这部分执行对应的是输出信息里的:

arm-linux-gcc -E -g  -Os   -fno-common -ffixed-r8 -msoft-float  -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0x0 -I/home/zhangjun/u-boot-2012.04.01/include -fno-builtin -ffreestanding -nostdinc -isystem /usr/local/arm/arm-linux-gcc-4.4.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.3/include -pipe  -DCONFIG_ARM -D__ARM__ -marm -mabi=aapcs-linux -mno-thumb-interwork -march=armv4 -include /home/zhangjun/u-boot-2012.04.01/include/u-boot/u-boot.lds.h -DCPUDIR=arch/arm/cpu/arm920t  -ansi -D__ASSEMBLY__ -P - </home/zhangjun/u-boot-2012.04.01/arch/arm/cpu/u-boot.lds >u-boot.lds

到这里我们依赖部分就分析完了,接下来我们继续分析命令部分:
$(GEN_UBOOT)

ifeq ($(CONFIG_SANDBOX),y)                                                      
GEN_UBOOT = \                                                                   
        cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \                      
            -Wl,--start-group $(__LIBS) -Wl,--end-group \                       
            $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map -o u-boot                  
else                                                                            
GEN_UBOOT = \                                                                   
        cd $(LNDIR) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \                      
            $(__OBJS) \                                                         
            --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \              
            -Map u-boot.map -o u-boot                                           
endif 

这里对应的是输出的这部分:

 cd /home/zhangjun/u-boot-2012.04.01 && arm-linux-ld  -pie -T u-boot.lds -Bstatic -Ttext 0x0 $UNDEF_SYM arch/arm/cpu/arm920t/start.o --start-group api/libapi.o arch/arm/cpu/arm920t/libarm920t.o arch/arm/cpu/arm920t/s3c24x0/libs3c24x0.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/eth/libusb_eth.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/usb/ulpi/libusb_ulpi.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 lib/zlib/libz.o net/libnet.o post/libpost.o board/samsung/smdk2410/libsmdk2410.o --end-group /home/zhangjun/u-boot-2012.04.01/arch/arm/lib/eabi_compat.o  -L /usr/local/arm/arm-linux-gcc-4.4.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.3 -lgcc -Map u-boot.map -o u-boot

到这里uboot的elf文件就构建完成了,下面就是生成.bin文件。

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

至此编译的分析就完成了。

你可能感兴趣的:(uboot)