在《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. 2018-8-10-WPF-鼠标移动到列表上-显示列表图标

    title author date CreateTime categories WPF 鼠标移动到列表上 显示列表图标 lindexi 2018-08-10 19:16:51 +0800 2018-2 ...

  2. 基于在树上走的DP问题

    笔者已经很久没有打过题解了,如果打题解,就总是要连着一个知识点来打题解. 最近做过一共两道这样的题目.笔者认为这样的题有较强的可拓展性,比较有意义. 所以就打一篇博客. 问题概述 先说说这是个什么样的 ...

  3. nextjs服务端渲染原理

    1. 简单的介绍一下 nextjs是react进行服务端渲染的一个工具,默认以根目录下的pages为渲染路由 比如我在pages目录下创建一个index.js文件,然后export default一个 ...

  4. Schedule(Hackerrank Quora Haqathon)

    题目链接 Problem Statement At Quora, we run all our unit tests across many machines in a test cluster on ...

  5. PAT甲级——A1046 Shortest Distance

    The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed t ...

  6. 左神算法书籍《程序员代码面试指南》——1_10最大值减去最小值小于或等于num的子数组数量

    [题目]给定数组arr和整数num,共返回有多少个子数组满足如下情况:max(arr[i.j]) - min(arr[i.j]) <= num max(arfi.j])表示子数组ar[ij]中的 ...

  7. tensorflow object detection faster r-cnn 中keep_aspect_ratio_resizer是什么意思

    如果小伙伴的英语能力强可以直接阅读这里:https://stackoverflow.com/questions/45137835/what-the-impact-of-different-dimens ...

  8. chown权限命令

    chown 命令用途更改与文件关联的所有者或组. 语法chown[  -f ] [ -h] [  -R ] Owner [ :Group ] { File ... | Directory ... } ...

  9. UVA1416/LA4080 Warfare And Logistics

    题目大意:有N个点,M条路,如果两条路不连通的话,就将这两条路的距离设置为L 现在要求你求出每两点之间的最短距离和 接着要求 求出炸断 给出的M条路中的一条路后,每两点之间的最短距离和的最大值(翻译来 ...

  10. UVA11021 Tribbles

    题目大意:n个麻球,第一天有k个,麻球生命期为一天,临近死亡前会有i的几率生出Pi个麻球.问m天后麻球全部死亡概率 设f[i]表示i天后一个麻球全部死亡的概率 有f[1] = P0 f[i] = P0 ...