rv1126 recovery整包升级以及分区升级

rv1126 recovery整包升级以及分区升级 2024-01-03 10:17:12 2991

官方升级参考文档“Rockchip_Developer_Guide_Linux_Upgrade_CN.pdf”,下面根据自己实际操作和实验,来整理下recovery模式升级固件的方法。

1.简介以及代码

1.1 简介

Rockchip Linux 平台支持两种启动方案,Recovery 模式和Linux A/B 模式:

  1. Recovery 模式,设备上有一个单独的分区(recovery)用于升级操作。
  2. Linux A/B 模式,设备上有两套固件,可切换使用。

这两种启动模式各有优缺点,用户根据需求选择使用。

1.2 代码

Rockchip Linux 平台有两套升级方案代码。

2.Recovery 模式

2.1 概述

Recovery 模式是在设备上多一个Recovery分区,该分区由kernel+resource+ramdisk 组成,主要用于升级操

作。u-boot会根据misc分区(详见misc 分区章节)存放的字段来判断将要引导的系统是Normal 系统还是

Recovery 系统。由于系统的独立性,所以Recovery模式能保证升级的完整性,即升级过程被中断,如异

常掉电,升级仍然能继续执行。

优点:

  1. 能保证升级的完整性

缺点:

  1. 系统多了一个分区,该分区仅用于升级。
  2. 升级过程必须重启进入recovery模式,不能在Normal系统直接进行升级。

分区简介:

2.2 配置和编译

Buildroot:recovery 配置文件选择如下(make menuconfig)

BR2_PACKAGE_RECOVERY=y #开启升级相关功能
BR2_PACKAGE_RECOVERY_USE_UPDATEENGINE=y #使用新升级程序,不配置则默认使用原有升级流程
BR2_PACKAGE_RECOVERY_RECOVERYBIN=y #开启recovery bin 文件
BR2_PACKAGE_RECOVERY_UPDATEENGINEBIN=y #编译新升级程序
BR2_PACKAGE_RECOVERY_NO_UI=y # 关掉UI

Buildroot:rootfs 配置文件选择如下(make menuconfig)

BR2_PACKAGE_RECOVERY=y #开启升级相关功能
BR2_PACKAGE_RECOVERY_USE_UPDATEENGINE=y #使用新升级程序
BR2_PACKAGE_RECOVERY_UPDATEENGINEBIN=y #编译新升级程序
BR2_PACKAGE_RECOVERY_NO_UI=y # 关掉UI

带屏与不带屏

目前只有RK3308使用不带屏的recovery,如有其它要让recovery不显示界面,在文件 buildroot/package/rockchip/recovery/recovery.mk做如下配置即可:

TARGET_MAKE_ENV += RecoveryNoUi=true

SDK默认会开启以上配置,用户无需再次配置。源码目录位于external/recovery/

2.3 OTA升级

升级支持网络升级和本地升级,且可指定要升级的分区,在normal系统运行如下命令:

网络升级:

# updateEngine --misc=update --image_url=固件地址 --partition=0x3FFC00 -- version_url=版本文件地址 --savepath=/userdata/update.img --reboot 
updateEngine --image_url=http://172.16.21.110:8080/recovery/update.img --misc=update --savepath=/userdata/update.img --reboot &

本地升级:

updateEngine --image_url=/userdata/update.img --misc=update --savepath=/userdata/update.img --reboot &

流程介绍:

  1. 固件版本比较(—version_url)
  2. 下载固件(—image_url),并保存到本地(—savepath)
  3. 升级recovery 分区
  4. 重启(—reboot)
  5. 进入recovery模式,升级指定的分区(—partition)
  6. 升级成功,重启进入normal系统

可缺省参数:

  1. —version_url:远程地址或本地地址,没有设置该参数,则不会进行版本比较。
  2. —savepath:固件保存地址,缺省时为/tmp/update.img,建议传入/userdata/update.img。
  3. —partition:设置将要升级的分区,建议使用0x3FFC00,不支持升级parameterloader分区。详见参数说明章节。
  4. —reboot:升级recovery 完后,重启进入recovery模式。

