解压u-boot-2010.03.tar.bz2就可以得到全部U-Boot源程序。在顶层目录下有29个子目录,分别存放和管理不同的源程序。这些目录中所要存放的文件有其规则,可以分为3类。

● 与处理器体系结构或者开发板硬件直接相关。
    ● 一些通用的函数或者驱动程序。
    ● U-Boot的应用程序、工具或者文件。

表1.5列出了U-Boot顶层目录下各级目录的存放原则。

表1.5 U-Boot的源码顶层目录说明

目 录 特 性 解 释 说 明
board 平台依赖 存放电路板相关的目录文件,如RPXlite(mpc8xx)、smdk2410(arm920t)、sc520_cdp(x86) 等目录
cpu 平台依赖 存放了CPU相关的目录文件,如mpc8xx、ppc4xx、arm720t、arm920t、xscale、i386等目录
lib_ppc 平台依赖 存放对PowerPC体系结构通用的文件,主要用于实现PowerPC平台通用的函数
lib_arm 平台依赖 存放对ARM体系结构通用的文件,主要用于实现ARM平台通用的函数
lib_i386 平台依赖 存放对X86体系结构通用的文件,主要用于实现X86平台通用的函数
lib_avr32 平台依赖 存放对AVR32体系结构通用的文件,主要用于实现AVR32平台通用的函数
lib_blackfin 平台依赖 存放对BLACKFIN体系结构通用的文件,主要用于实现BLACKFIN平台通用的函数
lib_m68k 平台依赖 存放对M68K体系结构通用的文件,主要用于实现M68K 平台通用的函数
lib_microblaze 平台依赖 存放对Microblaze体系结构通用的文件,主要用于实现Microblaze平台通用的函数
lib_mips 平台依赖 存放对MIPS体系结构通用的文件,主要用于实现MIPS平台通用的函数
lib_nios 平台依赖 存放对NIOS体系结构通用的文件,主要用于实现NIOS平台通用的函数
lib_nios2 平台依赖 存放对NIOS体系结构通用的文件,主要用于实现NIOS2平台通用的函数
lib_sh 平台依赖 存放对SH体系结构通用的文件,主要用于实现SH平台通用的函数
lib_sparc 平台依赖 存放对SPARC体系结构通用的文件,主要用于实现SPARC平台通用的函数
libfdt 通用 支持设备树的库文件
api 通用 存放U-Boot提供的接口函数
common 通用 通用的代码,涵盖各个方面,以命令行处理为主
disk 通用 磁盘分区相关代码
nand_spl 通用 NAND存储器相关代码
include 通用 头文件和开发板配置文件,所有开发板的配置文件都在configs目录下
common 通用 通用的多功能函数实现
lib_generic 通用 通用库函数的实现
net 通用 存放网络相关程序
fs 通用 存放文件系统相关程序
post 通用 存放上电自检程序
drivers 通用 通用的设备驱动程序,主要有以太网接口的驱动
disk 通用 硬盘接口程序
examples 应用例程 一些独立运行的应用程序的例子,如helloworld
tools 工具 存放制作S-Record或者U-Boot格式的镜像等工具,如mkimage
doc 文档 开发使用文档
Rtc 通用 RTC的驱动程序

U-Boot的源代码包含对几十种处理器、数百种开发板的支持。可是对于特定的开发板,配置编译过程只需其中部分程序。这里以S3C2410处理器为例,具体分析S3C2410处理器和开发板所依赖的程序,以及U-Boot的通用函数和工具。

U-Boot的源码是通过gcc和Makefile组织编译的。顶层目录下的Makefile可以设置开发板的定义,然后递归地调用各级子目录下的Makefile,最后把编译过的程序链接成U-Boot映像。

1)顶层目录下的Makefile

Makefile负责U-Boot整体配置编译,按照配置的顺序阅读其中关键的几行。

每一种开发板在Makefile下都需要有主板配置的定义。例如,smdk2410开发板的定义如下:

smdk2410_config : unconfig
        @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0

执行配置U-Boot的命令make smdk2410_config,通过mkconfig脚本生成include/config.mk的配置文件,文件内容正是根据Makefile对开发板的配置生成的。

ARCH = arm
    CPU = arm920t
    BOARD = smdk2410
    VENDOR = samsung
    SoC = s3c24x0

上面的include/config.mk文件定义了ARCH、CPU、BOARD、VENDOR、SoC这些变量,这样,硬件平台依赖的目录文件可以根据这些定义来确定。SMDK2410平台相关目录如下:

board/Samsung/smdk2410
    cpu/arm920t/
    cpu/arm920t/s3c24x0/
    lib_arm/
    include/configs/smdk2410.h

再回到顶层目录的Makefile文件开始的部分,其中,下列几行包含了这些变量的定义:

# load ARCH, BOARD, and CPU configuration
    include $(obj)include/config.mk
    export ARCH CPU BOARD VENDOR SOC

Makefile的编译选项和规则在顶层目录的config.mk文件中定义,各种体系结构通用的规则直接在这个文件中定义。通过
ARCH、CPU、BOARD、VENDOR、SoC等变量为不同硬件平台定义不同选项。不同体系结构的规则分别包含在ppc_config.mk、
arm_config.mk、mips_config.mk等文件中。

