3.1【U-boot分析】Bootloader概念及U-boo分析

Bootloader类似于Windows里的BIOS,用于启动Linux内核,其本质也是一段单片机程序,用于初始化硬件和搭建Linux启动环境。例如关看门狗,关中断,初始化Flash等。初始化完成以后就会引导内核启动。

Bootloader的启动大体可以分为两个部分,第一阶段使用汇编编写,用于做前期准备工作。可以这么理解第一阶段:

第一阶段的准备类似于我们小时候玩的跳方格。

第一步:我们得去找一根粉笔或者可以刻出字的石头=>初始化硬件。

第二步:准备好工具后,我们需要找场地,用粉笔画出我们要游戏的范围=>也就是准备Bootloader需要的RAM空间。

第三步:我们要把小朋友请到这里游戏 => Bootloader会将第二阶段的代码拷贝到RAM空间

第四步:给方格标记跳的顺序 => 设置栈

第五步:站在1号方格开始游戏 => 跳转到函数入口处

 

完成第一阶段的硬件准备工作后Bootloader将会跳转到第二段代码,这一阶段主要用于内核启动的前期工作,主要使用C语言编写的,可以这么理解这一阶段的操作:类似于打群架:

第一步:准备打斗工具:硬邦邦的拳头或者大棒 => 初始化调试用的硬件用于程序员与Bootloader进行交互

第二步:观察一下对方人数和位置 => 确认单板上有多少内存和地址空间是多少

第三步:过去把对方拖到计划的位置打一顿 => 将内核映射读到RAM后解压缩

第四步:在要害处拳拳留印记 => 在指定的地址处设置内核启动参数

第五步:最后踹上一脚 => 启动内核

在第二阶段完成后启动内核之前,还有初始化CPU设置,寄存器设置,禁止中断等操作。完成这些操作之后,会在内存的指定位置存放内核需要的一些参数,内核会到这个指定的地址里获取需要的参数。这个参数是一个结构体,内部一个tag_header和联合体,tag_header用于表示参数的类型,不同的tag_header调用不同的union联合体。


单板用的最多的Bootloader是U-boot,其对应关系就是手机和小米的对应关系。启动过程和实现的功能不同的Bootloader大体相同。那么如何使用U-boot和编译进单板?

首先在官网下载自己需要的u-boot源码,查看顶层目录的Makefile,里面回复告诉如何make config自己需要的,一般命名为单板名_config,配置完成后执行make all,将生成的.bin文件通过NFS,OFlash下载到单板上

我们将U-boot烧写进板子后启动,然后启动开发板。用串口进行监听,会发现u-boot启动时候会出现一段倒计时,此时我们按下任何一个按键,u-boot会进入下载模式,该模式是用于给开发者进行调试安装使用的。

四、Bootloader之uboot

       一、uboot的编译体验

 

            源码结构分析:Uboot共有26个子目录,大致可以分为4类:

 

 

            编译步骤:解压缩uboot文件---->打补丁----->配置----->编译

            解压缩:tar xjf u-boot-1.1.6.tar.bz2--->跳转到解压缩后的文件夹内

            1)怎么打补丁

                     补丁文件中修改过的代码表示:“---” 表示是 原来代码 。“+++”表示修改后的代码。

                    执行命令:patch -p?     <..补丁文件(?表示忽略前面文件目录的总数)

                    例如:patch -p1 <../u-boot-1.1.6_jz2440.patch

                    解释:-p1为补丁文件内增加的内容里第一个斜杆之前的目录

            2)怎么配置

                    执行命令:make  100ask24x0_config

            3)怎么编译:make

 

        二、Makefile结构分析

            1)配置命令 :make smdk2440_config 执行什么?

                    在Makefile中可以找到下面代码

...........

MKCONFIG    := $(SRCTREE)/mkconfig

........

smdk2440_config    :    unconfig

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

$(@:_config=)的结 果就是将”smdk2440_config“中的_config去掉,结果为“smdk2440”.所以“make smdk2440_config”实际上就是执行如下命令: 

./mkconfig smdk2440 arm arm920t smdk2410 NULL s3c24x0

                        MKCONFIG    := $(SRCTREE)/mkconfig的意思是在源文件下有一个mkconfig文件,打开它,会看到下面这个

APPEND=no    # Default: Create new config file

BOARD_NAME=""    # Name to print in make output


