Android 5.0開始,ota包採用了一種新的system.img的壓縮方式。對於這種方式,如果是完整地升級,在ota的zip包中放的基本上就是一個ext4格式的image,但是它不是完整的ext4鏡像,而是一個扣除了很多全零信息的包。如果是針對一個基礎鏡像做差值得到的差量包,也可以用這種方式進行稀疏描述。
這裏主要介紹如何從system的源目錄生成最後的ota的zip包。對於從ota包中解包得到文件的方式可以參見我的另一篇博文:Android5.0的更新包中system.new.dat文件的解包。http://blog.csdn.net/howellzhu/article/details/41967523
如果想生成一個ota完整包,一般會放置boot、system以及其他一些image,後面的一般跟設備有關,比如radio,slb等。Boot的生成其實也跟設備相關,比如有的需要dt(device tree)什麼的。這裏主要介紹一下system的打包:如何生成system.new.dat等文件。
1. 第一步,利用system目錄和file_contexts生成system.img
其實製作system.img非常簡單簡單,請參考另一篇博文:android中system.img的打包過程。
http://blog.csdn.net/howellzhu/article/details/42804191
2.利用system.img得到system.new.dat、system.patch.dat和system.transfer.list文件
這是本文的重點。
這個過程的主要目的是降低ota.zip的大小,將system.img轉換成爲稀疏數組描述。
我們先看看android的源代碼工具是如何工作的。
在blockimgdiff.py文件中,blockimgdiff.py:BlockImageDiff::WriteTransfers()函數中,會將self.transfers中的所有xf寫入transfer.list文件中。
參見如下的調用棧:
[call stack]
build/tootls/releasetools/blockimgdiff.py:BlockImageDiff::ComputePatches&BlockImageDiff::WriteTransfers
build/tootls/releasetools/blockimgdiff.py:BlockImageDiff::Compute
build/tootls/releasetools/common.py:BlockDifference::__init__
build/tootls/releasetools/ota_from_target_files:WriteFullOTAPackage
build/tootls/releasetools/ota_from_target_files:main()
/build/core/Makefile:$(INTERNAL_OTA_PACKAGE_TARGET):$(BUILT_TARGET_FILES_PACKAGE) $(DISTTOOLS)
其實BlockImageDiff的是一個sparse_img.SparseImage對象和一個None對象。
用下面的img2sdat.py腳本就可以在當前目錄下生成system.new.dat、system.transfer.list和空的system.patch.dat文件:
</pre><pre name="code" class="python">#!/usr/bin/env python
import sys
import blockimgdiff
import sparse_img
from rangelib import *
def main(argv):
tgt = sparse_img.SparseImage("system.img");
bif = blockimgdiff.BlockImageDiff(tgt, None)
bif.Compute("system")
if __name__ == '__main__':
main(sys.argv[1:])
爲了簡化工作,我將上述的一些python腳本進行打包,形成一個python包文件:img2sdat.zip,並提供在文章最後提到的mkotazip工具包中。利用該包對system.img的處理就非常簡單了,就是如下的命令:
$ python img2sdat.zip
這樣就會在當前目錄下生成system.new.dat、system.patch.dat和system.transfer.list文件。
3. 準備升級腳本文件和升級執行文件
升級執行文件由Android提供,名字是update-binary,需要放在壓縮包中如下目錄:META-INF/com/google/android
爲了方便,我已經將該文件打包在最後提到的壓縮文件中了。
另一個文件就是自己要編寫修改的updater-script腳本文件了,也需要放在壓縮包中和update-binary一個目錄。這裏提供一個hammerhead的參考:
show_progress(0.05, 0);
getprop("ro.product.device") =="hammerhead" || abort("This package is for\"hammerhead\" devices; this is a \"" +getprop("ro.product.device") + "\".");
show_progress(0.75, 10);
block_image_update("/dev/block/platform/msm_sdcc.1/by-name/system",package_extract_file("system.transfer.list"),"system.new.dat", "system.patch.dat");
show_progress(0.20, 2);
package_extract_file("boot.img","/dev/block/platform/msm_sdcc.1/by-name/boot");
4. 將上面準備的文件打包生成一個zip文件。
這一步非常簡單,利用zip、minizip或者7zip等工具都可以實現。爲了方便,在mkotazip工具中提供了一個install.sh腳本,將前面生成的那些文件放到合適的目錄下,然後打包。該腳本接受一個參數,即存放ota包的目的目錄。如果不指定,在當前目錄下新建一個otazip目錄,然後作爲目標目錄。
5.對該zip文件進行簽名[可選]
這部分內容就不說了,網上有很多類似的文章。
總結一下上面的步驟。
1. 下載博文中提到的工具包mkotazip.zip(下載地址參見文章最後)解壓;
2. 利用mkext4_fs工具生成system.img;
3. 利用命令python img2sdat.zip得到system.new.dat等文件;
4. 修改updater-script文件;
5. 運行install.sh腳本,生成ota.zip文件。
Ok
附錄:mkotazip.zip文件: