uboot 编译、生成、运行--uboot诞生记

    每一段程序的诞生,都是神圣而伟大的……

    今天,我们就来见证这神圣而伟大的时刻!

 

    上一篇《Exynos4412 启动过程 - bootloader的一生》,我们主要了解了系统的启动过程,iRAM --> BL1 --> BL2 --> 启动OS

    其中,iRAM固化在芯片里,iRAM会根据OM Pin,选择从哪种启动介质(SD,NAND Flash,eMMc等)加载并运行BL1,BL1再加载BL2(如果有的话),BL2再启动OS。

    iRAM固化在芯片里,只要芯片没坏,硬件电路设计正确,一启动,就必然会先执行iRAM代码。

    BL1由三星提供,BL2可能由三星提供(pop封装),也可能从编译生成的代码中取14k(scp封装),启动OS前呢,要初始化系统,构建系统所能运行的环境,是自个编译的。

    所以,u-boot的构成,可能会是 BL1+BL2+其它。

 

    这一篇,我们以迅为开发板的uboot为例,编译、生成、烧录,了解整个uboot的诞生。

    本人板卡使用 samsung exynos4412 POP封装的,内置1GDDR。

    1、 解压:注意,一定要拷在linux系统下解压,不能在window下解压,除非,你只想看一看代码。

    2、 ./build_sh POP_1GDDR(因为我的芯片是 POP_1GDDR的,如果哪位是 SCP的,请选择别的参数)

    3、 等一大会...

    就这样,编译和生成都一步到位,生成的u-boot-iTOP-4412.bin,就是要烧录的bin文件。

    5.28日 11:19,成功诞下u-boot,男女未知?重45465字节。名u-boot-iTop-4412.bin

 

    上一篇《Exynos4412 启动过程 - bootloader的一生》我们讲过,iRAM会根据 OM Pin,选择启动介质。

    这个启动介质可以是 SD卡,eMMC等,得先把生成的 u-boot-iTop-4412.bin,写进启动介质里面。

    板子刚出厂的时候,除了 iROM之外,eMMC,SD等存储介质,是没有任何程序的,系统一上电,就只能运行 iROM程序。

    我们就选择SD卡启动吧。为什么不选择eMMC呢?因为eMMC是焊在板子上的啊,你得把它取下来,烧好了,再焊上去,麻烦。

    选择 SD 卡启动,就要把 u-boot-iTop-4412.bin 写进 SD 卡里面。

    1、 插入SD卡。

    2、 ./mkuboot /dev/sdb

    3、 等一小会...

    就这样,把u-boot_itop412.bin写进SD卡里面。

    把拨码开关设置至xxxx,看上一篇的OM Pin选择。

    插入SD卡,连上串口线,开机,这就是u-boot的启动界面,至此,bootloader的使命结束。

    PS:一般来说,这就是 u-boot,u-boot的作用仅仅只是引导系统,在实际应用中,我们会把u-boot,内核,文件系统,统统烧录进emmc里面,由板载的emmc引导,启动。该过程类似于安装操作系统,emmc相当于硬盘,SD卡相当于U盘安装盘。图中,由于在 mmc 里面没有找到内核和文件系统,所以最终无法启动操作系统。

 

    我们从 ./build_sh 开始,一步步来了解一下,u-boot 的形成机制。

    这是一个 shell 脚本,不熟悉 shell 脚本的同学,请移步《linux shell 脚本 - 给男友的家务清单

    完整的 build_uboot.sh 文件如下:

#!/bin/sh



if [ -z $1 ]

then    

   echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"

   echo "Please use correct make config.for example make SCP_1GDDR for SCP 1G DDR CoreBoard linux,android OS"

   echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"

   exit 0

fi


if   [ "$1" = "SCP_1GDDR" ] ||   [ "$1" = "SCP_2GDDR" ] || [ "$1" = "SCP_1GDDR_Ubuntu" ] ||   [ "$1" = "SCP_2GDDR_Ubuntu" ]

then

      sec_path="../CodeSign4SecureBoot_SCP/"

      CoreBoard_type="SCP"


elif [ "$1" = "POP_1GDDR" ] || [ "$1" = "POP_1GDDR_Ubuntu" ]

then

      sec_path="../CodeSign4SecureBoot_POP/"

      CoreBoard_type="POP"


elif [ "$1" = "POP_2GDDR" ] ||  [ "$1" = "POP_2GDDR_Ubuntu" ]

then

     sec_path="../CodeSign4SecureBoot_POP/"

     CoreBoard_type="POP2G"

else

      echo "make config error,please use correct params......"

      exit 0

fi


