zoukankan      html  css  js  c++  java
  • Lichee ( 四 ) 打包IMAGE

    在《Lichee(三) Android4.0的目标产品文件夹与Lichee的纽带---extract-bsp》中我们分析了extract-bsp的作用和意义。到这里,我们能够開始编译Android了

    运行 make -j8

    ………………

    漫长的等待之后。Android的目标文件都到了out文件夹,假设我们的目标产品名叫crane-mt7332


    out/target/product/crane-mt7332/

    ├── android-info.txt

    ├── boot.img

    ├── clean_steps.mk

    ├── data

    ├── installed-files.txt

    ├── kernel

    ├── obj

    ├── previous_build_config.mk

    ├── ramdisk.img

    ├── ramdisk-recovery.img

    ├── recovery

    ├── recovery.fstab

    ├── recovery.img

    ├── root

    ├── symbols

    ├── system

    ├── system.img

    └── userdata.img

    非常高兴,我们看到了非常多的.img文件。这些文件就是为了给我们打包做准备


    接下来,我们開始具体地分析Lichee的打包过程

    打包有2种方式。在lichee。Android中都能够完毕pack

    在lichee中运行

    $ ./build.sh pack就能够实现打包

    在 buildroot/scripts/common.sh中有:


    if [ "$1" = "pack" ]; then
            ${BR_DIR}/scripts/build_pack.sh
            exit 0
    fi

    这里环境变量BR_DIR=buildroot,事实上去运行buildroot/script/build_pack.sh


    变量赋值部分:

    LICHEE_ROOT=$PWD
    PACK_ROOT=tools/pack
    TARGET_CHIP="sun4i"
    TARGET_PLATFORM="linux"
    TARGET_BOARD="evb"
    count=0


     选择chip

    文件夹结构

        #tree -L 1 tools/pack/chips/

        #tools/pack/chips/

        #└── sun4i



    printf "Start packing for Lichee system
    
    "
    select_chips
    我们分析这个函数
    select_chips()
    {
        count=0
    
        printf "All valid chips:
    "
        # $PACK_ROOT/chips/ 就是 lichee/tools/pack/chips  
        #find -mindepth 1 -maxdepth 1 -type d |sort  意思是查找 lichee/tools/pack/chips中的全部文件夹。深度为1。也就是仅仅查找到chips这一级。不再往下查找子文件夹了
        #我们来tree一下 tools/pack/chips/ 这个文件夹。发现就仅仅有sun4i一个子文件夹
    
        for chip in $(cd $PACK_ROOT/chips/; find -mindepth 1 -maxdepth 1 -type d |sort); do
            chips[$count]=`basename $PACK_ROOT/chips/$chip`
            printf "$count. ${chips[$count]}
    "
            let count=$count+1
        done
        # 在这里读取我们的选择,并对输入的数据做验证
        while true; do
            read -p "Please select a chip:"
            RES=`expr match $REPLY "[0-9][0-9]*$"`
            if [ "$RES" -le 0 ]; then
                echo "please use index number"
                continue
            fi
            if [ "$REPLY" -ge $count ]; then
                echo "too big"
                continue
            fi
            if [ "$REPLY" -lt "0" ]; then
                echo "too small"
                continue
            fi
            break
        done
    
        TARGET_CHIP=${chips[$REPLY]}
    }

    我们来看看实际运行结果


    Start packing for Lichee system

    All valid chips:

    0. sun4i

    Please select a chip:0


    果然不出所料 仅仅有一个sun4i 说明我们前面的分析全然正确,这里我们输入 '0'


    选择平台


    运行命令

    select_platform $TARGET_CHIP


    文件夹结构

    tools/pack/chips/sun4i/configs/

    ├── crane

    ├── dragonboard

    ├── linux

    └── test



    select_platform()
    {
        count=0
        chip=$1
    
        printf "All valid platforms:
    "
        # 由于之前select_chips已经$TARGET_CHIP=sun4i 所以$chip=sun4i
        # 相似于select_chips,这里会find tools/pack/chips/sun4i/configs/的结果,以序号. 文件夹名的方式输出到终端,让用户选择
    
        for platform in $(cd $PACK_ROOT/chips/$chip/configs/; find -mindepth 1 -maxdepth 1 -type d |sort); do
            platforms[$count]=`basename $PACK_ROOT/chips/$chip/configs/$platform`
            printf "$count. ${platforms[$count]}
    "
            let count=$count+1
        done
    ……
    
        TARGET_PLATFORM=${platforms[$REPLY]}
    }


    运行结果

    All valid platforms:

    0. crane

    1. dragonboard

    2. linux

    3. test

    Please select a platform:0

    这么我们要打包的平台是Android 所以我们选择crane,输入 '0' 


    选择目标板

    select_boards $TARGET_CHIP $TARGET_PLATFORM

    文件夹结构

    tree -L 1 tools/pack/chips/sun4i/configs/crane/

    tools/pack/chips/sun4i/configs/crane/

    ├── 3g

    ├── aino

    ├── aino-aurora

    ├── bk7011

    ├── default

    ├── evb

    ├── evb_mmc

    ├── evb-v12r

    ├── evb-v13

    ├── m1003h6

    ├── m802h6

    ├── mid7042

    ├── MID9742-sc3052

    ├── t780 

    └── tvdevb


    select_boards()
    {
        count=0
        # 把我们选定的chip 和 platform 參数传进来
        chip=$1
        platform=$2
    
        printf "All valid boards:
    "
        # 依据传进来的參数 $PACK_ROOT/chips/$chip/configs/$platform/ 即  tools/pack/chips/sun4i/configs/crane 查找1级子文件夹 ,并排序
    
    
        for board in $(cd $PACK_ROOT/chips/$chip/configs/$platform/; find -mindepth 1 -maxdepth 1 -type d |grep -v default|sort); do
            boards[$count]=`basename $PACK_ROOT/chips/$chip/configs/$platform/$board`
            printf "$count. ${boards[$count]}
    "
            let count=$count+1
        done
    
    
    ……
    }

    到这里我们发现了我们打包缺少了一个非常重要的步骤,记得《Lichee(三) Android4.0的目标产品文件夹与Lichee的纽带---extract-bsp》我们lunch之后。会有自己的目标产品,通过上面的分析我们能够看出,我们必须在打包的时候在tools/pack/chips/sun4i/configs/crane文件夹下创建一个自己产品的文件夹,我们临时把evb-v13文件夹复制过来,改名为mt7332,关于mt7332目下的具体内容。后面会作为重点对象单独提出来分析


    运行pack


    cd $PACK_ROOT
    ./pack -c $TARGET_CHIP -p $TARGET_PLATFORM -b $TARGET_BOARD
    cd -


    当编译完毕后我们会运行一个pack命令。pack也是一个脚本。路径:lichee/tools/pack/pack。这是一个可运行的脚本文件(softwinner相同也提供了windows的打包工具),然后我们来看看pack到底干了些什么



    do_pack_crane()
    {
        printf "!!!Packing for crane!!!
    "
     
        if [ -z "$LICHEE_OUT" ]; then
            LICHEE_OUT=`cd ../../out; pwd`
        fi
     
        if [ -z "$CRANE_IMAGE_OUT" ]; then
            echo "please specify CRANE_IMAGE_OUT env"
            exit 1
        fi
         #拷贝全部的fex cfg文件到out文件夹
        cp -v chips/$PACK_CHIP/configs/$PACK_PLATFORM/default/* out/
        cp -v chips/$PACK_CHIP/configs/$PACK_PLATFORM/$PACK_BOARD/*.fex out/ 2>/dev/null
        cp -v chips/$PACK_CHIP/configs/$PACK_PLATFORM/$PACK_BOARD/*.cfg out/ 2>/dev/null
        #cp  -v (verbose)选项。cp命令将告诉用户正在做什么。

    #2>/dev/null 就是当出错的时候,重定向到/dev/null。也就是不向中断输出出错时候的信息 # modify the debug opt if [ $PACK_CHIP = sun4i ]; then #由于A10有2个能够复用的UART0 假设运行命令是 ./pack -c sun4i -p crane -b mt7332 -d card0,就表示将串口内容输出到card0 #由于我们使用默认的PB22 PB23,所以我们的运行命令时./pack -c sun4i -p crane -b mt7332 -d uart0 if [ $PACK_DEBUG = card0 ]; then cp $TOOLS_DIR/awk_debug_card0 out/awk_debug_card0 TX=`awk '$0~"a10"{print $2}' pctools/linux/card_debug_pin` RX=`awk '$0~"a10"{print $3}' pctools/linux/card_debug_pin` sed -i s'/uart_debug_tx =/uart_debug_tx = '$TX'/g' out/awk_debug_card0 sed -i s'/uart_debug_rx =/uart_debug_rx = '$RX'/g' out/awk_debug_card0 sed -i s'/uart_tx =/uart_tx = '$TX'/g' out/awk_debug_card0 sed -i s'/uart_rx =/uart_rx = '$RX'/g' out/awk_debug_card0 awk -f out/awk_debug_card0 out/sys_config1.fex > out/a.fex rm out/sys_config1.fex mv out/a.fex out/sys_config1.fex echo "uart -> card0 !!!" fi fi #将boot0.bin boot1.bin bootfs.ini diskfs.fex复制到fex文件夹下 cp -rf eFex/split_xxxx.fex eFex/card/mbr.fex eGon/storage_media/nand/boot0.bin eGon/storage_media/nand/boot1.bin wboot/bootfs wboot/bootfs.ini wboot/diskfs.fex out/ cp -rf eGon/storage_media/sdcard/boot0.bin out/card_boot0.fex cp -rf eGon/storage_media/sdcard/boot1.bin out/card_boot1.fex cp -v chips/$PACK_CHIP/configs/$PACK_PLATFORM/$PACK_BOARD/drv_de.drv out/bootfs/ 2>/dev/null cd out/ # 拷贝uboot 运行cp -v $LICHEE_OUT/u-boot.bin bootfs/linux/u-boot.bin do_copy_u_boot sed -i 's/\bootfs//bootfs/g' bootfs.ini sed -i 's/\\///g' image.cfg sed -i 's/imagename/;imagename/g' image.cfg if [ $PACK_DEBUG = card0 ]; then IMG_NAME="${PACK_CHIP}_${PACK_PLATFORM}_${PACK_BOARD}_$PACK_DEBUG.img" else IMG_NAME="${PACK_CHIP}_${PACK_PLATFORM}_${PACK_BOARD}.img" fi echo "imagename = $IMG_NAME" >> image.cfg echo "" >> image.cfg # sys_config.fex和sys_config1.fex文件事实上就是 tools/pack/chips/sun4i/configs/crane/mt7332文件夹以下的配置,sys_config1.fex主要配置CPU频率、外设、GPIO等。 sys_config.fex主要用来配置分区 # unix2dos 将unix转为dos的文件方式。最基本的就是换行不同 busybox unix2dos sys_config.fex busybox unix2dos sys_config1.fex script sys_config.fex script sys_config1.fex update_23 sys_config1.bin boot0.bin boot1.bin update_23 sys_config1.bin card_boot0.fex card_boot1.fex SDMMC_CARD cp sys_config1.bin bootfs/script0.bin cp sys_config1.bin bootfs/script.bin update_mbr sys_config.bin mbr.fex 4 16777216 fsbuild bootfs.ini split_xxxx.fex # get bootloader.fex mv bootfs.fex bootloader.fex # get env.fex u_boot_env_gen env_mmc.cfg env_mmc.fex u_boot_env_gen env_nand.cfg env_nand.fex cat env_mmc.fex >> env_nand.fex cp env_nand.fex env.fex # get other images from android build ln -s $CRANE_IMAGE_OUT/boot.img boot.fex ln -s $CRANE_IMAGE_OUT/system.img system.fex ln -s $CRANE_IMAGE_OUT/recovery.img recovery.fex # checksum for all fex FileAddSum bootloader.fex vbootloader.fex FileAddSum env.fex venv.fex FileAddSum boot.fex vboot.fex FileAddSum system.fex vsystem.fex FileAddSum recovery.fex vrecovery.fex #依据 image.cfg 用dragon来打包,生成最后的img文件 dragon image.cfg if [ -e ${IMG_NAME} ]; then mv ${IMG_NAME} ../${IMG_NAME} echo '---------image is at-------------' echo -e '33[0;31;1m' echo ${ROOT_DIR}/${IMG_NAME} echo -e '33[0m' fi cd - 1>/dev/null }


     ./pack -c sun4i -p crane -b mt7332 -d uart0

     


     ./pack -c sun4i -p crane -b mt7332 -d card0




        小贴士:

    awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。

    数据能够来自标准输入、一个或多个文件,或其他命令的输出。它支持用户自己定义函数和动态正則表達式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用。但很多其他是作为脚本来使用。


       awk的处理文本和数据的方式:它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。假设没有指定处理动作。则把匹配的行显示到标准输出(屏幕),假设没有指定模式,则全部被操作所指定的行都被处理。
       awk分别代表其作者姓氏的第一个字母。由于它的作者是三个人。各自是Alfred AhoPeter WeinbergerBrian Kernighan

       gawkawkGNU版本号,它提供了Bell实验室和GNU的一些扩展。

    以下介绍的awk是以GUNgawk为例的,在linux系统中已把awk链接到gawk,所以以下全部以awk进行介绍。




    本文主要是对于pack的过程进行了分析,对于do_pack_crane的分析比較浅显。由于这个脚本的关键内容。诸如update_23,  update_mbr, dragon 等,我们无法看到源码。打包固件的过程本来就是比較复杂的,可是我们对Lichee的主要架构已经非常清晰了,通过对脚本的分析。我们知道了在tools/pack/chips/sun4i/configs/crane文件夹下必须创建我们自己产品的文件夹,否则就无法打包


查看全文
  • 相关阅读:
    java获取指定文件夹下的所有文件名
    org.dom4j.DocumentException: unknown protocol: d Nested exception: unknown
    如何在spring中获取request对象
    Java获取文件后缀名
    解析XML并将信息封装到对象中
    在web项目启动时执行某个方法
    Maven Dependencies没有了的解决办法
    B-树(B+树) 学习总结
    Netty学习笔记之一(Netty解析简单的Http Post Json 请求)
    用到的设计模式总结--单例模式+工厂方法模式+Builder模式
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10476001.html
  • Copyright © 2011-2022 走看看