android2.3.4 OTA包的生成研究

641人閱讀評論(0)收藏舉報
     版本:android2.3.4
主要文件: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就行。

發佈了9 篇原創文章 · 獲贊 2 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章