初步了解UBOOT (1)

来源:互联网 发布:淘宝刷手会坐牢吗 编辑:程序博客网 时间:2024/06/05 15:07

这两天在学习UBoot,简单说说自己的认识。
当然自己还是个新手,关于Uboot的更深入了解还有待提升自己,希望以后工作了能够对它越来越了解。

首先Uboot是Universal boot loader,就是通用的bootloader,也即引导加载程序,用来加载和启动操作系统的。在我所学的嵌入式开发板JZ2440中,它是用来启动LINUX操作系统,当然启动LINUX操作系统是它的最终目的,这其中Uboot要干的事情还有很多。

Uboot的启动分成了两个阶段
其中第一阶段的功能一般为:
1.硬件设备初始化
2.为加载Bootloader的第二阶段代码准备RAM空间
3.复制Bootloader的第二段代码到RAM空间中
4.设置好栈

第二阶段的功能一般为:
1.初始化本阶段要使用到的硬件设备
2.检测系统内存映射
3.将内核映像和根文件系统映像从FLASH读到RAM空间中
4.为内核设置启动参数
5.调用内核

明白了这些粗略的概念之后,我需要进一步去阅读uboot源码,让自己对大概的来龙去脉有所了解。
首先拿到了官方uboot是压缩后的文件 u-boot-1.1.6.tar.bz2 ,在Linux中使用解压缩指令 tar jxf u-boot-1.1.6.tar.bz2,进入到源码目录中,使用厂家提供的补丁文件对官方Uboot进行打补丁,补丁文件大概内容如下:

这里写图片描述

进入到Uboot源码目录,使用patch指令进行打补丁 patch -p1 < ../u-boot-1.1.6_jz2440.patch,选项-p1表示的是忽略补丁文件中的第一层目录,即u-boot-1.1.6。

打完补丁之后,Uboot源码目录有以下一堆文件:

这里写图片描述

当下载了一个官方的uboot时,该怎么做才能应用在我自己的JZ2440开发板中?
首先是配置,然后是编译,最后是烧写进板子。

在我使用的厂家所提供的Uboot中已经提供了相应的配置文件,所以只需要执行make 100ask24x0_config即可完成配置。根据该指令,我进入到Makefile文件进行跟踪,发现以下指令:

100ask24x0_config   :   unconfig    @$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0对其进行展开最终则为:./mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0

打开源码目录下的mkconfig文件,能对应的内容如下:

# Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]APPEND=no   # Default: Create new config fileBOARD_NAME=""   # Name to print in make output[ "${BOARD_NAME}" ] || BOARD_NAME="$1"echo "Configuring for ${BOARD_NAME} board..."## Create link to architecture specific headers#if [ "$SRCTREE" != "$OBJTREE" ] ; then    mkdir -p ${OBJTREE}/include    mkdir -p ${OBJTREE}/include2    cd ${OBJTREE}/include2    rm -f asm    ln -s ${SRCTREE}/include/asm-$2 asm    LNPREFIX="../../include2/asm/"    cd ../include    rm -rf asm-$2    rm -f asm    mkdir asm-$2    ln -s asm-$2 asmelse    cd ./include    rm -f asm    ln -s asm-$2 asmfirm -f asm-$2/archif [ -z "$6" -o "$6" = "NULL" ] ; then    ln -s ${LNPREFIX}arch-$3 asm-$2/archelse    ln -s ${LNPREFIX}arch-$6 asm-$2/archfiif [ "$2" = "arm" ] ; then    rm -f asm-$2/proc    ln -s ${LNPREFIX}proc-armv asm-$2/procfi## Create include file for Make#echo "ARCH   = $2" >  config.mkecho "CPU    = $3" >> config.mkecho "BOARD  = $4" >> config.mk[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC    = $6" >> config.mk## Create board specific header file#if [ "$APPEND" = "yes" ]   # Append to existing config filethen    echo >> config.helse    > config.h      # Create new config filefiecho "/* Automatically generated - do not edit */" >>config.hecho "#include <configs/$1.h>" >>config.hexit 0

所以根据该文件内容,我们能够得知. /mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
这条指令做了以下事情:
1.将开发板名称BOARD_NAME修改为100ask24x0
2.创建到平台/开发板相关的头文件的链接

  ln -s asm-arm asm  ln -s arch-s3c24x0 asm-100ask24x0/arch  ln -s proc-armv asm-100ask24x0/proc

3.创建顶层Makefile包含的文件include/config.mk,这一项很重要,因为它定义了顶层Makefile中一些宏的值,例如:

# load ARCH, BOARD, and CPU configurationinclude $(OBJTREE)/include/config.mkexport  ARCH CPU BOARD VENDOR SOCifndef CROSS_COMPILEifeq ($(HOSTARCH),ppc)CROSS_COMPILE =elseifeq ($(ARCH),ppc)CROSS_COMPILE = powerpc-linux-endififeq ($(ARCH),arm)CROSS_COMPILE = arm-linux-endif这段代码指出了使用了哪种编译器其中ARCH = armCPU = arm920tBOARD = 100ask24x0SOC = s3c24x0

4.创建开发板相关的头文件include/config.h,内容如下:

/* Automatically generated - do not edit */#include <configs/100ask24x0.h>

从以上4个结果可得,如果要在board目录下新建一个开发板 < board_name >的目录,则在include/configs目录下也要建立一个 < board_name >.h,里面存放的是开发板< board_name >的配置信息。
对于Uboot来说,没有类似Linux一样的可视化配置界面(例如make menuconfig来配置),只能要手动修改配置文件裁剪,该配置文件位于 include/configs/< board_name >.h

配置完成之后则是进行编译。直接执行make指令,即可得到u-boot.bin。
对于u-boot.bin,我们观察Makefile文件,可以看出来:

ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)all:        $(ALL)...$(obj)u-boot.bin:$(obj)u-boot        $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@它依赖于elf格式的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对于这么长的一段,我们可以通过对uboot进行编译,从编译信息中可以找到相对应的具体指令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.6 && arm-linux-ld -Bstatic -T /work/system/u-boot-1.1.6/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.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5 -lgcc \                        -Map u-boot.map -o u-boot

对于uboot的编译过程则能看出uboot是由这些 .a 还有 .o文件构成的。对于上面的编译信息能够得出比较重要的信息则在:

arm-linux-ld -Bstatic -T /work/system/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000  $UNDEF_SYM cpu/arm920t/start.o \

指出了链接脚本还有链接地址。

1 0