rv1126 recovery整包升级以及分区升级
官方升级参考文档“Rockchip_Developer_Guide_Linux_Upgrade_CN.pdf”,下面根据自己实际操作和实验,来整理下recovery模式升级固件的方法。
1.简介以及代码
1.1 简介
Rockchip Linux 平台支持两种启动方案,Recovery 模式和Linux A/B 模式:
- Recovery 模式,设备上有一个单独的分区(recovery)用于升级操作。
- Linux A/B 模式,设备上有两套固件,可切换使用。
这两种启动模式各有优缺点,用户根据需求选择使用。
1.2 代码
Rockchip Linux 平台有两套升级方案代码。
2.Recovery 模式
2.1 概述
Recovery 模式是在设备上多一个Recovery分区,该分区由kernel+resource+ramdisk 组成,主要用于升级操
作。u-boot会根据misc分区(详见misc 分区章节)存放的字段来判断将要引导的系统是Normal 系统还是
Recovery 系统。由于系统的独立性,所以Recovery模式能保证升级的完整性,即升级过程被中断,如异
常掉电,升级仍然能继续执行。
优点:
- 能保证升级的完整性
缺点:
- 系统多了一个分区,该分区仅用于升级。
- 升级过程必须重启进入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 &
流程介绍:
- 固件版本比较(—version_url)
- 下载固件(—image_url),并保存到本地(—savepath)
- 升级recovery 分区
- 重启(—reboot)
- 进入recovery模式,升级指定的分区(—partition)
- 升级成功,重启进入normal系统
可缺省参数:
- —version_url:远程地址或本地地址,没有设置该参数,则不会进行版本比较。
- —savepath:固件保存地址,缺省时为/tmp/update.img,建议传入/userdata/update.img。
- —partition:设置将要升级的分区,建议使用0x3FFC00,不支持升级parameter 和loader分区。详见参数说明章节。
- —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=的值,不指定该值,默认是升级整包。
- 分享
- 举报
-
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:185.00元回复 举报文章不错,大家可以多多关注哦~
-
浏览量:1833次2024-01-05 14:15:33
-
浏览量:2100次2023-11-21 14:45:31
-
浏览量:6368次2022-05-31 11:14:16
-
浏览量:4725次2023-03-24 22:56:50
-
浏览量:3835次2021-04-01 13:54:47
-
浏览量:2311次2022-10-09 10:38:23
-
浏览量:2965次2023-11-24 19:08:58
-
浏览量:6935次2021-04-01 17:04:01
-
浏览量:3112次2023-04-03 15:10:25
-
浏览量:5442次2021-04-01 16:24:41
-
浏览量:6061次2021-04-01 16:50:31
-
浏览量:960次2023-08-30 18:37:06
-
浏览量:728次2024-01-02 09:46:50
-
浏览量:1612次2023-12-29 17:51:55
-
浏览量:5900次2021-04-01 16:47:04
-
浏览量:3980次2021-06-18 16:05:42
-
浏览量:3293次2018-04-12 11:32:51
-
浏览量:3661次2017-11-16 11:30:55
-
浏览量:1247次2023-08-31 16:23:55
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
林
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明