顶层目录的Makefile中还要定义交叉编译器,以及编译U-Boot所依赖的目标文件
    ifeq (arm,$(ARCH))
        CROSS_COMPILE ?=arm-none-linux-gnueabi-
    # 交叉编译器的前缀
    endif
    # load other configuration
    include $(TOPDIR)/config.mk
    # U-Boot objects....order is important (i.e. start must be first)
    OBJS = cpu/$(CPU)/start.o # 处理器相关的目标文件
    …
    #定义依赖的目录,每个目录下先把目标文件连接成*.a文件
    LIBS = lib_generic/libgeneric.a
    LIBS += lib_generic/lzma/liblzma.a
    LIBS += lib_generic/lzo/liblzo.a
    LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ];
    Then echo "board/$(VENDOR)/common/lib$(VENDOR).a"; fi)
    LIBS += cpu/$(CPU)/lib$(CPU).a
    ifdef SOC
    LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
    endif
    ifeq ($(CPU),ixp)
    LIBS += cpu/ixp/npe/libnpe.a
    endif
    LIBS += lib_$(ARCH)/lib$(ARCH).a
    …

还有U-Boot镜像编译的依赖关系如下:

ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
    $(U_BOOT_ONENAND)
    all: $(ALL)
    $(obj)u-boot.hex: $(obj)u-boot
            $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
    $(obj)u-boot.srec: $(obj)u-boot
            $(OBJCOPY) -O srec $< $@
    $(obj)u-boot.bin: $(obj)u-boot
      $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
    $(obj)u-boot.ldr: $(obj)u-boot
            $(CREATE_LDR_ENV)
            $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
    $(obj)u-boot.ldr.hex: $(obj)u-boot.ldr
            $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary
    $(obj)u-boot.ldr.srec: $(obj)u-boot.ldr
            $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary
    $(obj)u-boot.img: $(obj)u-boot.bin
            ./tools/mkimage -A $(ARCH) -T firmware -C none \
            -a $(TEXT_BASE) -e 0 \
            -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
                sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \-d $< $@
    $(obj)u-boot.imx: $(obj)u-boot.bin
            $(obj)tools/mkimage -n $(IMX_CONFIG) -T imximage \
            -e $(TEXT_BASE) -d $< $@
    $(obj)u-boot.kwb: $(obj)u-boot.bin
            $(obj)tools/mkimage -n $(KWD_CONFIG) -T kwbimage \
            -a $(TEXT_BASE) -e $(TEXT_BASE) -d $< $@
    $(obj)u-boot.sha1: $(obj)u-boot.bin
            $(obj)tools/ubsha1 $(obj)u-boot.bin
    $(obj)u-boot.dis: $(obj)u-boot
            $(OBJDUMP) -d $< > $@

Makefile默认的编译目标为all,包括u-boot.srec、u-boot.bin和System.map。u-
boot.srec和u-boot.bin就是通过ld命令按照U-Boot.map地址表把目标文件组装成U-Boot的。其他Makefile内容就
不再详细分析了,通过上述代码分析应该可以为读者阅读代码提供一些线索。

2)开发板配置头文件

除了编译过程Makefile以外,还要在程序中为开发板定义配置选项或者参数。这个头文件是include/configs/<board_name>.h。<board_name>用相应的BOARD定义代替。

这个头文件中主要定义了两类形式的参数。

一类形式的参数用来选择处理器、设备接口、命令、属性等,以及定义总线频率、串口波特率、Flash地址等参数。

大部分参数前缀是CONFIG_,例如:

#define CONFIG_ARM920T 1
    #define CONFIG_KGDB_BAUDRATE 115200
    #define CONFIG_CS8900
    #define CONFIG_KGDB_BAUDRATE 115200

另一类形式的参数为:

#define PHYS_FLASH_SIZE 0x00100000
    #define USE_920T_MMU 1

根据对Makefile的分析,编译分为两步。第1步是配置,如make smdk2410_config;第2步是编译,执行make就可以了。

编译完成后,可以得到U-Boot各种格式的映像文件和符号表,如表1.6所示。

表1.6 U-Boot编译生成的映像文件

文 件 名 称 说 明 文 件 名 称 说 明
System.map U-Boot映像的符号表 u-boot.bin U-Boot映像原始的二进制格式
u-boot U-Boot映像的ELF格式 u-boot.srec U-Boot映像的S-Record格式

U-Boot的3种映像格式都可以烧写到Flash中,但需要看加载器能否识别这些格式。一般u-boot.bin最为常用,直接按照二进制格式下载,并且按照绝对地址烧写到Flash中就可以了。U-Boot和u-boot.srec格式映像都自带定位信息。

本文选自华清远见嵌入式培训教材《从实践中学嵌入式Linux应用程序开发》

    原文地址:http://www.farsight.com.cn/news/emb158.htm

更多相关嵌入式教程查看华清远见电子书频道>>

