u-boot-2009.08工程编译过程分析

1、背景:

             由于项目需求,需要了解bootloader的相关知识,而项目中使用到的bootloader为u-boot-2009.08,
所以本文以u-boot的2009.08版本为基础进行分析。
       正如标题所言,本文只对u-boot的编译过程进行分析,而暂且不去理会u-boot代码结构、u-boot的
启动流程以及详细的代码分析等。
       写作本文的目的主要是为了方便日后查阅u-boot相关的知识,正所谓“好记性不如烂笔头”。另外
如果此文能帮助各位同行或者刚接触 u-boot的人更好的理解u-boot的相关知识,本人也深感欣慰。如
文中有不当或者错误的地方,也请指正,本人不胜感激!

2、u-boot

      u-boot是bootloader中的一种,也是嵌入式开发中应用最广的一种,已经支持了多种CPU和多种开发
板。u-boot在嵌入式产品中的作用主要是引导操作系统,即板子上电或者复位之后首先会运行u-boot程序
,然后才去加载操作系统。需要强调的是,这只是u-boot最平凡的作用,u-boot本身的“能力”远不止于此。
       注:不是所有的板子上电后运行的第一段程序就是u-boot程序,很多CPU内部集成了一块ROM,出
厂时就由厂家固化了一段引导程序,用户是擦除不掉的。这段程序是在u-boot之前运行的。这块ROM程序
存在的原因:CPU上电后需要运行程序,假设程序在nand flash或者usb又或者SD卡这样的存储设备中,
而CPU的程序需要在RAM里面运行,这时就由这段ROM程序驱动nand flash或者usb又或者SD卡接口,将
其中的程序拷贝到RAM里面再去执行。很多板子在没有任何程序(也没有u-boot程序)的时候能用USB进
行烧片应该也是由于这个原因。
       u-boot-2009.08是uboot的一个版本,u-boot的命名方式可以网上查找相关资料了解。

3、u-boot编译流程概要

        回到本文的主题----u-boot-2009.08的编译过程分析 一般编译u-boot分为两步:
        (1)执行命令make boardname_config配置开发板,如make smdk2410_config;
        (2)执行命令make进行编译;

         3.1、make boardname_config流程概要
               执行make boardname_config命令后,根据Makefile指定的编译顺序,会执行以下几个操作:
                <1>、在顶层include目录下:生成asm目录,并将此目录链接到对应的以asm-开头的目录,如ln  -s 
        asm-arm asm;
                <2>、在顶层include目录下:在对应的以asm-开头的目录生成arch目录,并将此目录链接到对应
        的以arch-开头的目录,如ln -s arch-s3c24x0 asm-arm/arch;
                <3>、在顶层include目录下:生成config.mk文件,并在此文件中添加相应的内容;
                <4>、在顶层include目录下:生成config.h文件,并在此文件中添加相应的内容。

         3.2、make流程概要
                执行make命令后,根据Makefile指定的编译顺序,会执行以下一些操作:
                <1>、在顶层include目录下:生成timestamp_autogenerated.h文件;
                <2>、在顶层include目录下:生成version_autogenerated.h文件
                <3>、在顶层include目录下:生成autoconf.mk文件,并在此文件中添加相应的内容;
                <4>、在tools、example/standalone和example/api三个目录下根据各自的Makefile文件进行编译。在
        tools目录下会生成mkimage、img开头的一些工具。其他两个目录下生成一些测试demo,如helloworld;
                <5>、在顶层cpu目录下:在对应的具体的CPU型号的目录中根据Makefile文件生成start.o文件。某些
        CPU下还会生成start16.o等目标文件;
                <6>、在对应的目录下生成多个静态库文件,如在lib_generic目录下生成libgeneric.a、liblzma.a、
        liblzo.a;在drivers/i2c目录下生成libi2c.a;在common目录下生成libcommon.a等;
                <7>、在 顶层board目录下对应的目录中生成对应的库文件,如在board/samsung/smdk2410目录下生
        成 libsmdk2410.a
                <8>、在 顶层目录下生成u-boot.lds链接脚本
                <9>、在顶层目录下生成u-boot.map文件和ELF格式的文件u-boot 
                <10>、在顶层目录下分别生成S-recordd格式文件u-boot.srec 二进制文件u-boot.bin和system.map
        文件
                <11>、根据配置,在顶层目录下还可能会生成u-boot-nand.bin和u-boot-onenand.bin二进制文件

4、u-boot-2009.08顶层Makefile分析

       不管执行make boardname_config命令还是make命令,都是根据Makefile文件进行相关处理。所以,
首先我们还是应该仔细阅读清楚Ma kefile文件。下面便正式开始顶层Makefile文件的分析:
       注:为了方便阅读,u-boot源码大部分标注为黑色,需要注意的地方标注为红色;注释标注为蓝色,
需要注意的地方也标注为红色;