CPU_JOB_NUM=$(grep processor /proc/cpuinfo | awk '{field=$NF};END{print field+1}')

ROOT_DIR=$(pwd)

CUR_DIR=${ROOT_DIR##*/}




#clean

make distclean


#rm link file

rm ${ROOT_DIR}/board/samsung/smdkc210/lowlevel_init.S    

rm ${ROOT_DIR}/cpu/arm_cortexa9/s5pc210/cpu_init.S


case "$1" in

    clean)

        echo make clean

        make mrproper

        ;;

    *)

            

        if [ ! -d $sec_path ]

        then

            echo "**********************************************"

            echo "[ERR]please get the CodeSign4SecureBoot first"

            echo "**********************************************"

            return

        fi


                if [ "$1" = "SCP_1GDDR" ]

                then

                    make itop_4412_android_config_scp_1GDDR


                elif [ "$1" = "SCP_2GDDR" ]

                then

                       make itop_4412_android_config_scp_2GDDR


                elif [ "$1" = "POP_1GDDR" ]

                then

                       make itop_4412_android_config_pop_1GDDR


                elif [ "$1" = "POP_2GDDR" ]

                then

                       make itop_4412_android_config_pop_2GDDR


                elif [ "$1" = "SCP_1GDDR_Ubuntu" ]    

                then

                       make itop_4412_ubuntu_config_scp_1GDDR


                elif [ "$1" = "SCP_2GDDR_Ubuntu" ]

                then

                       make itop_4412_ubuntu_config_scp_2GDDR


                elif [ "$1" = "POP_1GDDR_Ubuntu" ]

                then

                       make itop_4412_ubuntu_config_pop_1GDDR


                elif [ "$1" = "POP_2GDDR_Ubuntu" ]

                then

                       make itop_4412_ubuntu_config_pop_2GDDR

        fi    

        

        make -j$CPU_JOB_NUM

        

        if [ ! -f checksum_bl2_14k.bin ]

        then

            echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"

            echo "There are some error(s) while building uboot, please use command make to check."

            echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"

            exit 0

        fi

        

        cp -rf checksum_bl2_14k.bin $sec_path

        cp -rf u-boot.bin $sec_path

        rm checksum_bl2_14k.bin

        

        cd $sec_path

        #./codesigner_v21 -v2.1 checksum_bl2_14k.bin BL2.bin.signed.4412 Exynos4412_V21.prv -STAGE2

        

        # gernerate the uboot bin file support trust zone

        #cat E4412.S.BL1.SSCR.EVT1.1.bin E4412.BL2.TZ.SSCR.EVT1.1.bin all00_padding.bin u-boot.bin E4412.TZ.SSCR.EVT1.1.bin > u-boot-iTOP-4412.bin



                if  [ "$CoreBoard_type" = "SCP" ]

                then

                cat E4412_N.bl1.SCP2G.bin bl2.bin all00_padding.bin u-boot.bin tzsw_SMDK4412_SCP_2GB.bin > u-boot-iTOP-4412.bin


                elif [ "$CoreBoard_type" = "POP" ]

                then

                   cat E4412.S.BL1.SSCR.EVT1.1.bin E4412.BL2.TZ.SSCR.EVT1.1.bin all00_padding.bin u-boot.bin E4412.TZ.SSCR.EVT1.1.bin > u-boot-iTOP-4412.bin


                elif [ "$CoreBoard_type" = "POP2G"  ]

                then

                   cat bl2.bin u-boot.bin E4412.TZ.SSCR.EVT1.1.bin > u-boot-iTOP-4412.bin


                else

                   echo  "make uboot image error......"

                fi


        mv u-boot-iTOP-4412.bin $ROOT_DIR

        

        rm checksum_bl2_14k.bin

        #rm BL2.bin.signed.4412

        rm u-boot.bin


        echo

        echo

        ;;

        

