现在的位置: 首页 > 综合 > 正文

bootloader及uboot初期配置简介

2019年04月20日 ⁄ 综合 ⁄ 共 5546字 ⁄ 字号 评论关闭

首先介绍一下bootloader

       在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。

在arm处理器中各软件部分的分布:

(从0x00000000开始)bootloader   -->    boot parameters(传给内核的参数)     ---->     kernel     ------->图形用户界面(可选) -------->   root  filesystem

通用bootloader的启动的两个阶段:

    第一阶段:

               硬件初始化:关看门狗、关中断、设置时钟、RAM初始化

               为二阶段准备RAM空间

               复制二阶段代码到RAM

              设置好堆栈

               跳到二阶段C入口处

   第二阶段:

               初始化需要的硬件:串口 ......

               检测内存映射

               将内核映像、根文件系统映像从FLASH上读到RAM中(可能需解压)

               设置内核启动参数

               调用内核:调用内核前的条件

                  (1)cpu寄存器的设置

                                 R0 = 0

                                 R1 = 机器类型ID

                                 R2 = 启动参数列表在RAM中的基址

                 (2)cpu工作模式

                                 禁止IRQ  FIQ

                                 CPU为SUV模式

                 (3)cache  mmu的设置

                                 MMU关闭

                                 指令cache可开可关

                                 数据cache必须关闭


下面进入常见的uboot分析

先看uboot源码目录层次结构

   lib_generic            common              include                ————————>通用函数

post        net       fs       disk                                                _______________驱动       

nand_spl            rtc             drivers

board          cpu            lib_xxx                                           —————————底板  平台

例如:通用函数(common/cmd_nand.c) 调用的是驱动层(drivers/nand/nand_base.c),再调用底板或平台层(cpu/xxx   board/xxx)

uboot的编译: 根据配置修改好文件如在顶层makefile中添加开发板目标,在include/configs/下创建board_name.h,然后执行如下命令

                                #make makefile中目标名(开发板名_config)                           ; 对应的板子做文件配置             

                                #make all                                                   ; 对源程序进行编译


对编译步骤的具体分析:

                       第一步make  board_name_config

所有的编译都是从顶层makefile
决定的

                    在makefile中查找  board_name_config  目标(下面以smdk2410为分析对象) 

MKCONFIG    := $(SRCTREE)/mkconfig
export MKCONFIG

......

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

     

             MKCONFIG就是根目录下的mkconfig文件, $(@:_config=)是将目标中的_config去掉,所以实际上是执行如下命令

  ./mkconfig    smdk2410    arm arm920t smdk2410 NULL s3c24x0  
           

执行上边这命令就会去执行mkconfig脚本文件,所以下面分析mkconfig文件内容

6     # Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]     ;给出了mkconfig的使用方法

;下面确定开发板的名称

23   [ "${BOARD_NAME}" ] || BOARD_NAME="$1"      

;下面是创建到平台/开发板的相关头文件的链接

46    cd ./include        

47    rm -f asm
 48   ln -s asm-$2 asm   


51    rm -f asm-$2/arch

56    ln -s ${LNPREFIX}arch-$6 asm-$2/arch      ;LNPREFIX为空


60    rm -f asm-$2/proc
61    ln -s ${LNPREFIX}proc-armv asm-$2/proc


;下面是创建顶层makefile包含的文件incude/config.mk

#
# Create include file for Make
#
67  echo "ARCH   = $2" >  config.mk
68  echo "CPU    = $3" >> config.mk
69  echo "BOARD  = $4" >> config.mk

71  [ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk

73   [ "$6" ] && [ "$6" != "NULL" ] && echo "SOC    = $6" >> config.mk

;下面是创建开发板相关的头文件

#
# Create board specific header file
#
if [ "$APPEND" = "yes" ]    # Append to existing config file              ;APPEND为  no
then
    echo >> config.h
else
    > config.h        # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.h

;所以创建了config.h文件,内容如下:

              "/* Automatically generated - do not edit */" >>config.h
              "#include <configs/$1.h>" >>config.h      
;此处包含了incude/configs/board_name.h

至此make  board_name_config命令执行完

下面看一下如何通过incude/configs/board_name.h配置文件来裁剪 uboot

         这个头文件中主要定义了两类宏
       
       
         一类是选项,前缀是CONFIG_,用来选择处理器、设备接口、命令、属性等,主要用来 决定是否编译某些文件或者函数。

         另一类是参数,前缀是CFG_,用来定义总线频率、串口波特率、Flash地址等参数。这些常数参量主要用来支持通用目录中的代码,定义板子资源参数。

         这两类宏定义对u-boot的移植性非常关键,比如drive/CS8900.c,对cs8900而言,很多操作都是通用的,但不是所有的板子上面都有这个芯片,即使有它在内存中映射的基地址也是平台相关的。所以对于smdk2410板,在             
         smdk2410.h中定义了
          #define CONFIG_DRIVER_CS8900 1              /* we have a CS8900 on-board */
          #define CS8900_BASE 0x19000300              /*IO mode base address*/
         CONFIG_DRIVER_CS8900的定义使得cs8900.c可以被编译(当然还得定义CFG_CMD_NET才行),因为cs8900.c中在函数定义的前面就有编译条件判断:#ifdef CONFIG_DRIVER_CS8900 如果这个选项没有定义,整            cs8900.c就        
不会被编译了。
         而常数参量CS8900_BASE则用在cs8900.h头文件中定义各个功能寄存器的地址。u-boot的CS8900工作在IO模式下,只要给定IO寄存器在内存中映射的基地址,其余代码就与平台无关了。
 
           u-boot的命令也是通过目标板的配置头文件来配置的,比如要添加ping命令,就必须添加CFG_CMD_NET和CFG_CMD_PING才行。不然common/cmd_net.c就不会被编译了。
         

   第二个命令make all


117  include $(OBJTREE)/include/config.mk ;包含文件,确定CPU,ARCH,BOARD,SOC等参数

164  include $(TOPDIR)/config.mk   ;包含顶层config.mk

     看看顶层config.mk中有用的信息

       88  BOARDDIR = $(BOARD)

       91  sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk    # include board specific rules

       在board/$(BOARDDIR)/config.mk 中有TEXT_BASE的定义


;下面指定变量的值

169   OBJS  = cpu/$(CPU)/start.o
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
ifeq ($(CPU),mpc83xx)
LIBS += drivers/qe/qe.a
endif
LIBS += drivers/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/cpu/libcpu.a
LIBS += common/libcommon.a
LIBS += $(BOARDLIBS)


;下面指定要编译的内容

268  $(OBJS):
        $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))

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


;下面是链接的规则

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

至此整个uboot的配置编译结束


      

参考文档:http://blog.csdn.net/liukun321/article/details/5680504

《嵌入式linux应用完全手册 韦东山》

抱歉!评论已关闭.