Android recovery更新簡單流程及注意點
關於recovery更新相關的幾點總結記錄:
1、recovery升級的大致流程:
①編譯:執行make otapackage
②.main system模式下,將升級包重名為update.zip,下載到/cache目錄下
③.建立檔案/cache/recovery/command,並向command中寫入:--update_package=/cache/update.zip
④終端執行reboot recovery進入recovery模式,也可以通過android上層調用函數android_reboot,並設定進入recovery模式的代碼
⑤.系統重啟,進入recovery模式,並啟動recovery進程,該進程會檢測/cache/recovery/command的內容,然後升級update.zip。
2、命令檔案/cache/recovery/command:儲存著Mainsystem傳給Recovery的命令列,每一行就是一條命令,支援一下幾種的組合。
--send_intent=anystring //write the text out to recovery/intent 在Recovery結束時在finish_recovery函數中將定義的intent字串作為參數傳進來,並寫入到/cache/recovery/intent中
--update_package=root:path //verify install an OTA package file Main system將這條命令寫入時,代表系統需要升級,在進入Recovery模式後,將該檔案中的命令讀取並寫入BCB中,然後進行相應的更新update.zip包的操作。
--wipe_data //erase user data(and cache),then reboot。擦除使用者資料。擦除data分區時必須要擦除cache分區。
--wipe_cache //wipecache(but not user data),then reboot。擦除cache分區。
3、recovery時分區相關需要與system主模式的分區號一致
位置:bootable/bootloader/uboot-imx/include/autoconf.mk
CONFIG_ANDROID_CACHE_PARTITION_MMC=12
CONFIG_ANDROID_RECOVERY_PARTITION_MMC=6
CONFIG_ANDROID_SYSTEM_PARTITION_MMC=5
CONFIG_ANDROID_RECOVERY_CMD_FILE="/recovery/command"
4、bootable/recovery/recovery.c修改
#LOCAL_MODULE_TAGS := eng
如果放開這行,將只會在eng版本軟體中有copy到/system/bin的動作
5、build/core/Makefile修改
$(INTERNAL_OTA_PACKAGE_TARGET):$(BUILT_TARGET_FILES_PACKAGE) $(DISTTOOLS)
@echo "Package OTA: $@"
$(hide) ./build/tools/releasetools/ota_from_target_files -v \
-p $(HOST_OUT) \
-k $(KEY_CERT_PAIR) \
-n \
-w \
-n在升級時是否不檢查時間戳記,預設要檢查,即預設情況下只能基於舊版本升級
-w是否清除userdata分區
註:如果/cache/recovery/last_log中出現如下錯誤則說明升級包較舊導致終止執行,可以加上上面說的-n項
assert failed: !less_than_int(1397801920,getprop("ro.build.date.utc"))
6、recovery的log檔案放在/cache/recovery/
last_install
last_locale:上次recovery使用的語言,如在更新時介面顯示的提示的語種,英語、日語等
last_log:log
7、檢測命令檔案/cache/recovery/command函數是int check_recovery_cmd_file(void)在如下檔案中定義
"bootable/bootloader/uboot-imx/board/freescale/mx6q_sabresd/mx6q_sabresd.c"
8、recovery升級最終是通過執行updater-script指令碼來進行的。下面是部分注釋供參考。
- assert(getprop("ro.product.device") == "sabresd_6dq" ||
- getprop("ro.build.product") == "sabresd_6dq");
- //show_progress(frac,sec):frac表示進度完成的數值,sec表示整個過程的總秒數。主要用與顯示UI上的進度條。
- show_progress(0.500000, 0);
- //format(fs_type,partition_type,location):fs_type,檔案系統類型,取值一般為“yaffs2”或“ext4”。Partition_type,分區類型,一般取值為“MTD”或則“EMMC”。主要用于格式化為指定的檔案系統。
- format("ext4", "EMMC", "/dev/block/mmcblk0p5", "0", "/system");
- //掛在一個檔案系統/system到指定掛載點mmcblk0p5
- mount("ext4", "EMMC", "/dev/block/mmcblk0p5", "/system");
- //package_extract_dir(src_path,destination_path):src_path,要提取的目錄,destination_path目標目錄。作用:從升級包內,提取目錄到指定的位置。
- package_extract_dir("recovery", "/system");//提取recovery
- package_extract_dir("system", "/system");//提取system
- //建立符號連結
- symlink("Roboto-Bold.ttf", "/system/fonts/DroidSans-Bold.ttf");
- symlink("Roboto-Regular.ttf", "/system/fonts/DroidSans.ttf");
- symlink("mksh", "/system/bin/sh");
- symlink("toolbox", "/system/bin/cat", "/system/bin/chmod",
- "/system/bin/chown", "/system/bin/cmp", "/system/bin/cp",
- "/system/bin/date", "/system/bin/dd", "/system/bin/df",
- "/system/bin/dmesg", "/system/bin/du", "/system/bin/getevent",
- "/system/bin/getprop", "/system/bin/grep", "/system/bin/hd",
- "/system/bin/id", "/system/bin/ifconfig", "/system/bin/iftop",
- "/system/bin/insmod", "/system/bin/ioctl", "/system/bin/ionice",
- "/system/bin/kill", "/system/bin/ln", "/system/bin/log",
- "/system/bin/ls", "/system/bin/lsmod", "/system/bin/lsof",
- "/system/bin/md5", "/system/bin/mkdir", "/system/bin/mount",
- "/system/bin/mv", "/system/bin/nandread", "/system/bin/netstat",
- "/system/bin/newfs_msdos", "/system/bin/notify", "/system/bin/printenv",
- "/system/bin/ps", "/system/bin/reboot", "/system/bin/renice",
- "/system/bin/rm", "/system/bin/rmdir", "/system/bin/rmmod",
- "/system/bin/route", "/system/bin/schedtop", "/system/bin/sendevent",
- "/system/bin/setconsole", "/system/bin/setprop", "/system/bin/sleep",
- "/system/bin/smd", "/system/bin/start", "/system/bin/stop",
- "/system/bin/sync", "/system/bin/top", "/system/bin/touch",
- "/system/bin/umount", "/system/bin/uptime", "/system/bin/vmstat",
- "/system/bin/watchprops",
- "/system/bin/wipe");
- //設定檔案或目錄許可權
- set_perm_recursive(0, 0, 0755, 0644, "/system");
- set_perm_recursive(0, 2000, 0755, 0755, "/system/bin");
- set_perm(0, 3003, 02750, "/system/bin/netcfg");
- set_perm(0, 3004, 02755, "/system/bin/ping");
- set_perm(0, 2000, 06750, "/system/bin/run-as");
- set_perm(1002, 1002, 0440, "/system/etc/dbus.conf");
- set_perm(1014, 2000, 0550, "/system/etc/dhcpcd/dhcpcd-run-hooks");
- set_perm(0, 2000, 0550, "/system/etc/init.goldfish.sh");
- set_perm(0, 0, 0544, "/system/etc/install-recovery.sh");
- set_perm_recursive(0, 0, 0755, 0555, "/system/etc/ppp");
- set_perm_recursive(0, 2000, 0755, 0644, "/system/vendor");
- set_perm(0, 0, 0644, "/system/vendor/etc/audio_effects.conf");
- set_perm_recursive(0, 2000, 0755, 0755, "/system/xbin");
- show_progress(0.200000, 0);
- show_progress(0.200000, 10);
- //將升級包中的boot.img檔案寫入到/dev/block/mmcblk0p1
- package_extract_file("boot.img", "/dev/block/mmcblk0p1");
- show_progress(0.100000, 0);
- unmount("/system");
9、updater-script指令碼是從python指令碼build/tools/releasetools/ota_from_target_files中產生的。
10、更新時的圖片顯示是在/android4.2-imx6/bootable/recovery/res/images下面
11、Android recovery模式時介面顯示的文字是從png文本圖片中讀取的。目錄也是在/android4.2-imx6/bootable/recovery/res/images
如果要顯示文字是需要從上層傳遞locale變數的。如果沒有設定或者不知如何設定(我就不知),可以直接修改bootable/recovery/recovery.cpp檔案中locale 定義時賦予初始值,如下表示英語_英國
char* locale = "en_GB"