注意:

目前—misc=update模式不会进行版本判断,即使有—version_url字段也不会去判断版本。而—update模式会根据是否有—version_url字段来决定是否判断版本,—version_url如果没有不会进行版本比较,如果有远程地址(判断依据是url中带http就认为是远程地址),则会先下载版本文件,然后再像本地地址一样的处理方式,读取版本文件中的version参数,进行比较,新版本大于历史版本,才会升级。设备中版本文件的默认路径为“/etc/version”,内容如下:

[root@RV1126_RV1109:~]# cat /etc/version
RK_MODEL=RKXXXX_RETROGAME
RK_VERSION=V1.0.0
RK_OTA_HOST=172.16.21.205:8080
XML_NAME=rv1126_rv1109_linux_20210714.xml

recovery中版本判断主要代码如下:

bool RK_ota_check_version(char *url) {
    char source_version[20] = {0};
    char target_version[20] = {0};
    if (!getLocalVersion(source_version, sizeof(source_version))) {
        return false;
    }

    if (strncmp(url, "http", 4) == 0) {
        //如果是远程文件,从远程获取版本号
        if (!getRemoteVersion(url, target_version, sizeof(target_version))) {
            return false;
        }
    } else {
        //如果是本地文件,从固件获取版本号
        if (!getImageVersion(url, target_version, sizeof(target_version))) {
            return false;
        }
    }

    LOGI("check version new:%s  old:%s", target_version, source_version);
    if (strcmp(target_version, source_version) > 0) {
        return true;
    }
    return false;
}

3.升级程序详细说明

3.1 参数说明

updateEngine主要包含升级分区和写Misc配置功能,支持命令参数如下:

*** update_engine: Version V1.1.0 ***. 
--misc=now                 Linux A/B mode: Setting the current partition to bootable. 
--misc=other             Linux A/B mode: Setting another partition to bootable. 
--misc=update             Recovery mode: Setting the partition to be upgraded. 
--misc=wipe_userdata     Format data partition. 
--update                 Upgrade mode. 
--partition=0x3FFC00     Set the partition to be upgraded.(NOTICE: OTA not support upgrade loader and parameter) 
                        0x3FFC00:     0011 1111 1111 1100 0000 0000. 
                                    uboot trust boot recovery rootfs oem 
                                    uboot_a uboot_b boot_a boot_b system_a system_b.
                        000000000000000000000000: reserved 
                        100000000000000000000000: Upgrade loader                 
                        010000000000000000000000: Upgrade parameter 
                        001000000000000000000000: Upgrade uboot 
                        000100000000000000000000: Upgrade trust 
                        000010000000000000000000: Upgrade boot 
                        000001000000000000000000: Upgrade recovery 
                        000000100000000000000000: Upgrade rootfs 
                        000000010000000000000000: Upgrade oem 
                        000000001000000000000000: Upgrade uboot_a 
                        000000000100000000000000: Upgrade uboot_b 
                        000000000010000000000000: Upgrade boot_a 
                        000000000001000000000000: Upgrade boot_b 
                        000000000000100000000000: Upgrade system_a 
                        000000000000010000000000: Upgrade system_b 
                        000000000000001000000000: Upgrade misc 
                        000000000000000100000000: Upgrade userdata
--reboot Restart the machine at the end of the program. 
--version_url=url The path to the file of version. 
--image_url=url Path to upgrade firmware. 
--savepath=url save the update.img to url.

—misc

now:供Linux A/B 模式使用,将当前分区设置为可引导分区。

注意:external/recovery/update_engine/S99_bootcontrol 脚本在开机最后阶段会运行该命令,将当前分区设

置为可引导分区,需要开启

BR2_PACKAGE_RECOVERY_BOOTCONTROL=y

other:供Linux A/B 模式使用,将另外一个分区设置为升级完成分区,重启之后会尝试从另外一个分区引

导。

注意:如果使用updateEngine升级,在升级结束之后,会自动设置,无需重复设置。

update:供Recovery模式使用,在normal系统升级recovery分区,在recovery 系统升级其余分区。