while [ $# -gt 0 ] ; do

    case "$1" in

    --) shift ; break ;;

    -a) shift ; APPEND=yes ;;

    -n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;

    *)  break ;;

    esac

done

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

       对于上面执行的./mkconfig smdk2440 arm arm920t smdk2440 NULL s3c2440 这条命令中没有--, -a ,-n等,所以不会这行这段代码,[ "${BOARD_NAME}" ] || BOARD_NAME="$1"则是将BOARD_NAME命名为s3c2440

        所以我们接着往下看,会看到这段

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 asm

else

    cd ./include

    rm -f asm

    ln -s asm-$2 asm

fi

        if [ "$SRCTREE" != "$OBJTREE" ] ; then判断源代码目录和目标文件目录是否是一样,如果条件不满足,将执行else分支的代码,进入include目录,删除asm文件,然后再次建立 asm文件,并令它链接向asm-$2目录,即asm-arm

        然后对相关参数进行配置

#

# Create include file for Make

#

echo "ARCH   = $2" >  config.mk

echo "CPU    = $3" >> config.mk

echo "BOARD  = $4" >> config.mk

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

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

     由./mkconfig smdk2440 arm arm920t smdk2410 NULL s3c24x0可得

ARCH = arm

CPU = arm920t

BOARD = smdk2410

SOC =s3c24x0

  

    接着创建开发板的头文件include/config.h

#

# Create board specific header file

#

if [ "$APPEND" = "yes" ]    # Append to existing config file

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

   APPEND维持原值no时 if [ "$APPEND" = "yes" ]不执行所以执行> config.h  创建一个config.h头文件,并将注释"/* Automatically generated - do not edit */" 和头文件#include <configs/$1.h>和#include <asm/config.h>包含进去

    看完了mkconfig文件,返回根文件目录下的Makefile,继续往下看,看到这段代码

# load ARCH, BOARD, and CPU configuration

include $(OBJTREE)/include/config.mk

export    ARCH CPU BOARD VENDOR SOC


ifndef CROSS_COMPILE

ifeq ($(HOSTARCH),ppc)

CROSS_COMPILE =

else

ifeq ($(ARCH),ppc)

CROSS_COMPILE = powerpc-linux-

endif

ifeq ($(ARCH),arm)

CROSS_COMPILE = arm-linux-

endif

ifeq ($(ARCH),i386)

ifeq ($(HOSTARCH),i386)

CROSS_COMPILE =

else

CROSS_COMPILE = i386-linux-

endif

endif

ifeq ($(ARCH),mips)

CROSS_COMPILE = mips_4KC-

endif

ifeq ($(ARCH),nios)

CROSS_COMPILE = nios-elf-

endif

ifeq ($(ARCH),nios2)

CROSS_COMPILE = nios2-elf-

endif

ifeq ($(ARCH),m68k)

CROSS_COMPILE = m68k-elf-

endif

ifeq ($(ARCH),microblaze)

CROSS_COMPILE = mb-

endif

ifeq ($(ARCH),blackfin)

CROSS_COMPILE = bfin-elf-

endif

ifeq ($(ARCH),avr32)

CROSS_COMPILE = avr32-

endif

endif

endif


export    CROSS_COMPILE


# load other configuration

include $(TOPDIR)/config.mk

    

第 一行中包含的config.mk文件,就是在第一开始配置过程中制作出来的include/conifg.mk文件,我们在一开始配置U-boot时执行 时生成的文件,其中定义了ARCH,CPU,BOARD,SOC等。

最后一句话include $(TOPDIR)/config.mk 包含顶层目录的config.mk文件。它根据上面4个变量的值确定了编译器。编译选项等。

            2)分析编译过程:0

                    ①第1个文件:cpu/arm920t/start.S

                    ②链接地址:board/100ask24x0_u-boot.lds+0x33F80000

        三、u-boot源码分析

                1)第一阶段(硬件相关的初始化)

                        a>设置SVC模式: set the cpu to SVC32 mode 将 CPU 设置为 SVC32 管理模式

                                    

                        b>关看门狗

                                    

                        c>屏蔽中断

                                    

                        d>初始化SDRAM

                        e>设置栈

                        f>时钟

                        g>代码Flash-->SDRAM(重定位)

                        h>清BSS段

                        i>调用start_armboot

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林零七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值