/***********************************************************************************************************************/
/*********************************************Start:Makefile文件分析**********************************************/
/***********************************************************************************************************************/
   /* 24~27行定义了u-boot的各版本号 */
    24 VERSION = 2009
    25 PATCHLEVEL = 08
    26 SUBLEVEL =
    27 EXTRAVERSION =
   /* 28~32行:如果变量SUBLEVEL的值为不空,则执行ifneq段,否则执行else段,显然为else段*/
    28 ifneq "$(SUBLEVEL)" ""
    29 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
    30 else
    31 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL)$(EXTRAVERSION)
    32 endif

   /* 33~34行定义了变量TIMESTAMP_FILE和变量VERSION_FILE */
   /* 注意:下面源码中标红的两个文件为编译过程中自动生成的,编译之前是不存在的,$(obj)此处还未定
   义,为空,所以这两个文件最后生成的位置就是顶层目录下的include目录中。这两个变量是如何生成的,
   暂且记为问题Q1和Q2,留到后面再分析,先按照顺序往下接着走 */
    33 TIMESTAMP_FILE =$(obj)include/t imestamp_autogenerated.h(Q1:timestamp_autogenerated.h如何生成的?)
    34 VERSION_FILE =$(obj)include/ version_autogenerated.h(Q2:version_autogenerated.h如何生成的?)

   /* 36~43行定义了变量HOSTARCH ,即主机的架构,得到的结果为HOSTARCH := i386 */
    36 HOSTARCH := $(shell uname -m | \ /* $(shell command)格式的意思是在Makefile文件中调用shell命令
    37 sed -e s/i.86/i386/ \ uname -m为打印主机硬件架构名字的命令,在我的机器上为i686 */
    38    -e s/sun4u/sparc64/ \ /* 符号“|” 为连接管道命令 */
    39    -e s/arm.*/arm/ \ /* 符号“\” 为断行符 */
    40    -e s/sa110/arm/ \ /* sed为操作字符的管道命令,sed -e s/aaa/bbb/命令表示把字符串
    41    -e s/powerpc/ppc/ \ 中的字符aaa替换为bbb*/
    42    -e s/ppc64/ppc/ \ /* i.86中的.表示任意字符 */
    43    -e s/macppc/ppc/)
    /* 45~46行定义了变量HOSTOS ,即主机的操作系统,得到的结果为HOSTOS := linux */
    45 HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ /*uname -m为打印主机操作系统内核名称,在我的
    46    sed -e 's/\(cygwin\).*/cygwin/') Ubuntu系统中为Linux */
/*tr '[:upper:]' '[:lower:]'命令将大写字母替换为小写字母 */  

    /* 48~51行定义了变量 SHELL  ,得到的结果为 SHELL := /bin/bash  */
    48 # Set shell to bash if possible, otherwise fall back to sh
    49 SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
    50 else if [ -x /bin/bash ]; then echo /bin/bash; \
    51 else echo sh; fi; fi)
     /* 53行将上述三个变量导出,以便子Makefile中也可以访问这三个变量   */
    53 export HOSTARCH HOSTOS SHELL

    /* 56行的变量VENDOR暂时没有定义 */
    55 # Deal with colliding definitions from tcsh etc.
    56 VENDOR=

    /* 58~64行定义XECHO变量,得到的结果是XECHO =: */
    58 #########################################################################
    59 # Allow for silent builds /* 静态编译,即make -s,此时编译过程中将不打印出相关
的命令 */
    60 ifeq (,$(findstring s,$(MAKEFLAGS))) /*findstring 函数在变量MAKEFLAGS中查找是否存在字符s */
    61 XECHO = echo
    62 else
    63 XECHO = :
    64 endif

    /* 68~86行说明了在编译u-boot时可以用两种方式制定一个输出路径。u-boot的源码顶层目录下的
README文件中也对此有说明。对此不再做详细说明,一般情况下都不指定,而是直接编译 */
    66 #########################################################################
    67 #
    68 # U-boot build supports producing a object files to the separate external
    69 # directory. Two use cases are supported:
    70 #
    71 # 1) Add O= to the make command line
    72 # 'make O=/tmp/build all'
    73 #
    74 # 2) Set environement variable BUILD_DIR to point to the desired location
    75 # 'export BUILD_DIR=/tmp/build'
    76 # 'make'
    77 #
    78 # The second approach can also be used with a MAKEALL script
    79 # 'export BUILD_DIR=/tmp/build'
    80 # './MAKEALL'
    81 #
    82 # Command line 'O=' setting overrides BUILD_DIR environent variable.
    83 #
    84 # When none of the above methods is used the local build is performed and
    85 # the object files are placed in the source directory.
    86 #
    /* 88~92行根据具体情况对变量BUILD_DIR 赋值 */
    88 ifdef O
    89 ifeq ("$(origin O)", "command line") /*origin 函数查询变量O的出处,如果O是在命令行中定义的话,则
    90 BUILD_DIR := $(O) 返回command line */
    91 endif
    92 endif
    /* 94~103行根据变量BUILD_DIR的值做如下处理   */
    94 ifneq ($(BUILD_DIR),) /*如果变量BUILD_DIR不为空变量BUILD_DIR的值保存到saved-
    95 saved-output := $(BUILD_DIR) output中*/
    96
    97 # Attempt to create a output directory.
    98 $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})/* 如果不存在目录BUILD_DIR,则用mkdir命令创建*/
    99
   100
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值