display:调试使用,显示misc分区的数据结构

—update

sdboot:走sdboot升级流程,即直接对flash操作,没有分区概念。

不带参数:主要供Linux A/B使用,在当前模式下,直接进行升级。

—partition=0x0000

设置将要升级的分区,如果缺省,默认值为0x3FFC00,升级uboot,trust,boot,recovery,rootfs,

oem,uboot_a,uboot_b,boot_a,boot_b,system_a,system_b分区。高16位已经使用,低8位为保留

位,可扩展使用。

1:升级,0:不升级

—reboot

运行成功之后,机器重启

—version_url

如果有传入路径,升级之前会与/etc/version 文件中的 RK_VERSION= 版本值进行比较

本地路径:从固件中读取版本号

远程路径:从远程下载版本文件,远程版本文件格式必须跟/etc/version 一致

—image_url

设置升级固件的路径,可为远程或本地路径。

—savepath

设置保存固件的位置,如果没有传入且升级的固件路径为远程地址,则默认值为/tmp/update.img

4.Recovery模式下升级某个单独的分区

4.1 升级命令

举例,以升级 userdata 分区为例:

1.本地升级命令:

updateEngine --image_url=/userdata/userdata.img --misc=update --savepath=/userdata/userdata.img --partition=0x100 --reboot

2.网络升级命令:

不判断版本号:

updateEngine --image_url=http://192.168.0.161:8080/download/update.img --misc=update --savepath=/userdata/userdata.img --partition=0x100 --reboot

带版本号校验的:

updateEngine --version_url=http://192.168.0.161:8080/download/version --image_url=http://192.168.0.161:8080/download/update.img --update --savepath=/userdata/userdata.img --partition=0x100 --reboot

4.2 制作升级文件和确定参数

举例,以升级 userdata 分区为例:

1.首先根据 3.1开头部分确定—partition=的值为:

--partition=0x100

2.编译该分区的镜像,并打包得到ota升级的包,不能直接用分区编译得到的镜像,因为这个镜像没有ota升级需要的数据头等信息,直接用的话,用升级命令的时候会提示下面的错误:

[root@RV1126_RV1109:/userdata]# updateEngine --image_url=/userdata/userdata.img --misc=update --savepath=/userdata/userdata.img --partition=0x100 --reboot
 &
[root@RV1126_RV1109:/userdata]# LOG_INFO :*** update_engine: Version V1.1.0 ***.

LOG_INFO :start RK_ota_url url [/userdata/userdata.img] save path [/userdata/userdata.img].

LOG_INFO :save image to /userdata/userdata.img.
LOG_INFO :url = /userdata/userdata.img.
LOG_INFO :Current Mode is recovery.
LOG_INFO :[MiscUpdate:58] save path: /userdata/userdata.img
LOG_INFO :[RK_ota_set_partition:90] num [16]
LOG_INFO :need update parameter.
LOG_INFO :need update userdata.
LOG_INFO :start RK_ota_start.
LOG_INFO :rk m_status = 1.
LOG_INFO :where the file is local.
LOG_INFO :[RK_ota_set_partition:90] num [16]
LOG_DEBUG :uiTag = 0.
LOG_DEBUG :usSize = 0.
LOG_DEBUG :dwVersion = 0.
LOG_DEBUG :btMajor = 0, btMinor = 0, usSmall = 00.
LOG_DEBUG :dwBootOffset = 0.
LOG_DEBUG :dwBootSize = 0.
LOG_DEBUG :dwFWOffset = 0.
LOG_DEBUG :dwFWSize = 0.
LOG_ERROR : md5 : not support sign image.
LOG_ERROR : tag: 0

LOG_ERROR : Invalid image
LOG_ERROR : analyticImage error.
LOG_ERROR : RK_ota_set_partition failed.
LOG_INFO :rk m_status = 2.

镜像格式不对,需要用rkupdate.mk进行打包。

3.将编译的userdata.img镜像进行打包,Linux下打包脚本以及配置文件路径如下:

/home/zl/firefly-workspace/rv1126_rv1109_linux_release_20210306/tools/linux/Linux_Pack_Firmware/rockdev

到这个目录下修改 package-file文件,该文件默认情况下内容如下:

# NAME        Relative path
#
#HWDEF        HWDEF
package-file    package-file
bootloader    Image/MiniLoaderAll.bin
parameter    Image/parameter.txt
#
# if uboot.img is fit, uboot.img had include uboot and trust,
# so ignore trust.img
# file Image/uboot.img
# Image/uboot.img: Device Tree Blob version 17
#
# trust        Image/trust.img
#
uboot        Image/uboot.img
misc        Image/misc.img
#resource    Image/resource.img
#kernel        Image/kernel.img
boot        Image/boot.img
recovery    Image/recovery.img
rootfs        Image/rootfs.img
oem        Image/oem.img
userdata    Image/userdata.img
# 要写入backup分区的文件就是自身(update.img)
# SELF 是关键字,表示升级文件(update.img)自身
# 在生成升级文件时,不加入SELF文件的内容,但在头部信息中有记录
# 在解包升级文件时,不解包SELF文件的内容。
backup        RESERVED
#update-script    update-script
#recover-script    recover-script

默认情况下,打包的镜像有uboot,misc,boot,recovery,rootfs,oem,userdata,所以如果要单独升级打包某一个镜像,就需要将其他屏蔽掉,目前我用的是修改这个文件的方法,不过我觉得这种方法有些原始,应该有编译命令直接可以操作才对,只是相关资料有限,目前先用这个方式,修改之后的文件如下:

# NAME        Relative path
#
#HWDEF        HWDEF
package-file    package-file
bootloader    Image/MiniLoaderAll.bin
parameter    Image/parameter.txt
#
# if uboot.img is fit, uboot.img had include uboot and trust,
# so ignore trust.img
# file Image/uboot.img
# Image/uboot.img: Device Tree Blob version 17
#
# trust        Image/trust.img
#
#uboot        Image/uboot.img
#misc        Image/misc.img
#resource    Image/resource.img
#kernel        Image/kernel.img
#boot        Image/boot.img
#recovery    Image/recovery.img
#rootfs        Image/rootfs.img
#oem        Image/oem.img
userdata    Image/userdata.img
# 要写入backup分区的文件就是自身(update.img)
# SELF 是关键字,表示升级文件(update.img)自身
# 在生成升级文件时,不加入SELF文件的内容,但在头部信息中有记录
# 在解包升级文件时,不解包SELF文件的内容。
backup        RESERVED
#update-script    update-script
#recover-script    recover-script

只屏蔽其他img镜像的行,像那些bin和最后的backup都不要动,修改文件之后,运行rkupdate.sh脚本,打包log如下:

zl@zl-Lenovo:~/firefly-workspace/rv1126_rv1109_linux_release_20210306/tools/linux/Linux_Pack_Firmware/rockdev$ ./mkupdate.sh 
start to make update.img...
Android Firmware Package Tool v1.66
------ PACKAGE ------
Add file: ./package-file
Add file: ./package-file done,offset=0x800,size=0x332,userspace=0x1
Add file: ./Image/MiniLoaderAll.bin
Add file: ./Image/MiniLoaderAll.bin done,offset=0x1000,size=0x3f14e,userspace=0x7f
Add file: ./Image/parameter.txt
Add file: ./Image/parameter.txt done,offset=0x40800,size=0x211,userspace=0x1
Add file: ./Image/userdata.img
Add file: ./Image/userdata.img done,offset=0x41000,size=0x2600000,userspace=0x4c00
Add CRC...
Make firmware OK!
------ OK ------
********RKImageMaker ver 1.66********
Generating new image, please wait...
Writing head info...
Writing boot file...
Writing firmware...
Generating MD5 data...
MD5 data generated successfully!
New image generated successfully!
Making -RK1126 update.img OK.

在rkupdate.sh脚本所在目录下会生成打包的update.img,修改这个文件的名字,然后拷贝到设备上,然后再用下面的命令就可以了:

[root@RV1126_RV1109:/userdata]# updateEngine --image_url=/userdata/userdata.img --misc=update --savepath=/userdata/userdata.img --partition=0x100 --reboot
 &
[root@RV1126_RV1109:/userdata]# LOG_INFO :*** update_engine: Version V1.1.0 ***.

LOG_INFO :start RK_ota_url url [/userdata/userdata.img] save path [/userdata/userdata.img].

LOG_INFO :save image to /userdata/userdata.img.

LOG_INFO :url = /userdata/userdata.img.

LOG_INFO :Current Mode is recovery.

LOG_INFO :[MiscUpdate:58] save path: /userdata/userdata.img

LOG_INFO :[RK_ota_set_partition:90] num [16]

LOG_INFO :need update parameter.

LOG_INFO :need update userdata.

LOG_INFO :start RK_ota_start.

LOG_INFO :rk m_status = 1.

LOG_INFO :where the file is local.

LOG_INFO :[RK_ota_set_partition:90] num [16]

LOG_DEBUG :uiTag = 57464b52.

LOG_DEBUG :usSize = 66.

LOG_DEBUG :dwVersion = 8010000.

LOG_DEBUG :btMajor = 8, btMinor = 1, usSmall = 00.

LOG_DEBUG :dwBootOffset = 66.

LOG_DEBUG :dwBootSize = 3f14e.

LOG_DEBUG :dwFWOffset = 3f1b4.

LOG_DEBUG :dwFWSize = 2641004.

LOG_DEBUG :tag = 1178684242
LOG_DEBUG :size = 40112128
LOG_DEBUG :machine_model =  RV1126
LOG_DEBUG :manufacturer =  RV1126
LOG_DEBUG :version = 134283264
LOG_DEBUG :item = 5.

LOG_INFO :================================================
LOG_DEBUG :name = package-file
LOG_DEBUG :file = package-file
LOG_DEBUG :offset = 260532
LOG_DEBUG :flash_offset = -1
LOG_DEBUG :usespace = 1
LOG_DEBUG :size = 818
LOG_INFO :================================================
LOG_DEBUG :name = bootloader
LOG_DEBUG :file = Image/MiniLoaderAll.bin
LOG_DEBUG :offset = 102
LOG_DEBUG :flash_offset = -1
LOG_DEBUG :usespace = 127
LOG_DEBUG :size = 258382
LOG_INFO :================================================
LOG_DEBUG :name = parameter
LOG_DEBUG :file = Image/parameter.txt
LOG_DEBUG :offset = 522676
LOG_DEBUG :flash_offset = 0
LOG_DEBUG :usespace = 1
LOG_DEBUG :size = 529
LOG_INFO :================================================
LOG_DEBUG :name = userdata
LOG_DEBUG :file = Image/userdata.img
LOG_DEBUG :offset = 524724
LOG_DEBUG :flash_offset = 4816896
LOG_DEBUG :usespace = 19456
LOG_DEBUG :size = 39845888
LOG_INFO :================================================
LOG_DEBUG :name = backup
LOG_DEBUG :file = RESERVED
LOG_DEBUG :offset = 258484
LOG_DEBUG :flash_offset = 163840
LOG_DEBUG :usespace = 0
LOG_DEBUG :size = 0

new md5:01235cbdef5bb9fac7f5e9762d7ffe07
LOG_INFO :MD5Check is ok of /userdata/userdata.img

LOG_INFO :analyticImage ok.

LOG_INFO :found rkimage_hdr.item[2].name = parameter.

LOG_INFO :found rkimage_hdr.item[3].name = userdata.

LOG_INFO :Current device is not MTD
LOG_INFO :now write parameter to /dev/block/by-name/gpt.

LOG_INFO :ingore misc.

LOG_INFO :now write userdata to /dev/block/by-name/userdata.

update_cmd.flash_offset = 0.
LOG_INFO :flash_normal:188 start.

LOG_INFO :Current device is not MTD
LOG_INFO :block_write src /userdata/userdata.img dest /dev/block/by-name/userdata.