esac

    其中,关键的部分:

        make itop_4412_android_config_pop_1GDDR

        make -j$CPU_JOB_NUM

    这两行生成 u-boot.bin。

    make itop_4412_android_config_pop_1GDDR 生成各种配置文件,稍候我们仔细研读一下 Makefile自然了解;

    make -j$CPU_JOB_NUM 这个看你多少核 cpu,在我的电脑是,就是 make -j4,直接 make 也是可以的,只是编译的速度,比 make -j4 慢而已;

 

        cd $sec_path

        cat E4412.S.BL1.SSCR.EVT1.1.bin E4412.BL2.TZ.SSCR.EVT1.1.bin all00_padding.bin u-boot.bin E4412.TZ.SSCR.EVT1.1.bin > u-boot-iTOP-4412.bin

    这两行生成 u-boot-iTOP-4412.bin

    sec_path="../CodeSign4SecureBoot_POP/" 在make 之前已经设置好了。

    cd $sec_path 相当于进入 ../CodeSign4SecureBoot_POP/ 目录

    cat E4412.S.BL1.SSCR.EVT1.1.bin E4412.BL2.TZ.SSCR.EVT1.1.bin all00_padding.bin u-boot.bin E4412.TZ.SSCR.EVT1.1.bin > u-boot-iTOP-4412.bin

    E4412.S.BL1.SSCR.EVT1.1.bin + E4412.BL2.TZ.SSCR.EVT1.1.bin + all00_padding.bin + u-boot.bin + E4412.TZ.SSCR.EVT1.1.bin 拼起来,形成 u-boot-iTOP-4412.bin

 

    u-boot.bin 由我们编译而成,E4412.S.BL1.SSCR.EVT1.1.bin、E4412.BL2.TZ.SSCR.EVT1.1.bin、all00_padding.bin、E4412.TZ.SSCR.EVT1.1.bin 是由三星提供,在 CodeSign4SecureBoot_POP/ 目录下。

    所以,执行 ./build_uboot.sh POP_1GDDR 前,需要把三星提供的目录 CodeSign4SecureBoot_POP 拷到 u-boot 目录 的上级目录下。

 

    基本流程就是:

        1、make itop_4412_android_config_pop_1GDDR 进行配置,

        2、make -j4 编译生成 u-boot.bin,

        3、cat E4412.S.BL1.SSCR.EVT1.1.bin E4412.BL2.TZ.SSCR.EVT1.1.bin all00_padding.bin u-boot.bin E4412.TZ.SSCR.EVT1.1.bin > u-boot-iTOP-4412.bin 拼成最终的 u-boot-iTOP-4412.bin

 

    PS:build_uboot.sh 在原生的 u-boot 源代码上是没有的,原生的 u-boot 源代码,要自已 make xxxxxxxx_conf 再自己 make -j4,再自己 cat,当然,你可以自己仿照它写一个,方便编译。

 

1、make itop_4412_android_config_pop_1GDDR 进行配置

    打开 Makefile,Makefile的源码比较长,我就不放了。

    没有 Makefile 基础的同学们,请移步 《Makefile基础 - 让我欢喜让我忧

    搜一下:itop_4412_android_config_pop_1GDDR

itop_4412_android_config_pop_1GDDR:        unconfig

    @$(MKCONFIG) $(@:_config=) arm arm_cortexa9 smdkc210 samsung s5pc210 POP_1GDDR

    @$(MKCONFIG) $(@:_config=) arm arm_cortexa9 smdkc210 samsung s5pc210 POP_1GDDR

    MKCONFIG    := $(SRCTREE)/mkconfig

    $(@:_config=) 是把 itop_4412_android_config_pop_1GDDR中的 _config去掉,

    所以,整个就变成了

        mkconfig itop_4412_android_pop_1GDDR arm arm_cortexa9 smdkc210 samsung s5pc210 POP_1GDDR

    mkconfig 是个什么东西?

        mkconfig 也是个 shell 脚本,不熟悉 shell 脚本的同学,请移步《linux shell脚本 - 给男友的家务清单》。

#!/bin/sh -e


# Script to create header files and links to configure

# U-Boot for a specific board.

#

# Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]

#

# (C) 2002-2006 DENX Software Engineering, Wolfgang Denk <wd@denx.de>

#


APPEND=no    # Default: Create new config file

#BOARD_NAME=""    # Name to print in make output

TARGETS=""


echo "CoreBoard  is $7...... "


if   [ "$7" = "SCP_1GDDR" ]  ||   [ "$7" = "SCP_2GDDR" ] || [ "$7" = "POP_1GDDR" ]  ||   [ "$7" = "POP_2GDDR" ]

then

      BOARD_NAME="itop_4412_android"

      echo "CoreBoard OS is android or linux...... "


elif [ "$7" = "SCP_1GDDR_Ubuntu" ]  ||  [ "$7" = "SCP_2GDDR_Ubuntu" ] || [ "$7" = "POP_1GDDR_Ubuntu" ] ||  [ "$7" = "POP_2GDDR_Ubuntu" ]

then

      BOARD_NAME="itop_4412_ubuntu"

      echo "CoreBoard OS is Ubuntu...... "

else

      echo "unknown coreboard type and os type......"

fi

    

while [ $# -gt 0 ] ; do

    case "$1" in

    --) shift ; break ;;

    -a) shift ; APPEND=yes ;;

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

    -t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;

    *)  break ;;

    esac

