以前須要處理一些應用程序用到的update相關問題, 瞭解到android build system會利用開源的bsdiff進行一些關於package的更新動做. 這篇文章就分析一下android系統的OTA update.node
首先,讓咱們來看看OTA的總體框架
Build System Support, 用來建立須要的OTA update image(包括所有更新及部分更新)
Releasetools (build/tools/releasetools/)
用以與build system配合,生成對應的full/incremental的update.zip包
對應的編譯腳本在build/core/main.mk及Makefile, 搜索target-files-package關鍵字
build/tools/releasetools
├── check_target_files_signatures -- 用來檢查cert和update包之間的關係
├── common.py -- 各類工具類,參數處理/META文件處理/image生成/sign certification/patch file 操做等等
├── edify_generator.py -- 用來生成edify腳本, 關於edify,參照bootable/recovery/edify/下的readme及tjworld,
主要是給manufacturer提供一個簡單的shell語言 來進行必要的recovery操做. 後面會單獨寫篇文章單獨描述一下edify的使用方法
<Android學習之edify是神馬>
├── img_from_target_files -- 由生成target zip file的製做被fastboot update命令所使用的xxx.img文件
├── ota_from_target_files -- 生成通過各類簽名的TFP更新包
└── sign_target_files_apks -- 用來對apk或者生成測zip更新包進行簽名, 參照/development/pdk/docs/porting/release_keys.jdhttp://androidxref.com/source/xref/development/ 中的描述
方便把test-key轉換成OEM廠商的release keylinux
使用make target-files-package來編譯update.zip, 生成的描述及image文件在
out/target/product/generic/obj/PACKAGING/apkcerts_intermediates/full-apkcerts-eng.txt
out/target/product/generic/obj/PACKAGING/target_files_intermediates/full-target_files-eng.zipandroid
這裏須要注意以上都是針對已經經過mkimage(system/core/mkbootimg)的工具生成了boot.img以後,來生成對應的recovery及update image.
上訴工具都不提功boot.img和update image之間的交互操做, 因此在製做update image時,要手動確保你製做的update image可以被安裝在預先已經有boot image的device上!!!shell
同時, 這裏提供了給OEM的擴展接口, 可使得OEM定義一些特有的操做, 並融合到update過程中. 能夠參照資料3的15頁的描述, 詳細的狀況推薦參考CyanogenMod中nexus one中的以下實現:
CyanogenMod/device/htc/passion-common/BoardConfigCommon.mk中releasetools的擴展定義:TARGET_RELEASETOOLS_EXTENSIONS := device/htc/common
CyanogenMod/device/htc/common/updater/ -- 是OEM各自的updater實現
CyanogenMod/device/htc/common/releasetools.py -- 裏面都是一些必需要實現extension 接口, 如,FullOTA_Assertions()/FullOTA_InstallEnd()等app
下圖簡要描述了下update.zip的生成過程框架
這裏請注意, re-sign apks是爲了apk的security, 用各個oem廠商的簽名替代Test的簽名.
簽名是使用openssl生成的帶public exponent 3 的 2048-bit RSA keys.ide
Related filesystem partition
談到Update,不得不提到android的分區狀況(參見各個OEM的配置)
boot, 包含如下文件:metadata, kernel image, ramdisk, optional 2nd-stage bootloader image, 由mkbooting(system/core/mkbooting)生成
關於boot.img的格式參見system/core/mkbooting/bootimg.h
[plain]
/*
** +-----------------+
** | boot header | 1 page
** +-----------------+
** | kernel | n pages
** +-----------------+
** | ramdisk | m pages
** +-----------------+
** | second stage | o pages
** +-----------------+
**
** n = (kernel_size + page_size - 1) / page_size
** m = (ramdisk_size + page_size - 1) / page_size
** o = (second_size + page_size - 1) / page_size
**
** 0. all entities are page_size aligned in flash
** 1. kernel and ramdisk are required (size != 0)
** 2. second is optional (second_size == 0 -> no second)
** 3. load each element (kernel, ramdisk, second) at
** the specified physical address (kernel_addr, etc)
** 4. prepare tags at tag_addr. kernel_args[] is
** appended to the kernel commandline in the tags.
** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
** 6. if second_size != 0: jump to second_addr
** else: jump to kernel_addr
*/
這個描述,在須要本身定製本身的rom,或者須要把本身編譯的kernel燒錄到手機上時,頗有用. 參見<如何製做android nexus one的內核>函數
system, 系統程序及apk等等
data, 用戶數據, 會被factory reset clear
recovery, 爲了恢復
misc, 包含Bootloader Control Block (BCB), recovery console經過它與bootloader交互
cache, 用來支持update的temp分區,及被特定apk做爲temp來使工具
還有一個重要的文件recovery.fstab, 用來爲recovery console及releasetools提供可以加載的文件系統及對應的mount node
以下是nexus one的recovery.fstab
[plain]
# mount point fstype device [device2]
/boot mtd boot
/cache yaffs2 cache
/data yaffs2 userdata
/misc mtd misc
/recovery mtd recovery
/sdcard vfat /dev/block/mmcblk0p1 /dev/block/mmcblk0
/system yaffs2 system
/sd-ext ext4 /dev/block/mmcblk0p2 學習
注:這個recovery.fstab在生成的out/target/product/generic/obj/PACKAGING/target_files_intermediates/full-target_files-eng.zip包中recovery目錄下可以看到。
Device Side Support, 用來接收update image並經過recovery模式來更新
全部的代碼都在/bootable/recovery, 固然仍是參照CyanogeMod中的代碼與真正的device比較接近.
由於這時,實際上是一個徹底獨立的小系統, 須要有本身的各類工具函數庫(不能使用linux,由於這時linux根本還沒開始運行, 這裏只是一個簡單軟硬件交互環境).
從中能夠看到不少關於裁剪定製的例子.
後面會寫一篇專門分析andorid的bootloader和recovery的分析的文章,請參看<Android學習之bootloader>, <Android學習之recovery>
Recovery Console (RC)
這就是經過開機時,按住指定的鍵進入的recovery UI界面(常常刷機的,應該很熟悉)
是全部其它recovery工做的總入口, 管理全部recovery工做及與bootloader,framework中的RecoverySystem交互
這裏從nexus one中的實現與AOSP的實現能夠看出, 大部分廠商都提供了本身的RC UI plugin從而做出各自的recovery UI.
參考資料5中的26頁給出了簡單更改Console UI的方法:)
bootloader
用來幫助硬件初始化資源並更根據要求選擇進入RC仍是Andorid系統
它除了跟RC交互,還會經過BCB接受從kenrel來的reboot notification(register_reboot_notifier()).
misc分區及其中的BCB
用來提供RC和bootloader之間的通訊環境及命令
Updater
它會包含在OTA update.zip文件之中, 由recovery console控制執行具體的update動做(包括驗證, 解壓, 安裝)
一樣也提供了plugin的擴展機制, 容許各個廠商定製一些額外的updater動做
SW Update UI intent from Settings application
代碼在
RecoverySystem APIs
參考資料:
http://tjworld.net/wiki/Android/UpdaterScriptEdifyFunctions -- edify介紹
https://events.linuxfoundation.org/images/stories/pdf/lf_abs12_boie.pdf