LOG_INFO :Current device is not MTD
storage_manager[2065]: [uevent_monitor.c][uevent_monitor_thread]:uevent_monitor_thread /dev/mmcblk0p8 change

new md5:263b8a5dad6032b2bfd0d34b6f1bf2e3
LOG_INFO :MD5Check is ok of /dev/block/by-name/userdata

storage_manager[2065]: [manage.c][file_manage_thread]:MSG_CMD_DEV_CHANGE /dev/mmcblk0p8

new md5:263b8a5dad6032b2bfd0d34b6f1bf2e3
LOG_INFO :MD5Check is ok of /userdata/userdata.img

LOG_INFO :check /dev/block/by-name/userdata ok.

LOG_INFO :RK_ota_start is ok!
LOG_INFO :rk ota success.

LOG_INFO :Current Mode is recovery.

LOG_INFO :rk m_status = 0.

提示升级成功,等重启之后,相应分区就会更改。目前这个分区升级是用命令行的方式,web前后端是升级整包,本来计划通过升级文件的名字来修改web前后端ota升级,结果发现web前后端的逻辑会将拷如的文件修改成id的形式,是随机数,比如502,所以从拷入的文件名上无法区分是哪个分区,并且也没有分区类似的参数,后期需要,倒是可以修改。

5.web后端升级处理流程

从web前端选择文件并点击升级开始,升级包开始传递到设备上,保存到/userdata目录下,文件是以一个随机数为名字:

// ipcweb-backend<----->system_api.cpp[239]
} else if (!path_specific_resource.compare("firmware-upgrade")) {
#ifdef ENABLE_JWT
  if (user_level > 1) {
    Resp.setErrorResponse(HttpStatus::kUnauthorized, "Unauthorized");
    return;
  }
#endif
  // int total_length = 0;
  int transmitted_length;
  int begin_position;
  int end_position;
  int current_transfer_length;
  std::string progress_rate = "";
  // for (auto p : Req.Params) {
  //   if (p.Key == "total-length")
  //     total_length = atoi(p.Value.c_str());
  // }
  for (auto p : Req.Params) {
    if ((p.Key == "upload-type") && (p.Value == "resumable")) {
      // Create a transmission resource
      Resp.setHeader(HttpStatus::kOk, "OK");
      Resp.addHeader("X-Location", create_fireware_location());
    } else if (p.Key == "id") {
      std::ofstream file;
      std::string file_id = p.Value;

      file.open("/data/" + file_id, std::ofstream::app); // append write
      if (!file) {
        Resp.setErrorResponse(HttpStatus::kNotFound, "Not Found");
      } else if (Req.ContentLength == 0) {
        // Query the current progress
        file.seekp(0, std::ofstream::end);
        transmitted_length = file.tellp();
        progress_rate = "bytes 0-" + std::to_string(transmitted_length - 1);
        Resp.setHeader(HttpStatus::kResumeIncomplete, "Resume Incomplete");
        content.emplace("range", progress_rate);
        Resp.setApiData(content);
      } else {
        // Transfer
        begin_position = file.tellp();
        file << Req.PostData;
        end_position = file.tellp();
        current_transfer_length = end_position - begin_position;
        // transmitted_length is not necessarily equal to end_position,
        // it is possible to change a paragraph in the middle of the file
        file.seekp(0, std::ofstream::end);
        transmitted_length = file.tellp();
        if (Req.ContentLength != current_transfer_length) {
          // Request for retransmission due to transmission error
          progress_rate = "bytes 0-" + std::to_string(begin_position - 1);
          Resp.setHeader(HttpStatus::kResumeIncomplete,
                         "Resume Incomplete");
        } else {
          progress_rate =
              "bytes 0-" + std::to_string(transmitted_length - 1);
          if (Req.ContentLength < 512 * 1024) {
            // Transfer completed
            Resp.setHeader(HttpStatus::kCreated, "Created");
          } else if (Req.ContentLength == 512 * 1024) {
            Resp.setHeader(HttpStatus::kResumeIncomplete,
                           "Resume Incomplete");
          } else {
            Resp.setHeader(HttpStatus::kResumeIncomplete,
                           "More than 512KB!");
          }
        }
        content.emplace("range", progress_rate);
        Resp.setApiData(content);
      }
      file.close();
    } else if (p.Key == "start") {
      int fireware_id = stoi(p.Value);
      std::string path = "/userdata/" + std::to_string(fireware_id);
      system_upgrade(path.c_str());
      Resp.setHeader(HttpStatus::kOk, "OK");
    }
  }
}

