/*************************************************************************
|
> File Name: main.cpp
|
> Author: jkand.huang
|
> Mail: jkand.huang@rock-chips.com
|
> Created Time: Mon 20 May 2019 10:56:06 AM CST
|
************************************************************************/
|
|
#include <stdio.h>
|
#include <string.h>
|
#include <stdlib.h>
|
#include <unistd.h>
|
#include <getopt.h>
|
#include <sys/reboot.h>
|
#include "log.h"
|
#include "update.h"
|
#include "../bootloader.h"
|
#include "defineHeader.h"
|
#include "rktools.h"
|
|
extern bool is_sdboot;
|
RK_Upgrade_Status_t m_status = RK_UPGRADE_ERR;
|
FILE* cmd_pipe = NULL;
|
|
void handle_upgrade_callback(void *user_data, RK_Upgrade_Status_t status){
|
if (status == RK_UPGRADE_FINISHED) {
|
LOGI("rk ota success.\n");
|
setSlotActivity();
|
}
|
m_status = status;
|
LOGI("rk m_status = %d.\n", m_status);
|
}
|
|
void handle_print_callback(char *szPrompt)
|
{
|
if(cmd_pipe != NULL){
|
fprintf(cmd_pipe, "ui_print %s\n", szPrompt);
|
}
|
}
|
|
static int MiscUpdate(char *url, char *update_partition, char *save_path) {
|
int partition;
|
char *savepath = NULL;
|
int slot = -1;
|
if (url == NULL) {
|
//如果没有传入URL,则可以去查找是否有存在
|
LOGE("MiscUpdate URL must be set.\n");
|
return -1;
|
}
|
slot = getCurrentSlot();
|
if (update_partition == NULL) {
|
//没有传入要升级的分区,默认升级
|
if (slot == -1){
|
// recovery mdoe
|
// u-boot/trust/boot/recovery/boot/rootfs/oem
|
partition = 0X3F0000;
|
} else {
|
// A/B mdoe
|
// uboot_a/uboot_b/boot_a/boot_b/system_a/system_b
|
partition = 0XFC00;
|
}
|
} else {
|
partition = strtol(update_partition+2, NULL, 16);
|
}
|
|
if (save_path == NULL) {
|
savepath = url;
|
} else {
|
savepath = save_path;
|
}
|
|
RK_ota_set_url(url, savepath);
|
LOGI("url = %s.\n", url);
|
LOGI("[%s:%d] save path: %s\n", __func__, __LINE__, savepath);
|
// If it's recovery mode, upgrade recovery in normal system.
|
if (slot == -1 && !is_sdboot){
|
if (partition & 0x040000) {
|
LOGI("update recovery in normal system.\n");
|
partition = partition & 0xFBFFFF;
|
|
// upgrade recoery in normal system
|
if (!RK_ota_set_partition(0x040000)) {
|
LOGE("ota file is error.\n");
|
return -1;
|
}
|
RK_ota_start(handle_upgrade_callback, handle_print_callback);
|
if (m_status != RK_UPGRADE_FINISHED) {
|
return -1;
|
}
|
|
//写MISC
|
struct bootloader_message msg;
|
memset(&msg, 0, sizeof(msg));
|
char recovery_str[] = "recovery\n--update_package=";
|
strcpy(msg.command, "boot-recovery");
|
sprintf(msg.recovery, "%s%s", recovery_str, savepath);
|
msg.recovery[strlen(msg.recovery) + 1] = '\n';
|
memcpy(msg.needupdate, &partition, 4);
|
set_bootloader_message(&msg);
|
return 0;
|
}
|
} else if (slot == 0) {
|
LOGI("In A system, now upgrade B system.\n");
|
partition = partition & 0x155ff;
|
} else if (slot == 1) {
|
LOGI("In B system, now upgrade A system.\n");
|
partition = partition & 0x1a9ff;
|
}
|
|
if (!RK_ota_set_partition(partition)) {
|
LOGE("ota file is error.\n");
|
return -1;
|
}
|
RK_ota_start(handle_upgrade_callback, handle_print_callback);
|
if (m_status != RK_UPGRADE_FINISHED) {
|
return -1;
|
}
|
|
return 0;
|
}
|
|
void display() {
|
LOGI("--misc=now Linux A/B mode: Setting the current partition to bootable.\n");
|
LOGI("--misc=other Linux A/B mode: Setting another partition to bootable.\n");
|
LOGI("--misc=update Recovery mode: Setting the partition to be upgraded.\n");
|
LOGI("--misc=display Display misc info.\n");
|
LOGI("--misc=wipe_userdata Format data partition.\n");
|
LOGI("--misc_custom= < op > Operation on misc for custom cmdline");
|
LOGI(" op: read Read custom cmdline to /tmp/custom_cmdline");
|
LOGI(" write Write /tmp/custom_cmdline to custom area");
|
LOGI(" clean clean custom area");
|
LOGI("--update Upgrade mode.\n");
|
LOGI("--partition=0x3FFC00 Set the partition to be upgraded.(NOTICE: OTA not support upgrade loader and parameter)\n");
|
LOGI(" 0x3FFC00: 0011 1111 1111 1100 0000 0000.\n");
|
LOGI(" uboot trust boot recovery rootfs oem\n");
|
LOGI(" uboot_a uboot_b boot_a boot_b system_a system_b.\n");
|
LOGI(" 100000000000000000000000: Upgrade loader\n");
|
LOGI(" 010000000000000000000000: Upgrade parameter\n");
|
LOGI(" 001000000000000000000000: Upgrade uboot\n");
|
LOGI(" 000100000000000000000000: Upgrade trust\n");
|
LOGI(" 000010000000000000000000: Upgrade boot\n");
|
LOGI(" 000001000000000000000000: Upgrade recovery\n");
|
LOGI(" 000000100000000000000000: Upgrade rootfs\n");
|
LOGI(" 000000010000000000000000: Upgrade oem\n");
|
LOGI(" 000000001000000000000000: Upgrade uboot_a\n");
|
LOGI(" 000000000100000000000000: Upgrade uboot_b\n");
|
LOGI(" 000000000010000000000000: Upgrade boot_a\n");
|
LOGI(" 000000000001000000000000: Upgrade boot_b\n");
|
LOGI(" 000000000000100000000000: Upgrade system_a\n");
|
LOGI(" 000000000000010000000000: Upgrade system_b\n");
|
LOGI(" 000000000000001000000000: Upgrade misc\n");
|
LOGI(" 000000000000000100000000: Upgrade userdata\n");
|
LOGI("--reboot Restart the machine at the end of the program.\n");
|
LOGI("--version_url=url The path to the file of version.\n");
|
LOGI("--image_url=url Path to upgrade firmware.\n");
|
LOGI("--savepath=url save the update.img to url.\n");
|
|
}
|
|
static const struct option engine_options[] = {
|
{ "update", optional_argument, NULL, 'u' },
|
{ "version_url", required_argument, NULL, 'v' + 'u' },
|
{ "image_url", required_argument, NULL, 'i' + 'u'},
|
{ "check", required_argument, NULL, 'c' },
|
{ "misc", required_argument, NULL, 'm' },
|
{ "misc_custom", required_argument, NULL, 'd' },
|
{ "partition", required_argument, NULL, 'p' },
|
{ "reboot", no_argument, NULL, 'r' },
|
{ "help", no_argument, NULL, 'h' },
|
{ "pipefd", required_argument, NULL, 'p' + 'f' },
|
{ "savepath", required_argument, NULL, 's'},
|
{ NULL, 0, NULL, 0 },
|
};
|
|
int main(int argc, char *argv[]) {
|
LOGI("*** update_engine: Version V1.1.5 ***.\n");
|
int arg;
|
char *image_url = NULL;
|
char *version_url = NULL;
|
char *misc_func = NULL;
|
char *save_path = NULL;
|
char *partition = NULL;
|
char *custom_define = NULL;
|
bool is_update = false;
|
bool is_reboot = false;
|
int pipefd = -1;
|
|
while ((arg = getopt_long(argc, argv, "", engine_options, NULL)) != -1) {
|
switch (arg) {
|
case 'u': is_update = true; if(optarg != NULL) is_sdboot = true; continue;
|
case 'c': version_url = optarg; continue;
|
case 'm': misc_func = optarg; continue;
|
case 'p': partition = optarg; continue;
|
case 's': save_path = optarg; continue;
|
case 'r': is_reboot = true; continue;
|
case 'v' + 'u': version_url = optarg; continue;
|
case 'i' + 'u': image_url = optarg; continue;
|
case 'p' + 'f': pipefd = atoi(optarg); continue;
|
case 'h': display(); break;
|
case 'd': custom_define = optarg; continue;
|
case '?':
|
LOGE("Invalid command argument\n");
|
continue;
|
}
|
}
|
|
if (pipefd != -1) {
|
cmd_pipe = fdopen(pipefd, "wb");
|
setlinebuf(cmd_pipe);
|
}
|
|
if (is_update) {
|
if (is_sdboot) {
|
int res = 0x3FFC00; //默认升级的分区
|
LOGI("%s-%d: is sdboot update.\n", __func__, __LINE__);
|
if (partition != NULL) {
|
res = strtol(partition+2, NULL, 16);
|
}
|
RK_ota_set_url(image_url, save_path);
|
if ( !RK_ota_set_partition(res) ){
|
LOGE("ota file is error.\n");
|
return -1;
|
}
|
|
if (version_url != NULL) {
|
if (!RK_ota_check_version(version_url) ){
|
LOGE("you shouldn't update the device.\n");
|
return -1;
|
}
|
}
|
|
RK_ota_start(handle_upgrade_callback, handle_print_callback);
|
} else {
|
LOGI("%s-%d: is ota update\n", __func__, __LINE__);
|
if (MiscUpdate(image_url, partition, save_path) == 0) {
|
m_status = RK_UPGRADE_FINISHED;
|
}
|
}
|
}else if (misc_func != NULL) {
|
if (strcmp(misc_func, "now") == 0) {
|
if (setSlotSucceed() ==0) {
|
m_status = RK_UPGRADE_FINISHED;
|
}
|
} else if (strcmp(misc_func, "other") == 0) {
|
if (setSlotActivity() == 0) {
|
m_status = RK_UPGRADE_FINISHED;
|
}
|
} else if (strcmp(misc_func, "wipe_userdata") == 0) {
|
if (wipe_userdata(0) == 0) {
|
m_status = RK_UPGRADE_FINISHED;
|
}
|
} else if (strcmp(misc_func, "update") == 0) {
|
if (MiscUpdate(image_url, partition, save_path) == 0) {
|
m_status = RK_UPGRADE_FINISHED;
|
}
|
} else if (strcmp(misc_func, "display") == 0) {
|
miscDisplay();
|
} else {
|
LOGE("unknow misc cmdline : %s.\n", misc_func);
|
return 0;
|
}
|
} else if (custom_define != NULL) {
|
if (strcmp(custom_define, "read") == 0) {
|
if (readCustomMiscCmdline())
|
return -1;
|
} else if (strcmp(custom_define, "write") == 0) {
|
if (writeCustomMiscCmdline())
|
return -1;
|
} else if (strcmp(custom_define, "clean") == 0) {
|
if (cleanCustomMiscCmdline())
|
return -1;
|
} else {
|
LOGI("Not supported\n");
|
return m_status;
|
}
|
m_status = RK_UPGRADE_FINISHED;
|
}
|
|
if (is_reboot && (m_status == RK_UPGRADE_FINISHED)) {
|
sync();
|
//reboot(RB_AUTOBOOT);
|
system(" echo b > /proc/sysrq-trigger ");
|
}
|
|
return m_status;
|
}
|