U-Boot编译过程解析的更多相关文章

  1. [译]C++, Java和C#的编译过程解析

    1.1.1 摘要 我们知道计算机不能直接理解高级语言,它只能理解机器语言,所以我们必须要把高级语言翻译成机器语言,这样计算机才能执行高级语言编写的程序,在接下来的博文中,我们将介绍非托管和托管语音的编 ...

  2. C/C++, Java和C#的编译过程解析

    原文地址:http://www.cnblogs.com/rush/p/3155665.html 1.1.1 摘要 我们知道计算机不能直接理解高级语言,它只能理解机器语言,所以我们必须要把高级语言翻译成 ...

  3. Spring boot 启动过程解析 logback

    使用 Spring Boot 默认的日志框架 Logback. 所有这些 POM 依赖的好处在于为开发 Spring 应用提供了一个良好的基础.Spring Boot 所选择的第三方库是经过考虑的,是 ...

  4. C++, Java和C#的编译、链接过程解析

    总是感觉java是解释性语言,转载下一篇感觉写的容易理解的文章 转自 http://www.cnblogs.com/rush/p/3155665.html 1.1.1 摘要 我们知道计算机不能直接理解 ...

  5. colmap编译过程中出现,无法解析的外部符号错误 “__cdecl google::base::CheckOpMessageBuilder::ForVar1(void)”

    错误提示: >colmap.lib(matching.obj) : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: cl ...

  6. 【转】编译quickfast解析库(沪深level2行情转码库)

     转自http://blog.csdn.net/hacode/article/details/7065889 编译quickfast解析库(沪深level2行情转码库) 目录(?)[-] 1 下载源代 ...

  7. 7、XAML的编译过程

    对于动态皮肤场景来说,在运行时加载和解析XAML是有意义的,对于那些没有支持XAML编译的.NET语言也是有意义的.但大多数WPF项目会通过MSBuild和Visual Studio完成XAML编译. ...

  8. 英蓓特Mars board的android4.0.3源码编译过程

    英蓓特Mars board的android4.0.3源码编译过程 作者:StephenZhu(大桥++) 2013年8月22日 若要转载,请注明出处 一.编译环境搭建及要点: 1. 虚拟机软件virt ...

  9. Android编译过程详解(三)

    前面两节讲解了自定义Android编译项和创建Product产品配置文件,除了编译和定义产品相关环境变量外,还需要定义Board相关环境变量. 1. build/core/config.mk 109 ...

随机推荐

  1. C++中的虚函数(表)实现机制以及用C语言对其进行的模拟实现

    tfref 前言 C++对象的内存布局 只有数据成员的对象 没有虚函数的对象 拥有仅一个虚函数的对象 拥有多个虚函数的对象 单继承且本身不存在虚函数的继承类的内存布局 本身不存在虚函数(不严谨)但存在 ...

  2. 【网络资料】Astar算法详解

    关于A*算法,很早就想写点什么,可是貌似天天在忙活着什么,可事实又没有做什么,真是浮躁啊!所以今晚还是来写一下总结吧! A*算法是很经典的只能启发式搜索算法,关于只能搜索算法和一般的搜索算法(例如DF ...

  3. HDU1502 Regular Words

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1502 思路:当只有两个数时,可以用卡特兰数做,当三个数时,没想到卡特兰数的做法.可以使用动态规划. 状态转 ...

  4. go sample-base64

    GoSample-base64 package mainimport ( "encoding/base64" "fmt")func base64Encode(s ...

  5. 中断处理流程,ok6410

    中断处理流程 CPU在工作的过程中,经常需要与外设进行交互,交互的方式包括”轮询方式”,”中断方式”. 1.轮询方式: CPU不断地查询设备的状态.该方式实现比较简单,但CPU利用率很低,不适合多任务 ...

  6. 在64位Win7中使用Navicat Premium 和PL\SQL Developer连接Oracle数据库备忘

    最近接手了一个项目,服务器端数据库是oracle 11g 64位.由于主要工作不是开发,也不想在自己的电脑上安装庞大的oracle数据库,因此寻思着只通过数据库管理工具连接数据库进行一些常用的查询操作 ...

  7. python web编程-CGI帮助web服务器处理客户端编程

    这几篇博客均来自python核心编程 如果你有任何疑问,欢迎联系我或者仔细查看这本书的地20章 另外推荐下这本书,希望对学习python的同学有所帮助 概念预热 eb客户端通过url请求web服务器里 ...

  8. json方式的面向对象

    json方式只适合于一个对象. var p1 = { name:"香菇", sex :"女", dreamdu: { URL: "www.dreamd ...

  9. UVA 12232 Exclusive-OR(并查集+思想)

    题意:给你n个数,接着三种操作: I p v :告诉你 Xp = v I p q v :告诉你 Xp ^ Xq = v Q k p1 p2 … pk:问你k个数连续异或的结果 注意前两类操作可能会出现 ...

  10. POJ 2750 Potted Flower (线段树区间合并)

    开始懵逼找不到解法,看了网上大牛们的题解才发现是区间合并...  给你n个数形成一个数列环,然后每次进行一个点的修改,并输出这个数列的最大区间和(注意是环,并且区间最大只有n-1个数) 其实只需要维护 ...