在执行make 100ask24x0_config之后就配置完成了针对JZ2440开发板的UBOOT,接下来需要执行make all进行编译链接最终生成u-boot.map、u-boot.srec、u-boot.bin文件,下面主要针对这一过程进行分析:

1、u-boot.map、u-boot.srec、u-boot.bin、u-boot四个文件的作用

2、从Make all逐步深入分析

3、分析子Makefile过程

1、u-boot.map、u-boot.srec、u-boot.bin、u-boot四个文件是编译链接后生成的,它们的作用如下:

a、u-boot.map:

1)、map文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法,是整个程序工程信息的静态文本,通常由linker生成。

2)、map文件保存整个工程的静态文本信息,里面有所有函数的入口地址。

3)、通过查看map文件,我们可以找到代码段(.text),全局未初始化区(.bss),数据段(.data),未初始化段(.bss),还有些不懂的.debug_line、.comment、.got等段

4)、map文件的作用是,我们可以根据程序产生错误地址在map文件中找到相应的函数、变量地址。

b、u-boot.srec:Motorola S-Record格式的可执行文件

c、u-boot:elf格式的可执行文件,里面包含了调试信息

d、u-boot.bin:二进制格式的可执行文件,它就是可以直接烧入ROM、NOR Flash的文件

2、从Make all逐步深入分析Makefile

变量:这些变量在很多Make规则中调用

OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))执行了这条之后则认为BUILD_DIR=CURDIR=/work/system/u-boot-1.1.6
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)

OBJTREE = /work/system/u-boot-1.1.6
SRCTREE = /work/system/u-boot-1.1.6
TOPDIR = /work/system/u-boot-1.1.6
LNDIR = /work/system/u-boot-1.1.6
obj :=
src :=

调用文件:调用文件中的很多内容被Make规则调用(下面文件包括了用什么编译器编译、链接的地址等等需要的内容)

include /work/system/u-boot-1.1.6/config.mk
include /work/system/u-boot-1.1.6/include/config.mk
sinclude /work/system/u-boot-1.1.6/arm_config.mk
sinclude /work/system/u-boot-1.1.6/cpu/arm920t/config.mk
sinclude /work/system/u-boot-1.1.6/board/100ask24x0/config.mk

跟随make all一步步往下看,all依赖于ALL,ALL则依赖于u-boot.srec 、u-boot.bin 、System.map、 $(U_BOOT_NAND)

ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)

all:            $(ALL)

下面是生成u-boot.srec的规则

$(obj)u-boot.srec:      $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@

u-boot.srec依赖于u-boot,下面是生产u-boot的规则。

$(obj)u-boot:           depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot

先分析第一行,等价于u-boot: depend version $(SUBDIRS) cpu/arm920t/start.o $(LIBS) $(LDSCRIPT)

LIBS的值,为所有子目录下的.a文件即子目录下编译后产生的所以.o文件的集合

LIBS  = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
ifdef SOC
LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
endif
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
LIBS += net/libnet.a
LIBS += disk/libdisk.a
LIBS += rtc/librtc.a
LIBS += dtt/libdtt.a
LIBS += drivers/libdrivers.a
LIBS += drivers/nand/libnand.a
LIBS += drivers/nand_legacy/libnand_legacy.a
LIBS += drivers/usb/libusb.a
LIBS += drivers/sk98lin/libsk98lin.a
LIBS += common/libcommon.a
LIBS += $(BOARDLIBS)

LDSCRIPT的值LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds等价于/work/system/u-boot-1.1.6/board/100ask24x0/u-boot.lds  (定义在/work/system/u-boot-1.1.6/config.mk中)

依赖depend不存在,version表示把版本号等等信息存放在VERSION_FILE文件中,依赖规则为:

version:
echo -n "#define U_BOOT_VERSION \"U-Boot " > $(VERSION_FILE); \
echo -n "$(U_BOOT_VERSION)" >> $(VERSION_FILE); \
echo -n $(shell $(CONFIG_SHELL) $(TOPDIR)/tools/setlocalversion \
$(TOPDIR)) >> $(VERSION_FILE); \
echo "\"" >> $(VERSION_FILE)

