U-Boot编译过程详解

分享到:
           

    早,DENX软件工程中心的Wolfgang Denk基于8xxrom的源码创建了PPCBOOT工程,并且不断添加处理器的支持。后来,Sysgo Gmbh把PPCBOOT移植到ARM平台上,创建了ARMBOOT工程。然后以PPCBOOT工程和ARMBOOT工程为基础,创建了U-Boot工程。

    现在,U-Boot已经能够支持PowerPC、ARM、X86、MIPS体系结构的上百种开发板,已经成为功能多、灵活性强并且开发积极的开放源码Bootloader。U-Boot的源码包可以从sourceforge网站下载,还可以订阅该网站活跃的U-Boot Users邮件论坛,这个邮件论坛对于U-Boot的开发和使用都很有帮助。

    U-Boot软件包下载网站:http://sourceforge.net/project/U-Boot。
    U-Boot邮件列表网站:http://lists.sourceforge.net/lists/listinfo/U-Boot-users/。
    DENX相关的网站:http://www.denx.de。

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

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

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

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

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

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

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

    (1)顶层目录下的Makefile

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

    每一种开发板在Makefile都需要有板子配置的定义。例如,smdk2410开发板的定义如下。
    smdk2410_config :unconfig
        @./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

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

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

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

    ·board/smdk2410/
    ·cpu/arm920t/
    ·cpu/arm920t/s3c24x0/
    ·lib_arm/
    ·include/asm-arm/
    ·include/configs/smdk2410.h

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

    # load ARCH, BOARD, and CPU configuration
    include include/config.mk
    export ARCH CPU BOARD VENDOR SoC

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

    顶层目录的Makefile中还要定义交叉编译器,以及编译U-Boot所依赖的目标文件。

    ifeq ($(ARCH),arm)
    CROSS_COMPILE = arm-Linux-     # 交叉编译器的前缀
    #endif
    export CROSS_COMPILE
    …
    # U-Boot objects...order is important (i.e. start must be first)
    OBJS = cpu/$(CPU)/start.o     # 处理器相关的目标文件
    …
    LIBS = lib_generic/libgeneric.a     #定义依赖的目录,每个目录下先把目标文件连接成*.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
    …

    然后还有U-Boot镜像编译的依赖关系。

    ALL = U-Boot.srec U-Boot.bin System.map
    all: $(ALL)
    U-Boot.srec: U-Boot
        $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
    U-Boot.bin: U-Boot
        $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
    …
    U-Boot: depend $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
        UNDEF_SYM='$(OBJDUMP) -x $(LIBS) \
        |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
        $(LD) $(LDFLAGS) $$UNDEF_SYM $(OBJS) \
        --start-group $(LIBS) $(PLATFORM_LIBS) --end-group \
        -Map U-Boot.map -o U-Boot

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

    (1)开发板配置头文件

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

    这个头文件中主要定义了两类变量。

    一类是选项,前缀是CONFIG_,用来选择处理器、设备接口、命令、属性等。例如:

    #define    CONFIG_ARM920T    1
    #define    CONFIG_DRIVER_CS8900    1

    另一类是参数,前缀是CFG_,用来定义总线频率、串口波特率、Flash地址等参数。例如:

    #define    CFG_Flash_BASE    0x00000000
    #define    CFG_PROMPT    "=>"

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

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

    表1.2 U-Boot编译生成的镜像文件

表1.2	U-Boot编译生成的镜像文件

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


   热点链接:

   1、ARM处理器是什么
   2、FPGA从事的工作是什么
   3、北京嵌入式培训哪好
   4、嵌入式培训资料:搭建交叉编译环境
   5、qq for android是什么意思

更多新闻>>