美文网首页
高可靠OTA升级

高可靠OTA升级

作者: Letcos | 来源:发表于2020-05-21 13:10 被阅读0次
    platform:RK3399
    OS:Android 7.1
    

    概述

    ​ OTA(空中下载技术)是一项在线升级技术,它允许终端设备通过网络从服务器下载系统固件并进行升级。高可靠OTA是RK在OTA的基础上增加了两个备份分区实现的一套高可靠的OTA升级机制,其高可靠表现在由于意外情况(断电、固件问题、机器故障)导致升级失败的情况下,仍然可以使用备份分区开机,再次进行升级,避免了升级变砖的情况。

    ​ 先简要介绍普通OTA,然后介绍高可靠OTA

    普通OTA

    步骤1.配置版本号及更新服务器

    device/rockchip/rk3399/rk3399_mid_pi.mk
    diff --git a/rk3399_mid_pi.mk b/rk3399_mid_pi.mk
    index 2c7f0f0..d19b131 100755
    --- a/rk3399_mid_pi.mk
    +++ b/rk3399_mid_pi.mk
    @@ -49,11 +49,13 @@ BUILD_WITH_WIDEVINE := true
     ifeq ($(TARGET_BUILD_VARIANT),user)
     PRODUCT_PROPERTY_OVERRIDES += \
         ro.adb.secure=1 \
    -    persist.sys.usb.config=mtp
    +    persist.sys.usb.config=mtp \
    +    ro.product.version = 1.0.0 \
    +   ro.product.ota.host =14.29.134.165:2300
     else
     PRODUCT_PROPERTY_OVERRIDES += \
         ro.adb.secure=0 \
    -    persist.sys.usb.config=mtp,adb
    +    persist.sys.usb.config=mtp,adb \
    +    ro.product.version = 1.0.0 \
    +   ro.product.ota.host =14.29.134.165:2300
     endif
    

    步骤2. 编译ota固件

    //仅编译android固件
    source build/envsetup.sh
    lunch 9
    make
    make otapackage
    ./mkimage.sh ota
    
    //全编译
    //uboot
    cd u-boot
    make rk3399_defconfig
    make ARCHV=aarch
    //kernel
    cd kernel
    make ARCH=arm64 qxzn_onfig
    make ARCH=arm64 rk3399-mid-pi.img 
    //android 
     source build/envsetup.sh
     lunch 9
     make
     //ota
    make otapackage
    ./mkimage.sh ota
    

    步骤3. 修改版本,编译差异包

    差异包生成脚本:

    ./build/tools/releasetools/ota_from_target_files --block -v -i rockdev/ota_package/orignal/rk3399-target_files-v1.0.0.zip -p out/host/linux-x86 -k build/target/product/security/testkey rockdev/ota_package/orignal/rk3399-target_files-v1.0.1.zip rockdev/ota_package/diff/rk3399-v100-v101.zip
    

    原始包路径(用于生成差异包的素材包):

    out/target/product/rk3399_mid_pi/obj/PACKAGING/target_files_intermediates
    

    ota升级整包路径(用于整包升级):

    out/target/product/rk3399_mid_pi
    

    注意:

    • 重新编译时要修改版本号
    • 重新编译时要删除out/target/product/rk3399_mid_pi/system/build.prop 文件
    • 重新编译时要删除out/target/product/rk3399_mid_pi/obj/PACKAGING 目录

    步骤4. 烧录烧录基准ota包

    使用RK提供的烧录工具即可.注意:不要单独烧kernel.img,否则无法进行差分升级。

    步骤5. 固件升级(本地测试)

    将固件(整包或差分包)改名为update.zip,放到机器用户根目录,即可自动检测升级(插拔typec或重启)。

    高可靠OTA

    步骤1.打开高可靠功能配置

    diff --git a/BoardConfig.mk b/BoardConfig.mk
    index c7ac4d3..e048b70 100755
    --- a/BoardConfig.mk
    +++ b/BoardConfig.mk
    @@ -368,5 +368,5 @@ BOARD_USE_FIX_WALLPAPER ?= false
     # SDBoot: Format data.
     RECOVERY_SDBOOT_FORMATE_DATA ?= false
     
    -HIGH_RELIABLE_RECOVERY_OTA := false
    +HIGH_RELIABLE_RECOVERY_OTA := true
     BOARD_USES_FULL_RECOVERY_IMAGE := false
    

    注意:不建议打开BOARD_USES_FULL_RECOVERY_IMAGE;该宏可能会导致高可靠OTA差分包制作失败。

    步骤2.制作parameter_hrr.txt高可靠分区文件

    FIRMWARE_VER: 7.1
    MACHINE_MODEL: RK3399
    MACHINE_ID: 007
    MANUFACTURER: RK3399
    MAGIC: 0x5041524B
    ATAG: 0x00200800
    MACHINE: 3399
    CHECK_MASK: 0x80
    PWR_HLD: 0,0,A,0,1
    #KERNEL_IMG: 0x00280000
    #FDT_NAME: rk-kernel.dtb
    #RECOVER_KEY: 1,1,0,20,0
    #in section; per section 512(0x200) bytes
    CMDLINE: console=ttyFIQ0 androidboot.baseband=N/A androidboot.selinux=permissive androidboot.hardware=rk30board androidboot.console=ttyFIQ0 init=/init mtdparts=rk29xxnand:0x00002000@0x00002000(uboot),0x00002000@0x00004000(trust),0x00002000@0x00006000(uboot_ro),0x00002000@0x00008000(trust_ro),0x00002000@0x0000A000(misc),0x00008000@0x0000C000(resource),0x0000C000@0x00014000(kernel),0x00010000@0x00020000(boot),0x00020000@0x00030000(recovery),0x00038000@0x00050000(backup),0x00040000@0x00088000(cache),0x00600000@0x000C8000(system),0x00008000@0x006C8000(metadata),0x00000040@0x006D0000(verity_mode),0x00002000@0x006D0040(reserved),0x00000400@0x006D2040(frp),-@0x006D2440(userdata)
    

    相较于普通parameter.txt文件,增加了uboot_ro和trust_ro分区.后面分区的起始地址都要做相应的增加.

    步骤3.生成uboot_ro.img

    合入补丁

    diff --git a/board/rockchip/common/rkboot/fastboot.c b/board/rockchip/common/rkboot/fastboot.c
    index ce6a0a1..80bbd98 100755
    --- a/board/rockchip/common/rkboot/fastboot.c
    +++ b/board/rockchip/common/rkboot/fastboot.c
    @@ -628,27 +628,32 @@ void board_fbt_preboot(void)
    #endif
    if (frt == FASTBOOT_REBOOT_RECOVERY) {
    - FBTDBG("\n%s: starting recovery img because of reboot flag\n", __func__);
    + printf("\nUBOOT_RO %s: starting recovery img because of reboot flag\n", __func__);
    board_fbt_run_recovery();
    } else if (frt == FASTBOOT_REBOOT_RECOVERY_WIPE_DATA) {
    - FBTDBG("\n%s: starting recovery img to wipe data "
    + printf("\nnUBOOT_RO %s: starting recovery img to wipe data "
    "because of reboot flag\n", __func__);
    /* we've not initialized most of our state so don't
    * save env in this case
    */
    board_fbt_run_recovery_wipe_data();
    }
    -#ifdef CONFIG_CMD_FASTBOOT
    +#if 0//def CONFIG_CMD_FASTBOOT
    else if (frt == FASTBOOT_REBOOT_FASTBOOT) {
    FBTDBG("\n%s: starting fastboot because of reboot flag\n", __func__);
    board_fbt_request_start_fastboot();
    }
    #endif
    else {
    + #if 0
    FBTDBG("\n%s: check misc command.\n", __func__);
    /* unknown reboot cause (typically because of a cold boot).
    * check if we had misc command to boot recovery.
    */
    rkloader_run_misc_cmd();
    + #else
    + printf("\nUBOOT_RO %s: Boot to recovery anyway\n", __func__);
    + board_fbt_run_recovery();
    + #endif
    }
    }
    

    然后编译,编译成功后将 uboot.img 修改为 uboot_ro.img

    注意:移植完成高可靠OTA之后,每次在u-boot目录进行提交都需要重新生成uboot_ro.img。这样才能保证备份分区和主分区代码一致。

    步骤4. 去掉前面生成 uboot_ro 的补丁修改;将高可靠升级的 miniloader放置在 u-boot/ tools/rk_tools/bin/rk33/目录下(miniloader需要向RK申请)

    打上loader的patch

    diff --git a/board/rockchip/common/rkboot/fastboot.c b/board/rockchip/common/rkboot/fastboot.c
    index ce6a0a1..e630dda 100755
    --- a/board/rockchip/common/rkboot/fastboot.c
    +++ b/board/rockchip/common/rkboot/fastboot.c
    @@ -62,6 +62,7 @@ int low_power_level = 0;
     int exit_uboot_charge_level = 0;
     int exit_uboot_charge_voltage = 0;
     int uboot_brightness = 1;
    +extern void board_fbt_run_recovery(void);
     
     #ifdef CONFIG_UBOOT_CHARGE
     /**
    @@ -256,8 +257,12 @@ void board_fbt_boot_failed(const char* boot)
     #ifdef CONFIG_CMD_BOOTRK
        if (!memcmp(BOOT_NAME, boot, sizeof(BOOT_NAME))) {
            printf("try to start recovery\n");
    +       #if 0
            char *const boot_cmd[] = {"bootrk", RECOVERY_NAME};
            do_bootrk(NULL, 0, ARRAY_SIZE(boot_cmd), boot_cmd);
    +       #else
    +       board_fbt_run_recovery();
    +       #endif
        } else if (!memcmp(RECOVERY_NAME, boot, sizeof(RECOVERY_NAME))) {
            printf("try to start backup\n");
            char *const boot_cmd[] = {"bootrk", BACKUP_NAME};
    @@ -326,19 +331,72 @@ const disk_partition_t* board_fbt_get_partition(const char* name)
        return get_disk_partition(name);
     }
     
    +void board_fbt_set_recovery_for_hrr_0(void)
    +{
    +   struct bootloader_message bmsg;
    +
    +   printf("board_fbt_set_recovery_for_hrr_0\n");
    +
    +   memset((char *)&bmsg, 0, sizeof(struct bootloader_message));
    +   strcpy(bmsg.command, "boot-recovery");
    +   bmsg.status[0] = 0;
    +   rkloader_set_bootloader_msg_for_hrr(&bmsg);
    +}
    +
    +void board_fbt_set_recovery_for_hrr_32(void)
    +{
    +   struct bootloader_message bmsg;
    +
    +   printf("board_fbt_set_recovery_for_hrr_32\n");
    +
    +
    +   memset((char *)&bmsg, 0, sizeof(struct bootloader_message));
    +   strcpy(bmsg.command, "boot-recovery");
    +   bmsg.status[0] = 0;
    +   if(is_bootloader_msg_has_content())
    +   {
    +       printf("board_fbt_set_recovery_for_hrr_32 bcb has content\n");
    +   }
    +   else
    +   {
    +       rkloader_set_bootloader_msg(&bmsg);
    +   }
    +}
     
    -static void board_fbt_run_recovery(void)
    +void board_fbt_set_recovery_for_hrr_reset(void)
     {
    +   printf("board_fbt_set_recovery_for_hrr_reset reset to miniloader\n");
    +#if 0
     #ifdef CONFIG_CMD_BOOTRK
        char *const boot_recovery_cmd[] = {"bootrk", "recovery"};
        do_bootrk(NULL, 0, ARRAY_SIZE(boot_recovery_cmd), boot_recovery_cmd);
     #endif
    +#else
    +   do_reset(NULL,0,0,NULL);
    +#endif
    +}
    +
    +void board_fbt_set_recovery_for_hrr(void)
    +{
    +   board_fbt_set_recovery_for_hrr_0();
    +   check_misc_info_offset_0_and_32();
    +   board_fbt_set_recovery_for_hrr_reset();
    +}
     
    +void board_fbt_run_recovery(void)
    +{
    +#if 0
    +#ifdef CONFIG_CMD_BOOTRK
    +   char *const boot_recovery_cmd[] = {"bootrk", "recovery"};
    +   do_bootrk(NULL, 0, ARRAY_SIZE(boot_recovery_cmd), boot_recovery_cmd);
    +#endif
    +#else
    +   board_fbt_set_recovery_for_hrr();
    +#endif
        /* returns if recovery.img is bad */
        FBTERR("\nfastboot: Error: Invalid recovery img\n");
     }
     
    -
     void board_fbt_run_recovery_wipe_data(void)
     {
        struct bootloader_message bmsg;
    @@ -346,7 +404,7 @@ void board_fbt_run_recovery_wipe_data(void)
        FBTDBG("Rebooting into recovery to do wipe_data\n");
     
        if (!board_fbt_get_partition("misc")) {
    -       FBTERR("not found misc partition, just run recovery.\n");
    +       printf("not found misc partition, just run recovery.\n");
            board_fbt_run_recovery();
        }
     
    @@ -359,7 +417,6 @@ void board_fbt_run_recovery_wipe_data(void)
        board_fbt_run_recovery();
     }
     
    -
     #ifdef CONFIG_RK_POWER
     static void board_fbt_low_power_check(void)
     {
    @@ -628,10 +685,13 @@ void board_fbt_preboot(void)
     #endif
     
        if (frt == FASTBOOT_REBOOT_RECOVERY) {
    -       FBTDBG("\n%s: starting recovery img because of reboot flag\n", __func__);
    +       printf("\n%s: starting recovery img because of reboot flag\n", __func__);
    +       #if 1
    +       board_fbt_set_recovery_for_hrr_32();
    +       #endif
            board_fbt_run_recovery();
        } else if (frt == FASTBOOT_REBOOT_RECOVERY_WIPE_DATA) {
    -       FBTDBG("\n%s: starting recovery img to wipe data "
    +       printf("\n%s: starting recovery img to wipe data "
                    "because of reboot flag\n", __func__);
            /* we've not initialized most of our state so don't
             * save env in this case
    diff --git a/board/rockchip/common/rkloader/rkloader.c b/board/rockchip/common/rkloader/rkloader.c
    index 3afe20c..ddcc51f 100755
    --- a/board/rockchip/common/rkloader/rkloader.c
    +++ b/board/rockchip/common/rkloader/rkloader.c
    @@ -141,7 +141,7 @@ static int dispose_bootloader_cmd(struct bootloader_message *msg,
        int ret = 0;
     
        if (0 == strcmp(msg->command, "bootloader")
    -           || 0 == strcmp(msg->command, "loader")) // ÐÂLoader²ÅÄÜÖ§³Ö"loader"ÃüÁî
    +           || 0 == strcmp(msg->command, "loader"))
        {
            bool reboot;
     
    @@ -151,7 +151,7 @@ static int dispose_bootloader_cmd(struct bootloader_message *msg,
                ret = -1;
            }
     
    -       {// ²»¹Ü³É¹¦Óë·ñ£¬½«miscÇå0
    +       {
                int i=0;
                memset(g_32secbuf, 0, 32*528);
                for(i=0; i<3; i++)
    @@ -204,6 +204,7 @@ void rkloader_change_cmd_for_recovery(PBootInfo boot_info, char * rec_cmd)
     #define PAGE_SIZE           (16 * 1024)//16K
     #define MISC_SIZE           (MISC_PAGES * PAGE_SIZE)//48K
     #define MISC_COMMAND_OFFSET (MISC_COMMAND_PAGE * PAGE_SIZE / RK_BLK_SIZE)//32
    +extern void board_fbt_run_recovery(void);
     
     int rkloader_run_misc_cmd(void)
     {
    @@ -234,8 +235,12 @@ int rkloader_run_misc_cmd(void)
     #endif
            printf("got recovery cmd from misc.\n");
     #ifdef CONFIG_CMD_BOOTRK
    +       #if 0
            char *const boot_cmd[] = {"bootrk", "recovery"};
            do_bootrk(NULL, 0, ARRAY_SIZE(boot_cmd), boot_cmd);
    +       #else
    +       board_fbt_run_recovery();
    +       #endif
     #endif
            return false;
        } else if (!strcmp(bmsg->command, "boot-factory")) {
    @@ -259,6 +264,96 @@ int rkloader_run_misc_cmd(void)
        return false;
     }
     
    +int is_bootloader_msg_has_content(void)
    +{
    +   struct bootloader_message *bmsg = NULL;
    +#ifdef CONFIG_RK_NVME_BOOT_EN
    +   ALLOC_ALIGN_BUFFER(u8, buf, DIV_ROUND_UP(sizeof(struct bootloader_message),
    +       RK_BLK_SIZE) * RK_BLK_SIZE, SZ_4K);
    +#else
    +   ALLOC_CACHE_ALIGN_BUFFER(u8, buf, DIV_ROUND_UP(sizeof(struct bootloader_message),
    +       RK_BLK_SIZE) * RK_BLK_SIZE);
    +#endif
    +   const disk_partition_t *ptn = get_disk_partition(MISC_NAME);
    +
    +   if (!ptn) {
    +       printf("misc partition not found!\n");
    +       return 1;
    +   }
    +
    +   bmsg = (struct bootloader_message *)buf;
    +   if (StorageReadLba(ptn->start + MISC_COMMAND_OFFSET, buf, DIV_ROUND_UP(
    +       sizeof(struct bootloader_message), RK_BLK_SIZE)) != 0) {
    +           printf("failed to read misc\n");
    +           return 1;
    +       }
    +   
    +   if(strlen(bmsg->command) > 0)
    +   {
    +       printf("is_bootloader_msg_has_content bmsg->command=%s bmsg->recovery=%s\n", 
    +           bmsg->command, bmsg->recovery);
    +           return 1;
    +   }
    +   else
    +   {
    +       return 0;
    +   }
    +}
    +
    +void check_misc_info_offset_0_and_32(void)
    +{
    +   struct bootloader_message *bmsg = NULL;
    +#ifdef CONFIG_RK_NVME_BOOT_EN
    +   ALLOC_ALIGN_BUFFER(u8, buf, DIV_ROUND_UP(sizeof(struct bootloader_message),
    +       RK_BLK_SIZE) * RK_BLK_SIZE, SZ_4K);
    +#else
    +   ALLOC_CACHE_ALIGN_BUFFER(u8, buf, DIV_ROUND_UP(sizeof(struct bootloader_message),
    +       RK_BLK_SIZE) * RK_BLK_SIZE);
    +#endif
    +   const disk_partition_t *ptn = get_disk_partition(MISC_NAME);
    +
    +   if (!ptn) {
    +       printf("misc partition not found!\n");
    +       return;
    +   }
    +
    +   memset(buf, 0x0, DIV_ROUND_UP(sizeof(struct bootloader_message), RK_BLK_SIZE));
    +   bmsg = (struct bootloader_message *)buf;
    +   if (StorageReadLba(ptn->start, buf, DIV_ROUND_UP(
    +       sizeof(struct bootloader_message), RK_BLK_SIZE)) != 0) {
    +           printf("failed to read misc\n");
    +           return;
    +       }
    +
    +   if(strlen(bmsg->command) > 0)
    +   {
    +       printf("check_misc_info_offset_0 bmsg->command=%s \n", bmsg->command);
    +   }
    +   else
    +   {
    +       printf("check_misc_info_offset_0 bmsg->command is NULL \n");
    +   }
    +   
    +   memset(buf, 0x0, DIV_ROUND_UP(sizeof(struct bootloader_message), RK_BLK_SIZE));
    +   bmsg = (struct bootloader_message *)buf;
    +   if (StorageReadLba(ptn->start + MISC_COMMAND_OFFSET, buf, DIV_ROUND_UP(
    +       sizeof(struct bootloader_message), RK_BLK_SIZE)) != 0) {
    +           printf("failed to read misc\n");
    +           return;
    +       }
    +
    +   if(strlen(bmsg->command) > 0)
    +   {
    +       printf("check_misc_info_offset_32 bmsg->command=%s \n", bmsg->command);
    +       return;
    +   }
    +   else
    +   {
    +       printf("check_misc_info_offset_32 bmsg->command is NULL \n");
    +       return;
    +   }
    +}
    +   
     
     void rkloader_fixInitrd(PBootInfo pboot_info, int ramdisk_addr, int ramdisk_sz)
     {
    @@ -317,4 +412,22 @@ int rkloader_set_bootloader_msg(struct bootloader_message* bmsg)
                DIV_ROUND_UP(sizeof(struct bootloader_message), RK_BLK_SIZE));
     }
     
    +int rkloader_set_bootloader_msg_for_hrr(struct bootloader_message* bmsg)
    +{
    +#ifdef CONFIG_RK_NVME_BOOT_EN
    +   ALLOC_ALIGN_BUFFER(u8, buf, DIV_ROUND_UP(sizeof(struct bootloader_message),
    +       RK_BLK_SIZE) * RK_BLK_SIZE, SZ_4K);
    +#else
    +   ALLOC_CACHE_ALIGN_BUFFER(u8, buf, DIV_ROUND_UP(sizeof(struct bootloader_message),
    +       RK_BLK_SIZE) * RK_BLK_SIZE);
    +#endif
    +   memcpy(buf, bmsg, sizeof(struct bootloader_message));
    +   const disk_partition_t *ptn = get_disk_partition(MISC_NAME);
    +   if (!ptn) {
    +       printf("misc partition not found!\n");
    +       return -1;
    +   }
     
    +   return rkloader_CopyMemory2Flash((uint32)(unsigned long)buf, ptn->start/* + 
    +MISC_COMMAND_OFFSET*/,DIV_ROUND_UP(sizeof(struct bootloader_message), RK_BLK_SIZE));
    +}
    diff --git a/board/rockchip/common/rkloader/rkloader.h b/board/rockchip/common/rkloader/rkloader.h
    index 202a4c8..5a57093 100755
    --- a/board/rockchip/common/rkloader/rkloader.h
    +++ b/board/rockchip/common/rkloader/rkloader.h
    @@ -22,5 +22,8 @@ void rkloader_change_cmd_for_recovery(PBootInfo boot_info, char * rec_cmd);
     int rkloader_run_misc_cmd(void);
     void rkloader_fixInitrd(PBootInfo pboot_info, int ramdisk_addr, int ramdisk_sz);
     int rkloader_set_bootloader_msg(struct bootloader_message* bmsg);
    +int rkloader_set_bootloader_msg_for_hrr(struct bootloader_message* bmsg);
    +int is_bootloader_msg_has_content(void);
    +void check_misc_info_offset_0_and_32(void);
     
     #endif /* __RK_LOADER_H__ */
    diff --git a/tools/rk_tools/RKBOOT/RK3399MINIALL.ini b/tools/rk_tools/RKBOOT/RK3399MINIALL.ini
    index ef79b35..3b9352b 100644
    --- a/tools/rk_tools/RKBOOT/RK3399MINIALL.ini
    +++ b/tools/rk_tools/RKBOOT/RK3399MINIALL.ini
    @@ -15,6 +15,6 @@ NUM=2
     LOADER1=FlashData
     LOADER2=FlashBoot
     FlashData=tools/rk_tools/bin/rk33/rk3399_ddr_800MHz_v1.22.bin
    -FlashBoot=tools/rk_tools/bin/rk33/rk3399_miniloader_v1.15.bin
    +FlashBoot=tools/rk_tools/bin/rk33/rk3399miniloaderall.bin
     [OUTPUT]
     PATH=rk3399_loader_v1.22.115.bin
    

    打上build_tools的补丁

    commit 85b475cebca65830889269552b51e99c5d8041b7
    Author: letcos <leicongus@gmail.com>
    Date:   Sun Oct 20 23:01:13 2019 -0400
    
        hrr_ota
    
    diff --git a/core/Makefile b/core/Makefile
    old mode 100644
    new mode 100755
    index 2cc1588..6bdf3be
    --- a/core/Makefile
    +++ b/core/Makefile
    @@ -1997,11 +1997,9 @@ ifeq ($(HIGH_RELIABLE_RECOVERY_OTA),true)
     endif
        $(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
     ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
    -ifneq ($(HIGH_RELIABLE_RECOVERY_OTA),true)
        $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
            ./build/tools/releasetools/make_recovery_patch $(zip_root) $(zip_root)
     endif
    -endif
     ifeq ($(AB_OTA_UPDATER),true)
        @# When using the A/B updater, include the updater config files in the zip.
        $(hide) $(ACP) $(TOPDIR)system/update_engine/update_engine.conf $(zip_root)/META/update_engine_config.txt
    diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
    index af4db33..133ab98 100755
    --- a/tools/releasetools/common.py
    +++ b/tools/releasetools/common.py
    @@ -1654,6 +1654,7 @@ def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img,
     
       full_recovery_image = info_dict.get("full_recovery_image", None) == "true"
       system_root_image = info_dict.get("system_root_image", None) == "true"
    +  hrr_omit_recovery = info_dict.get("hrr_omit_recovery_image", None) == "true"
     
       if full_recovery_image:
         output_sink("etc/recovery.img", recovery_img.data)
    @@ -1708,6 +1709,37 @@ fi
            'recovery_device': recovery_device,
            'bonus_args': bonus_args}
     
    +
    +  if hrr_omit_recovery:
    +    if full_recovery_image:
    +      sh_hrr = """#!/system/bin/sh
    +if ! applypatch -c %(type)s:%(device)s:%(size)d:%(sha1)s; then
    +  log -t recovery "Recovery image skip"
    +else
    +  log -t recovery "Recovery image already installed"
    +fi
    +""" % {'type': recovery_type,
    +       'device': recovery_device,
    +       'sha1': recovery_img.sha1,
    +       'size': recovery_img.size}
    +    else:
    +      sh_hrr = """#!/system/bin/sh
    +if ! applypatch -c %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then
    +  log -t recovery "Recovery image skip"
    +else
    +  log -t recovery "Recovery image already installed"
    +fi
    +""" % {'boot_size': boot_img.size,
    +       'boot_sha1': boot_img.sha1,
    +       'recovery_size': recovery_img.size,
    +       'recovery_sha1': recovery_img.sha1,
    +       'boot_type': boot_type,
    +       'boot_device': boot_device,
    +       'recovery_type': recovery_type,
    +       'recovery_device': recovery_device,
    +       'bonus_args': bonus_args}
    +
    +
       # The install script location moved from /system/etc to /system/bin
       # in the L release.  Parse init.*.rc files to find out where the
       # target-files expects it to be, and put it there.
    @@ -1736,4 +1768,7 @@ fi
     
       print "putting script in", sh_location
     
    -  output_sink(sh_location, sh)
    +  if hrr_omit_recovery:
    +    output_sink(sh_location, sh_hrr)
    +  else:
    +    output_sink(sh_location, sh)
    diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
    index e88fa7d..b58a24d 100755
    --- a/tools/releasetools/ota_from_target_files.py
    +++ b/tools/releasetools/ota_from_target_files.py
    @@ -834,6 +834,7 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
       source_version = OPTIONS.source_info_dict["recovery_api_version"]
       target_version = OPTIONS.target_info_dict["recovery_api_version"]
     
    +  hrr_omit_recovery = OPTIONS.info_dict.get("hrr_omit_recovery_image")
       if source_version == 0:
         print ("WARNING: generating edify script for a source that "
                "can't install it.")
    @@ -1022,10 +1023,11 @@ else if get_stage("%(bcb_dev)s") != "3/3" then
         # patching on a device that's already on the target build will damage the
         # system. Because operations like move don't check the block state, they
         # always apply the changes unconditionally.
    -    if blockimgdiff_version <= 2:
    -      script.AssertSomeFingerprint(source_fp)
    -    else:
    -      script.AssertSomeFingerprint(source_fp, target_fp)
    +    if not hrr_omit_recovery:
    +      if blockimgdiff_version <= 2:
    +        script.AssertSomeFingerprint(source_fp)
    +      else:
    +        script.AssertSomeFingerprint(source_fp, target_fp)
       else:
         if blockimgdiff_version <= 2:
           script.AssertSomeThumbprint(
    @@ -1534,6 +1536,7 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
     
       source_version = OPTIONS.source_info_dict["recovery_api_version"]
       target_version = OPTIONS.target_info_dict["recovery_api_version"]
    +  hrr_omit_recovery = OPTIONS.info_dict.get("hrr_omit_recovery_image")
     
       if source_version == 0:
         print ("WARNING: generating edify script for a source that "
    @@ -1605,7 +1608,8 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
                                        OPTIONS.source_info_dict)
     
       if oem_props is None:
    -    script.AssertSomeFingerprint(source_fp, target_fp)
    +    if not hrr_omit_recovery:
    +      script.AssertSomeFingerprint(source_fp, target_fp)
       else:
         script.AssertSomeThumbprint(
             GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
    

    步骤五:重新编译uboot即可生成支持高可靠OTA的uboot.img

    注意:

    1. 不同SDK和主板miniloader可能不同,在源码路径的放置也可能不同。具体可以参考SDK中的《高可靠OTA使用说明文档.pdf》

    2. 步骤四不是必须的,如果不打build_tools的patch 也可以正常生成OTA整包和差分包,那么就不需要执行步骤四。

    其余步骤同普通OTA.

    固件无法单独烧录Kernel

    实现了高可靠OTA之后,测试时单独编译kernel并烧录可能出现问题,可以采用如下补丁规避.

    diff --git a/make_mid_pi.sh b/make_mid_pi.sh
    index 1da24f5..0d0f92d 100755
    --- a/make_mid_pi.sh
    +++ b/make_mid_pi.sh
    @@ -2,6 +2,30 @@
     
     set -e
     
    +. build/envsetup.sh >/dev/null && setpaths
    +
    +export PATH=$ANDROID_BUILD_PATHS:$PATH
    +TARGET_PRODUCT=`get_build_var TARGET_PRODUCT`
    +TARGET_HARDWARE=`get_build_var TARGET_BOARD_HARDWARE`
    +TARGET_BOARD_PLATFORM=`get_build_var TARGET_BOARD_PLATFORM`
    +TARGET_DEVICE_DIR=`get_build_var TARGET_DEVICE_DIR`
    +PLATFORM_VERSION=`get_build_var PLATFORM_VERSION`
    +PLATFORM_SECURITY_PATCH=`get_build_var PLATFORM_SECURITY_PATCH`
    +TARGET_BUILD_VARIANT=`get_build_var TARGET_BUILD_VARIANT`
    +BOARD_SYSTEMIMAGE_PARTITION_SIZE=`get_build_var BOARD_SYSTEMIMAGE_PARTITION_SIZE`
    +BOARD_USE_SPARSE_SYSTEM_IMAGE=`get_build_var BOARD_USE_SPARSE_SYSTEM_IMAGE`
    +HIGH_RELIABLE_RECOVERY_OTA=`get_build_var HIGH_RELIABLE_RECOVERY_OTA`
    +TARGET_BASE_PARAMETER_IMAGE=`get_build_var TARGET_BASE_PARAMETER_IMAGE`
    +echo TARGET_BOARD_PLATFORM=$TARGET_BOARD_PLATFORM
    +echo TARGET_PRODUCT=$TARGET_PRODUCT
    +echo TARGET_HARDWARE=$TARGET_HARDWARE
    +echo TARGET_BUILD_VARIANT=$TARGET_BUILD_VARIANT
    +echo BOARD_SYSTEMIMAGE_PARTITION_SIZE=$BOARD_SYSTEMIMAGE_PARTITION_SIZE
    +echo BOARD_USE_SPARSE_SYSTEM_IMAGE=$BOARD_USE_SPARSE_SYSTEM_IMAGE
    +echo HIGH_RELIABLE_RECOVERY_OTA=$HIGH_RELIABLE_RECOVERY_OTA
    +echo TARGET_BASE_PARAMETER_IMAGE==$TARGET_BASE_PARAMETER_IMAGE
    +TARGET="withoutkernel"
    
     usage()
     {
     cat << EOF
    @@ -67,6 +91,10 @@ if  $MAKE_ALL || [ $MAKE_MODULES = 'k' ]; then
         make  ARCH=arm64 "${KERNEL_DTS}.img" -j $MAKE_THEARD | tee build_kernel.log
         popd
     fi
    
    +    mkbootfs $OUT/root | minigzip > $OUT/ramdisk.img
    +    truncate -s "%4" $OUT/ramdisk.img
    +    cp kernel/arch/arm64/boot/Image kernel/kernel_Image
    +    mkbootimg --kernel kernel/kernel_Image --ramdisk $OUT/ramdisk.img --second kernel/resource.img --os_version $PLATFORM_VERSION --os_patch_level $PLATFORM_SECURITY_PATCH --cmdline buildvariant=$TARGET_BUILD_VARIANT --output kernel/boot_nokernel.img
    
     if $MAKE_ALL || [ $MAKE_MODULES = 'a' ]; then
         source ${QXZNTOOLS_PATH}/build.sh
    

    相关文章

      网友评论

          本文标题:高可靠OTA升级

          本文链接:https://www.haomeiwen.com/subject/lryzohtx.html