主要文件:build/core/Makefile
build/tools/releasetools/ota_from_target_files
第一階段:update原材料目錄生成,作爲第二階段的輸入。
build/core/Makefile +line 1118 ~ line 1311
中間目錄在:out/target/product/ginwave73_gb/obj/PACKAGING/target_files_intermediates/目錄下,名字爲:
ginwave73_gb-target_files-user.lizhiguo,生成的zip包爲:ginwave73_gb-target_files-user.lizhiguo.zip
$(zip_root)下面包含了:
RECOVERY目錄:kernel_ginwave73_gb.bin, ramdisk_recovery.bin, 還有一個RAMDISK的目錄,就是recovery/root的內容。
second, cmdline, base都是可選的。
FACTORY目錄:一個RAMDISK目錄,存放factory的目錄,可以生產ramdisk-factory.img
kernel, pagesize, second, cmdline, base可選。
沒有用到
BOOT目錄:一個RAMDISK目錄,存在root目錄下的內容,用於生產ramdisk.img
kernel_ginwave73_gb.bin, ramdisk.img
second, cmdline, base, pagesize, board,可選。
RADIO目錄: 沒有用到
SYSTEM目錄:將system目錄中的內容拷貝進去
DATA目錄:將data目錄內容拷貝進入
OTA/bin目錄:拷貝android-info.txt到OTA下,而將applypatch, applypatch_static, check_prereq, updater拷貝進OTA/bin。
例如:./ginwave73_gb/obj/EXECUTABLES/updater_intermediates/updater‘
META目錄:apkcrets.txt來自out/target/product/ginwave73_gb/obj/PACKAGING/apkcerts_intermediates/ginwave73_gb-apkcerts-user.lizhiguo.txt
otakeys.txt本來可以來自.../PACKAGING/ota_keys_intermediates/keys,但是這裏爲NULL。
生成misc_info.txt,這個文件包含的信息有:recovery_api_version, blocksize, boot_size, recovery_size, system_size
secro_size, userdata_size, tool_extensions, mkyaffs2_extra_flags。當然包含這些參數都是可選的。
所有目錄內容呈現於:
out/target/product/ginwave73_gb/obj/PACKAGING/target_files_intermediates/ginwave73_gb-target_files-user.lizhiguo$ ls
BOOT DATA FACTORY META OTA RECOVERY SYSTEM
接下來就是zip打包了:
@# Zip everything up, preserving symlinks
$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
返回ginwave73_gb-target_files-user.lizhiguo的上級目錄target_files_intermediates,打包生成ginwave73_gb-target_files-user.lizhiguo.zip
@# Run fs_config on all the system files in the zip, and save the output
$(hide) zipinfo -1 $@ | awk -F/ 'BEGIN { OFS="/" } /^SYSTEM\// {$$1 = "system"; print}' | $(HOST_OUT_EXECUTABLES)/fs_config > $(zip_root)/META/filesystem_config.txt
$(hide) (cd $(zip_root) && zip -q ../$(notdir $@) META/filesystem_config.txt)
生成 META/filesystem_config.txt 並將其加入到 zip 包中。該文件保存了 system 目錄下各目錄、文件的權限及 owner.
$ head META/filesystem_config.txt
system 0 0 755
system/usr 0 0 755
system/usr/srec 0 0 755
system/usr/srec/config 0 0 755
system/usr/srec/config/en.us 0 0 755
system/usr/srec/config/en.us/grammars 0 0 755
system/usr/srec/config/en.us/grammars/phone_type_choice.g2g 0 0 644
system/usr/srec/config/en.us/grammars/VoiceDialer.g2g 0 0 644
system/usr/srec/config/en.us/grammars/boolean.g2g 0 0 644
system/usr/srec/config/en.us/g2p 0 0 755
...
這裏,目錄由zipinfo –l提供, 而權限則由fs_config設定。
源碼位於build/tools/fs_config ,其中fs_config.c 包含一個頭文件:#include "private/android_filesystem_config.h"
這個文件(system/core/include/private/android_filesystem_config.h)以hardcoding的方式設定了android中各目錄的權限和屬主,
同時也包括system下各文件和目錄的權限和屬主。
注意:如果需要升級其它內容,比如bootloader, 則可以在這裏加入。
第二階段:運行python腳本
build/core/Makefile + line 1314 ~ line1342
name := $(TARGET_PRODUCT)
ifeq ($(TARGET_BUILD_TYPE),debug)
name := $(name)_debug
endif
name := $(name)-ota-$(FILE_NAME_TAG)
這裏可以看出,最後生成的ota upadte包名字這個,例如:ginwave73_gb-ota-user.lizhiguo.zip
INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip // 最終安裝的目錄是ginwave73_gb下。
$(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
採用默認的簽名密鑰,位於build/target/product/security,其中有很多簽名密鑰:
media.pk8 media.x509.pem platform.pk8 platform.x509.pem README shared.pk8 shared.x509.pem testkey.pk8 testkey.x509.pem
我們使用的是testkey。
$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS)// 這裏的依賴就是前面第一步中完成的工作。
@echo "Package OTA: $@"
$(hide) ./build/tools/releasetools/ota_from_target_files -v \
-n \
-p $(HOST_OUT) \
-k $(KEY_CERT_PAIR) \
$(BUILT_TARGET_FILES_PACKAGE) $@
接下來就會進入執行腳本ota_from_target_files了,我們先來看看這個腳本的各個參數的具體意思。
.PHONY: otapackage
otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
OTA升級包包括兩種:完全OTA升級包,增量OTA升級包
Given a target-files zipfile, produces an OTA package that installs
that build. An incremental OTA is produced if -i is given, otherwise
a full OTA is produced.該腳本的輸入時一個zip包,輸出就是一個OTA包了。
如果-i參數存在,那麼將會生成增量OTA包。
Usage: ota_from_target_files [flags] input_target_files output_ota_package
-b (--board_config) <file> // 過時,不再使用
Deprecated.
-k (--package_key) <key> // 簽名用的密鑰
Key to use to sign the package (default is "build/target/product/security/testkey").
-i (--incremental_from) <file> // 生成增量OTA包時用於定義對比包
Generate an incremental OTA using the given target-files zip as the starting build.
-w (--wipe_user_data) // 升級的時候會清除userdata分區
Generate an OTA package that will wipe the user data partition when installed.
-n (--no_prereq) // 有這個參數時在升級時不檢查時間戳;沒有這個參數時會檢查時間戳,此時只能基於老的向新的版本升級。
// 腳本中默認情況下是忽略檢查時間戳的。
Omit(忽略) the timestamp prereq check normally included at the top of
the build scripts (used for developer OTA packages which
legitimately need to go back and forth). // 用這個選項主要是爲了方便開發者前後升級
-e (--extra_script) <file> // 定義額外運行的腳本
Insert the contents of file at the end of the update script.
///////////// 可以指定對preloader.img, logo.img , uboot.img, dsp_bl.img進行升級 ///////
-r (--preloader) <file>
Specify 'preloader.img' to upgrade.
-l (--logo) <file>
Specify 'logo.img' to upgrade.
-u (--uboot) <file>
Specify 'uboot.img' to upgrade.
-d (--dsp) <file>
Specify 'dsp_bl.img' to upgrade.
///////////// 可以指定對preloader.img, logo.img , uboot.img, dsp_bl.img進行升級 ///////
-p (--path) <dir> // 定義腳本用到的一些可執行文件的路徑
Prepend <dir>/bin to the list of places to search for binaries
run by this script, and expect to find jars in <dir>/framework.
-s (--device_specific) <file>
Path to the python module containing device-specific releasetools code.
-x (--extra) <key=value> 定義額外運行的腳本可能用到的鍵/值對
Add a key/value pair to the 'extras' dict, which device-specific extension code may look at.
-v (--verbose)
Show command lines being executed.
-h (--help)
Display this usage message and exit.
綜上所述,重要的參數有-k, -i, -w, -n, (-l == logo , -r == preloader , -u == uboot, -d = dsp_bl)
那麼展開Makefile中調用ota_from_target_files腳本,如下:
./build/tools/releasetools/ota_from_target_files -v \
-n \
-p out/host/linux-x86 \
-k build/target/product/security/testkey \
out/target/product/ginwave73_gb/obj/PACKAGING/target_files_intermediates/ginwave73_gb-target_files-user.lizhiguo.zip out/target/product/ginwave73_gb/ginwave73_gb-ota-user.lizhiguo.zip
下面分析一下這個python腳本的代碼
首先可以看到腳本語句中設置的默認情況:
OPTIONS = common.OPTIONS
OPTIONS.package_key = "build/target/product/security/testkey" // 默認簽名用的密鑰
OPTIONS.incremental_source = None // 默認無增量源
OPTIONS.require_verbatim = set()
OPTIONS.prohibit_verbatim = set(("system/build.prop",))
OPTIONS.patch_threshold = 0.95
OPTIONS.wipe_user_data = False // 默認不會清除userdata
OPTIONS.omit_prereq = True // 默認不會進行時間戳比較
OPTIONS.extra_script = None
OPTIONS.worker_threads = 3
#wschen
OPTIONS.preloader = None // 可以看出這一部分是mtk加的
OPTIONS.uboot = None
OPTIONS.logo = None
OPTIONS.dsp = None
scatter_path = "mediatek/source/misc/ota_scatter.txt" // 默認的散列文件
WriteIncrementalOTAPackage()生成增量OTA包, 需要-i參數,加上對比包,這個對比包是前次的中間zip包。
WriteFullOTAPackage()生成完全OTA包
總結:
昨天說的OTA包的內容,之前我們都存在一些誤解,上午研究了下編譯OTA的過程,下面總結一下:
1. OTA包生成分兩步:
第一步生成輸入源目錄ginwave73_gb-target_files-user.lizhiguo,這裏面就放了將會進入OTA包的原始數據,其中包括一些目錄:
(這些目錄中的數據來源於./mk –t n 之後在out/target/product/ginwave73_gb/下的內容)
BOOT DATA FACTORY META OTA RECOVERY SYSTEM
其中以BOOT RECOVERY SYSTEM爲主;DATA和FACTORY沒有使用,可以對其配置;而META和OTA是一些升級的輔助工具。
可以看出主要升級的內容又boot.img, recovery.img, system.img
最後將其打包成ginwave73_gb-target_files-user.lizhiguo.zip,供第二步使用。
接着會調用一個python腳本ota_from_target_files,這個腳本以第一步的結果爲輸入,輸出的結果就是最終的OTA包:ginwave73_gb-ota-user.lizhiguo.zip
當然這個腳本還有一些重要的參數,mtk在原始的腳本文件中有做修改,加入了以下這些參數可以將u-boot之類的也加進入:
-r (--preloader) <file> Specify 'preloader.img' to upgrade.
-l (--logo) <file> Specify 'logo.img' to upgrade.
-u (--uboot) <file> Specify 'uboot.img' to upgrade.
-d (--dsp) <file> Specify 'dsp_bl.img' to upgrade.
但是,在MTK android的編譯環境中,並沒有加入這些img一起升級,要加的話我們可以自己修改。
另外一些中要參數有:
-i (--incremental_from) <file> // 生成增量OTA包時用於定義對比包
-w (--wipe_user_data) // 升級的時候會清除userdata分區
-n (--no_prereq) // 有這個參數時在升級時不檢查時間戳;沒有這個參數時會檢查時間戳,此時只能基於老的向新的版本升級。
// 腳本代碼中默認情況下是忽略檢查時間戳的。
目前的編譯系統內有加-n,忽略檢查時間戳,但是沒有-i和-w,就是說,目前我們編譯的都是完全OTA包,並沒有編譯過增量OTA包,也不會清楚userdata區域。
2. OTA包分完全OTA包和增量OTA包
完全OTA包就是相當於我們用工具下載那些img,不過其中只有boot.img完整,而system不是提供的img,而是一整個目錄;recovery.img是相對於boot.img的patch。
增量OTA包,需要在執行python腳本的時候加上-I <start_xxx.zip>作爲對比包,輸出就是兩個包之間的差異。
我們目前編譯出來的都是完全OTA包,裏面只包含了boot.img, recovery.img, system。
最後建議以後編譯出來的OTA包名字還是加上日期和項目名字,免得混淆,到時候給到用戶那邊的時候讓用戶在使用之間將名字修改爲update.zip就行。