web前端点击升级之后,先发送的是((p.Key == “upload-type”) && (p.Value == “resumable”)),通过create_fireware_location()方法获取此次升级过程中的id,该id是随机数,并以该id为文件名,作为镜像保存的名字。然后是(p.Key == “id”),开始镜像数据的传递,设备端保存文件,最后是(p.Key == “start”),调用system_upgrade方法,来构建升级命令,下面整理了一下相关过程涉及的文件以及主要代码段,所在文件行数可能有出入:

过程一:

// libIPCProtocol<----->system_manager.cc[123]
extern "C" char *system_upgrade(const char *path)
{
    char *ret = NULL;
    json_object *j_cfg = json_object_new_object();

    json_object_object_add(j_cfg, "sPath", json_object_new_string(path));
    ret = dbus_system_upgrade((char *)json_object_to_json_string(j_cfg));
    json_object_put(j_cfg);

    return ret;
}

过程二:

// libIPCProtocol<----->system_manager.cc[72]
char *dbus_system_upgrade(char *json)
{
    SYSTEMMANAGER_DBUSSEND_2(Upgrade);
}

过程三:

// ipc-daemon<----->system_manager.c[262]
{GDBUS_ASYNC_METHOD("Upgrade", GDBUS_ARGS({"json", "s"}),
                    GDBUS_ARGS({"json", "s"}), method_upgrade)},

过程四:

// ipc-daemon<----->system_manager.c[209]
DBusMessage *method_upgrade(DBusConnection *conn, DBusMessage *msg,
                            void *data) {
  const char *sender;
  DBusMessage *reply;
  DBusMessageIter array;
  const char *str;
  char *json_str;
  json_object *j_cfg;
  json_object *j_ret;

  sender = dbus_message_get_sender(msg);

  dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &json_str,
                        DBUS_TYPE_INVALID);

  j_cfg = json_tokener_parse(json_str);
  j_ret = json_object_new_object();

  char *path =
      (char *)json_object_get_string(json_object_object_get(j_cfg, "sPath"));
  LOGD("export db path = %s\n", path);
  int ret = system_upgrade(path);
  ...
  ...
}

过程五:

// ipc-daemon<----->system_manager.c[59]
int system_upgrade(const char *path) {
  char cmd[128] = {'\0'};

  /* TODO: check firmware */

  if (path)
    snprintf(cmd, 127, "updateEngine --image_url=%s --misc=update --savepath=%s --reboot &", path, path);
  else
    return ILLEGAL_ATTR;

  return system(cmd);
}

到这一步就拼接出了updateEngine命令,从目前代码来看,只是默认升级整包,如果升级某个分区,需要修改web前后端,将当前传入的镜像名字或者类型等标识发送过来,然后在拼接升级命令的时候,根据类型来确定—partition=的值,不指定该值,默认是升级整包。

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 4 1 评论 打赏
评论
3个
内容存在敏感词
手气红包
  • cll3712 2024-10-30 16:40:48
    回复
    上述文档4.2.2 2.编译该分区的镜像,并打包得到ota升级的包,不能直接用分区编译得到的镜像,因为这个镜像没有ota升级需要的数据头等信息,直接用的话,用升级命令的时候会提示下面的错误: ;我也遇到了这个问题,“ota升级需要的数据头等信息”打包update.img镜像后就会有吗?还是说需要ota特定的update.img打包工具才可以??
  • dmmonstr 2024-09-12 14:09:30
    回复
    文章不错,大家可以多多关注哦~
  • 易百纳技术社区 2024-01-03 15:30:18
    5.00元
    回复
    文章不错,大家可以多多关注哦~
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区