$(SUBDIRS)规则为,等价于cd SUBDIRS && make。解释为进入相应的子目录然后make。(对应子目录的make后面再介绍,这里只需知道有这么一个依赖即可,tool是编译的第一个目录)。

$(SUBDIRS):
$(MAKE) -C $@ all

接着往下看,将以下所有变量都翻译出来得到翻译后的语句。

UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
UNDEF_SYM=`arm-linux-objdump -x lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a
lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a
fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a
drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a
drivers/sk98lin/libsk98lin.a common/libcommon.a |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd /work/system/u-boot-1.1. && arm-linux-ld -Bstatic -T /work/system/u-boot-1.1./board/100ask24x0/u-boot.lds -Ttext 0x33F80000
$UNDEF_SYM cpu/arm920t/start.o --start-group lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a
cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a
fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a
disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a
drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a
common/libcommon.a --end-group -L /work/tools/gcc-3.4.-glibc-2.3./lib/gcc/arm-linux/3.4. -lgcc \
                                                      -Map u-boot.map -o u-boot

大致意思是把所以.a文件、.o文件以及静态库文件链接在0x33F80000开头的地方最终生成u-boot.map文件以及u-boot文件。具体链接规则参见work/system/u-boot-1.1.6/board/100ask24x0/u-boot.lds。详细分析参考https://blog.csdn.net/gongyuan073/article/details/13168239

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")//小端模式
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm) //arm架构
ENTRY(_start) //入口地址为_start
SECTIONS
{
. = 0x00000000; //当前地址为0x00000000+0x33f80000。装载地址与链接地址一样 . = ALIGN();
.text :
{
cpu/arm920t/start.o (.text) //第一个位置存放start.o的代码段
board/100ask24x0/boot_init.o (.text) //第二个位置存放boot_init.o的代码段
*(.text) //剩下的代码段
} . = ALIGN(); //四字节对齐
.rodata : { *(.rodata) } //只读数据段 . = ALIGN(); //四字节对齐
.data : { *(.data) } //数据段 . = ALIGN(); //四字节对齐
.got : { *(.got) } //got段 . = .;
__u_boot_cmd_start = .; //__u_boot_cmd_start=当前地址
.u_boot_cmd : { *(.u_boot_cmd) } //u_boot_cmd段
__u_boot_cmd_end = .; //__u_boot_cmd_end=当前地址 . = ALIGN(); //四字节对齐
__bss_start = .; //__bss_start=当前地址
.bss : { *(.bss) } //bss段未初始化段
_end = .; //_end=当前地址
}

最后再根据u-boot文件生成u-boot.srec文件与u-boot.bin文件

arm-linux-objcopy --gap-fill=0xff -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin

3、分析子Makefile过程

在分析make all过程当中提到了子Makefile这一概念。$(MAKE) -C $@ all等价于cd SUBDIRS && make。这几个子Makefile内容有点多,为了简单明了的理解子Makefile,下面以/work/system/u-boot-1.1.6/board/100ask24x0/Makefile文件做说明。

这里make以后需要被执行的目标文件是$(LIB): $(obj).depend $(OBJS) $(SOBJS)。

CROSS_COMPILE = arm-linux-(在work/system/u-boot-1.1.6/config.mk中定义)

AR = $(CROSS_COMPILE)ar(在work/system/u-boot-1.1.6/include/config.mk中定义)

ARFLAGS = crv(在work/system/u-boot-1.1.6/config.mk中定义)

.depend的内容为.c或者.s文件生成的.o文件,查看得到里面的内容为:

lowlevel_init.o: lowlevel_init.S \
/work/System2/u-boot-1.1.6/include/config.h \
/work/System2/u-boot-1.1.6/include/configs/100ask24x0.h \
/work/System2/u-boot-1.1.6/include/cmd_confdefs.h \
/work/System2/u-boot-1.1.6/include/version.h \
/work/System2/u-boot-1.1.6/include/version_autogenerated.h
100ask24x0.o: 100ask24x0.c /work/System2/u-boot-1.1.6/include/common.h \
/work/System2/u-boot-1.1.6/include/config.h \
/work/System2/u-boot-1.1.6/include/configs/100ask24x0.h \
/work/System2/u-boot-1.1.6/include/cmd_confdefs.h \
/work/System2/u-boot-1.1.6/include/linux/bitops.h \
/work/System2/u-boot-1.1.6/include/asm/bitops.h \
/work/System2/u-boot-1.1.6/include/linux/types.h \
/work/System2/u-boot-1.1.6/include/linux/config.h \
/work/System2/u-boot-1.1.6/include/linux/posix_types.h \
/work/System2/u-boot-1.1.6/include/linux/stddef.h \
/work/System2/u-boot-1.1.6/include/asm/posix_types.h \
/work/System2/u-boot-1.1.6/include/asm/types.h \
/work/System2/u-boot-1.1.6/include/linux/string.h \
/work/System2/u-boot-1.1.6/include/asm/string.h \
/work/System2/u-boot-1.1.6/include/asm/ptrace.h \
/work/System2/u-boot-1.1.6/include/asm/proc/ptrace.h \
/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/include/stdarg.h \
/work/System2/u-boot-1.1.6/include/part.h \
/work/System2/u-boot-1.1.6/include/ide.h \
/work/System2/u-boot-1.1.6/include/flash.h \
/work/System2/u-boot-1.1.6/include/image.h \
/work/System2/u-boot-1.1.6/include/asm/u-boot.h \
/work/System2/u-boot-1.1.6/include/asm/global_data.h \
/work/System2/u-boot-1.1.6/include/asm/mach-types.h \
/work/System2/u-boot-1.1.6/include/asm/setup.h \
/work/System2/u-boot-1.1.6/include/asm/u-boot-arm.h \
/work/System2/u-boot-1.1.6/include/s3c2410.h \
/work/System2/u-boot-1.1.6/include/s3c24x0.h
boot_init.o: boot_init.c /work/System2/u-boot-1.1.6/include/common.h \
/work/System2/u-boot-1.1.6/include/config.h \

具体生成它的规则在/work/system/u-boot-1.1.6/rules.mk,这是一个通用规则,每一个子目录丢调用这个规则生成.o文件,具体分析参见https://blog.csdn.net/mars1743/article/details/24180349,具体为:

_depend:    $(obj).depend

$(obj).depend:    $(src)Makefile $(TOPDIR)/config.mk $(SRCS)//依赖为当前目录下的Makefile、顶层的config.mk以及SRCS
@rm -f $@
@for f in $(SRCS); do \
g=`basename $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; \
$(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@ ; \ //
done
include $(TOPDIR)/config.mk               //等价于调用/work/system/u-boot-1.1.6/config.mk  

LIB = $(obj)lib$(BOARD).a                 //等价于LIB = lib100ask24x0.a,BOARD在/work/system/u-boot-1.1.6/include/config.mk里定义

COBJS := 100ask24x0.o boot_init.o
SOBJS := lowlevel_init.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS)) $(LIB): $(obj).depend $(OBJS) $(SOBJS) //等价于 lib100ask24x0.a:.depend 100ask24x0.o boot_init.o lowlevel_init.o
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) //等价于 arm-linux-ar crv lib100ask24x0.a 100ask24x0.o boot_init.o lowlevel_init.o
clean:
rm -f $(SOBJS) $(OBJS) //删除生成的.o文件 distclean: clean
rm -f $(LIB) core *.bak .depend //删除生成的.a文件、.bak文件、.depend文件以及core ######################################################################### # defines $(obj).depend target
include $(SRCTREE)/rules.mk //通用规则调用,生成.o文件 sinclude $(obj).depend //当前目录下的.depend
#########################################################################