done


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


[ $# -lt 4 ] && exit 1

[ $# -gt 7 ] && exit 1


if [ "${ARCH}" -a "${ARCH}" != "$2" ]; then

    echo "Failed: \$ARCH=${ARCH}, should be '$2' for ${BOARD_NAME}" 1>&2

    exit 1

fi


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 asm

else

    cd ./include

    rm -f asm

    ln -s asm-$2 asm

fi


rm -f asm-$2/arch


if [ -z "$6" -o "$6" = "NULL" ] ; then

    ln -s ${LNPREFIX}arch-$3 asm-$2/arch

else

    ln -s ${LNPREFIX}arch-$6 asm-$2/arch

fi


if [ "$2" = "arm" ] ; then

    rm -f asm-$2/proc

    ln -s ${LNPREFIX}proc-armv asm-$2/proc

fi


#

# 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


# Assign board directory to BOARDIR variable

if [ -z "$5" -o "$5" = "NULL" ] ; then

    BOARDDIR=$4

else

    BOARDDIR=$5/$4

fi




#add by dg for kinds of coreboard

if   [ "$7" = "SCP_1GDDR" ] ||   [ "$7" = "SCP_2GDDR" ] || [ "$7" = "SCP_1GDDR_Ubuntu" ] ||   [ "$7" = "SCP_2GDDR_Ubuntu" ]

then

     echo "CORE   =  SCP" >> config.mk

     ln -sf ${SRCTREE}/board/samsung/smdkc210/lowlevel_init_SCP.S  ${SRCTREE}/board/samsung/smdkc210/lowlevel_init.S    

     ln -sf ${SRCTREE}/cpu/arm_cortexa9/s5pc210/cpu_init_SCP.S     ${SRCTREE}/cpu/arm_cortexa9/s5pc210/cpu_init.S


elif [ "$7" = "POP_1GDDR" ]  ||  [ "$7" = "POP_2GDDR" ] || [ "$7" = "POP_1GDDR_Ubuntu" ] ||  [ "$7" = "POP_2GDDR_Ubuntu" ]

then

     echo "CORE   =  POP" >>  config.mk

     ln -sf ${SRCTREE}/board/samsung/smdkc210/lowlevel_init_POP.S  ${SRCTREE}/board/samsung/smdkc210/lowlevel_init.S    

     ln -sf ${SRCTREE}/cpu/arm_cortexa9/s5pc210/cpu_init_POP.S     ${SRCTREE}/cpu/arm_cortexa9/s5pc210/cpu_init.S

else

      echo "make config error,please use correct params......"

      exit 0

fi



#

# 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


for i in ${TARGETS} ; do

    echo "#define CONFIG_MK_${i} 1" >>config.h ;

done


#add by dg for all itop4412 type boards


[ "$7" ] && [ "$7" != "NULL" ] && echo "#define CONFIG_$7" >> config.h


cat << EOF >> config.h

#define CONFIG_BOARDDIR board/$BOARDDIR

#include <config_defaults.h>

#include <configs/$BOARD_NAME.h>

#include <asm/config.h>

EOF


exit 0

    它创建了一些编译所需的链接文件(类似于快捷方式,方便不同平台编译)、配置文件(如config.mk、config.h等),等等。

    所以,make itop_4412_android_config_pop_1GDDR 的作用是配置编译所需要的文件和环境,为下一步编译做准备。

 

2、make -j4 编译生成 u-boot.bin

    这个就是编译生成,它编译生成 u-boot.bin,但这不是我们最终烧录进板卡的 bootlaoder。

 

3、cat E4412.S.BL1.SSCR.EVT1.1.bin E4412.BL2.TZ.SSCR.EVT1.1.bin all00_padding.bin u-boot.bin E4412.TZ.SSCR.EVT1.1.bin > u-boot-iTOP-4412.bin

    这句生成最终的 u-boot-iTOP-4412.bin 文件,是我们最终烧录进板卡的 bootloader。

    基中,

    4412.S.BL1.SSCR.EVT1.1.bin 大小 8k,是由三星提供的 BL1;

    E4412.BL2.TZ.SSCR.EVT1.1.bin+all00_padding.bin,总共16K,是由三星提供的 BL2;

    u-boot.bin 大小328k,是自个源码编译生成的,如果我们的源码不够328k,sdfuse_q/add_padding会自动补足(在Makefile中有一句@./sdfuse_q/add_padding),所以,u-boot.bin不管怎么编译,都是 328k;

 

至此,整个 u-boot 编译完成,生成的 u-boot-iTOP-4412.bin 可以直接写进 SD 卡里面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值