在《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\n\n"
select_chips
我们分析这个函数
select_chips()
{
count=0 printf "All valid chips:\n"
# $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]}\n"
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:\n"
# 由于之前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]}\n"
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:\n"
# 依据传进来的參数 $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]}\n"
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!!!\n" 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 '\033[0;31;1m'
echo ${ROOT_DIR}/${IMG_NAME}
echo -e '\033[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 Aho、Peter Weinberger、Brian
Kernighan。

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

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


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

Lichee ( 四 ) 打包IMAGE的更多相关文章

  1. Java学习笔记四---打包成双击可运行的jar文件

    写笔记四前的脑回路是这样的: 前面的学习笔记二,提到3个环境变量,其中java_home好理解,就是jdk安装路径:classpath指向类文件的搜索路径:path指向可执行程序的搜索路径.这里的类文 ...

  2. conan使用(四)--打包二进制库

    前面总结过如何打包一个存头文件库,那种情况下非常简单,因为只需要将源文件拷贝就行了.现在来研究下如何打包一个正常情况下会生成动态库或静态库的包.参考文档:https://docs.conan.io/e ...

  3. 实用maven笔记四-打包&其他

    通过使用maven的生命周期和丰富多样的插件,可以方便的将项目代码编译打包为自己需要的构件. maven默认项目主代码位置src/main/java目录,测试代码位置src/test/java目录.主 ...

  4. 第五十六篇:webpack的loader(四) -打包js中的高级语法

    好家伙, 1.打包处理js文件中的高级语法 webpack只能打包处理一部分高级的JavaScript 语法.对于那些webpack无法处理的高级js 语法,需要借 助于 babel-loader 进 ...

  5. Electron桌面应用打包流程

    一. 准备工作 1.npm的安装需要下载node.js,安装完node.js之后npm自然会有. 参考链接:http://www.runoob.com/nodejs/nodejs-install-se ...

  6. iOS自动化打包上传的踩坑记

    http://www.cocoachina.com/ios/20160624/16811.html 很久以前就看了很多关于iOS自动打包ipa的文章, 看着感觉很简单, 但是因为一直没有AppleDe ...

  7. maven打包war,导入本地jar包

    方法1: 一 . 在项目根目录创建lib文件夹,把jar放入lib文件夹中 二 . 在项目中使用本地jar pom文件配置如下: <properties> <project.buil ...

  8. Python抖音视频去水印,并打包成exe可执行文件

    前言 抖音里面的视频保存之后,会发现全都带有水印,所以如何解决视频去除水印就很有必要,所以教程来了,本次教程不仅会教大家如何去除视频里的水印,并且教大家将程序制作成exe可执行文件,可以发给你的好友使 ...

  9. Sharepoint创建List

    (一)在一个环境下创建site 首先在sharepoint 2013 Central Administration中run administration --Application Managemen ...

随机推荐

  1. [Ceoi2010]Pin

    #2012. [Ceoi2010]Pin Online Judge:Bzoj-2012 Label:容斥,STL 题目描述 给出N(2<=N<=50000)个长度为4的字符串,问有且仅有D ...

  2. Leetcode965. Univalued Binary Tree单值二叉树

    如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树. 只有给定的树是单值二叉树时,才返回 true:否则返回 false. 示例 1: 输入:[1,1,1,1,1,null,1] 输出:tr ...

  3. Lombock原理

    说道Lombok,可能会鲜为人知.但是在实际的开发中,它起到了很大的作用,话不多说,直入正题: 一.Lombok是什么 现在看一下Lombok官方对其进行的解释:Lombok官网:https://pr ...

  4. Kafka在window上安装部署

    1.准备工作   ①jdk 具体自行百度安装jdk,配置好 JAVA_HOME和path, 下载地址:   http://www.oracle.com/technetwork/java/javase/ ...

  5. NVIDIA驱动安装、CUDA安装、cudnn安装

    1.禁用 nouveau 驱动 sudo vim /etc/modprobe.d/nvidia-installer-disable-nouveau.conf 或者 sudo vim /etc/modp ...

  6. Ionic 选择图片上传

    1.添加插件 1.1 安装ngcordova 1.2 安装选择图片插件 1.3 安装上传插件 1.4查看安装插件集合 2.html 代码 <div class="item item-i ...

  7. HDU 6003 Problem Buyer

    贪心题(好久不做了) 题解 考虑最一般的,判断合法性? 经典贪心问题:左端点升序,左端点相同,右端点降序,c[i]升序 优先队列,每次选择覆盖x的右端点最小的区间. 称此方法为“区间匹配贪心” 最小的 ...

  8. 矩阵快速幂2 3*n铺方格

    #include <iostream> #include <cstdlib> #include <cstring> #include <queue> # ...

  9. STL中的unique()和lower_bound ,upper_bound

    unique(): 作用:unique()的作用是去掉容器中相邻元素的重复元素(数组可以是无序的,比如数组可以不是按从小到大或者从大到小的排列方式) 使用方法:unique(初始地址,末地址): 这里 ...

  10. T2487 公交司机(搜索题)(小L的一生)

    https://www.luogu.org/problem/show?pid=T2487 题目背景 小L那没出息的儿子当上了一个公交司机. 题目描述 每个司机都有一个牌子,牌子的正面标出了这个司机所开 ...