u-boot之make all执行过程分析的更多相关文章

  1. ASP.NET MVC应用程序执行过程分析

    ASP.NET MVC应用程序执行过程分析 2009-08-14 17:57 朱先忠 朱先忠的博客 字号:T | T   ASP.NET MVC框架提供了支持Visual Studio的工程模板.本文 ...

  2. Ansible系列(七):执行过程分析、异步模式和速度优化

    本文目录:1.1 ansible执行过程分析1.2 ansible并发和异步1.3 ansible的-t选项妙用1.4 优化ansible速度 1.4.1 设置ansible开启ssh长连接 1.4. ...

  3. MFC的执行过程分析

    MFC程序的执行细节剖析 MFC程序也是Windows程序,所以它应该也有一个WinMain.可是在程序中看不到它的踪影.事实上在程序进入点之前.另一个(并且仅有一个)全局对象(theApp).这就是 ...

  4. u-boot、kernel和filesystem 执行过程分析

    标题: Uboot -kerne-root 启动流程 内容: ※uboot启动流程 ※Kernel启动流程 ※Root启动流程 ※构建根文件系统 /************************** ...

  5. spring boot mybatis 打成可执行jar包后启动UnsatisfiedDependencyException异常

    我的spring boot + mybatis项目在idea里面执行正常,但发布测试环境打成可执行jar包后就启动失败,提示错误如下: [ ERROR] [2018-08-30 17:23:48] o ...

  6. Spring Boot Maven 打包可执行Jar文件!

    Maven pom.xml 必须包含 <packaging>jar</packaging> <build> <plugins> <plugin&g ...

  7. Spring Boot Gradle 打包可执行Jar文件!

    使用Gradle构建项目,继承了Ant的灵活和Maven的生命周期管理,不再使用XML作为配置文件格式,采用了DSL格式,使得脚本更加简洁. 构建环境: jdk1.6以上,此处使用1.8 Gradle ...

  8. 将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class、缺少 xsd、重复打包依赖)

    最近在看 spring boot 的东西,觉得很方便,很好用.对于一个简单的REST服务,都不要自己部署Tomcat了,直接在 IDE 里 run 一个包含 main 函数的主类就可以了. 但是,转念 ...

  9. Spring boot 项目导出可执行jar

    配置文件中添加插件 <plugin> <groupId>org.springframework.boot</groupId> <artifactId>s ...

  10. CDH集群spark-shell执行过程分析

    目的 刚入门spark,安装的是CDH的版本,版本号spark-core_2.11-2.4.0-cdh6.2.1,部署了cdh客户端(非集群节点),本文主要以spark-shell为例子,对在cdh客 ...

随机推荐

  1. Android源码50例汇总,欢迎各位下载(转载)

    下载中心好资料很多,藏在各个角落,小弟在此帮大家做了一个整理,做了一个下载目录,方便大家选择性下载. 源码实例如下: <Android应用开发揭秘>源代码推荐 http://down.51 ...

  2. Oracle Oracle数据库 迁移到 SQL Server上

    原地址:https://blog.csdn.net/LongtengGensSupreme/article/details/81355181

  3. lcd 显示屏

    1.lcd 接口信号: VSYNC : 一帧新数据的开始信号 HSYNC :一行新数据的开始信号 VCLK   :像素的同步信号 VD[0:23]  :传递数据的信号线 2. LCD  的显示原理 ( ...

  4. pandas 读取大文件 read_table C-engine CParserError: Error tokenizing data

    解决办法: pd_data = pd.read_table(comment_file,header=None,encoding='utf-8', engine='python') 官网解析: engi ...

  5. Spark Streaming之五:Window窗体相关操作

    SparkStreaming之window滑动窗口应用,Spark Streaming提供了滑动窗口操作的支持,从而让我们可以对一个滑动窗口内的数据执行计算操作.每次掉落在窗口内的RDD的数据,会被聚 ...

  6. tomcat部署war包

    部署步骤 1.下载tomcat 直接在网上下载即可,随便把包下到一个地方 下面文中的xxx均代表tomcat的安装目录   2.将java工程导出war包 在intellij idea的执行左侧选中t ...

  7. 安装 pygame,找不到Python version 2.7

    今天在安装pygame时出错,提示“Python version 2.7 required, which was not found in the registry”,经过网上查找资料后发现只需要新建 ...

  8. spark streaming集成kafka接收数据的方式

    spark streaming是以batch的方式来消费,strom是准实时一条一条的消费.当然也可以使用trident和tick的方式来实现batch消费(官方叫做mini batch).效率嘛,有 ...

  9. ELK Deployed

    Enviroment prepare rpm -qa | grep java wget http://download.oracle.com/otn-pub/java/jdk/8u171-b11/51 ...

  10. 51nod 1163 最高的奖励

    链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1163 1163 最高的奖励  基准时间限制:1 秒 空间限制:13 ...