From: Jaewon Kim Date: Wed, 29 Mar 2017 01:22:34 +0000 (+0900) Subject: board: artik530_raptor: add update check feature for ota X-Git-Tag: submit/tizen/20171208.054649~112 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=74b5eca2cb626e87d531e5f23630e870e44a1089;p=profile%2Fcommon%2Fplatform%2Fkernel%2Fu-boot-artik7.git board: artik530_raptor: add update check feature for ota This patch adds update check feature to support OTA(Over the Air). This feature checks booting state information in FLAG partition. If booting failed on updated partition, partition changes to backuped boot partition. Change-Id: Id6484f0d5307f15b36f9f23e03d424a3e8d3feb5 Signed-off-by: Jaewon Kim --- diff --git a/board/s5p4418/artik530_raptor/Kconfig b/board/s5p4418/artik530_raptor/Kconfig index cd128c89a5..ad2c2847db 100644 --- a/board/s5p4418/artik530_raptor/Kconfig +++ b/board/s5p4418/artik530_raptor/Kconfig @@ -3,5 +3,11 @@ if TARGET_ARTIK530_RAPTOR config SYS_BOARD default "artik530_raptor" +config ARTIK_OTA + bool "ARTIK Update feature" + help + This feature provides OTA(Over-The-Air) function. + It updates kernel & modules partition without + the need of physical access. endif diff --git a/board/s5p4418/artik530_raptor/Makefile b/board/s5p4418/artik530_raptor/Makefile index 95ab99dfc2..cba9481361 100644 --- a/board/s5p4418/artik530_raptor/Makefile +++ b/board/s5p4418/artik530_raptor/Makefile @@ -5,4 +5,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y := board.o +obj-y += board.o +obj-$(CONFIG_ARTIK_OTA) += ota.o diff --git a/board/s5p4418/artik530_raptor/board.c b/board/s5p4418/artik530_raptor/board.c index 2aa1534fd3..033e68f005 100644 --- a/board/s5p4418/artik530_raptor/board.c +++ b/board/s5p4418/artik530_raptor/board.c @@ -28,6 +28,10 @@ #include #endif +#ifdef CONFIG_ARTIK_OTA +#include +#endif + DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_CHECK_BONDING_ID @@ -295,6 +299,9 @@ int board_late_init(void) #endif #ifdef CONFIG_SENSORID_ARTIK get_sensorid(board_rev); +#endif +#ifdef CONFIG_ARTIK_OTA + check_ota_update(); #endif return 0; } diff --git a/board/s5p4418/artik530_raptor/ota.c b/board/s5p4418/artik530_raptor/ota.c new file mode 100644 index 0000000000..06693409e1 --- /dev/null +++ b/board/s5p4418/artik530_raptor/ota.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_FLAG_INFO_ADDR +#define CONFIG_FLAG_INFO_ADDR 0x9A000000 +#endif + +static void write_flag_partition(void) +{ + char cmd[CMD_LEN] = {0, }; + + sprintf(cmd, "mmc write 0x%X 0x%X %X", + CONFIG_FLAG_INFO_ADDR, FLAG_PART_BLOCK_START, 1); + run_command(cmd, 0); +} + +static struct boot_info *read_flag_partition(void) +{ + char cmd[CMD_LEN] = {0, }; + + sprintf(cmd, "mmc read 0x%X 0x%X %X", + CONFIG_FLAG_INFO_ADDR, FLAG_PART_BLOCK_START, 1); + run_command(cmd, 0); + + return (struct boot_info *)map_sysmem( + CONFIG_FLAG_INFO_ADDR, sizeof(struct boot_info)); +} + +int check_ota_update(void) +{ + struct boot_info *boot; + struct part_info *cur_part, *bak_part; + char cmd[CMD_LEN] = {0, }; + char *bootcmd, *rootdev; + + setenv("ota", "ota"); + /* Do not check flag partition on recoveryboot mode */ + bootcmd = getenv("bootcmd"); + if (strstr(bootcmd, "recoveryboot") != NULL) { + return 0; + } + + /* Check booted device */ + rootdev = getenv("rootdev"); + if (strncmp(rootdev, "0", 1) == 0) { + sprintf(cmd, "mmc dev %d", MMC_DEV_NUM); + } else if (strncmp(rootdev, "1", 1) == 0) { + sprintf(cmd, "mmc dev %d", SD_DEV_NUM); + } else { + printf("Cannot find rootdev\n"); + return -1; + } + run_command(cmd, 0); + + boot = read_flag_partition(); + if (strncmp(boot->header_magic, HEADER_MAGIC, 32) != 0) { + printf("Cannot read FLAG information\n"); + return -1; + } + + if (boot->part_num == PART0) { + cur_part = &boot->part0; + bak_part = &boot->part1; + } else { + cur_part = &boot->part1; + bak_part = &boot->part0; + } + + switch (boot->state) { + case BOOT_SUCCESS: + printf("Booting State = Normal(%d)\n", boot->part_num); + if (boot->part_num == PART0) + setenv("bootpart", __stringify(CONFIG_BOOT_PART)); + else + setenv("bootpart", __stringify(CONFIG_BOOT1_PART)); + setenv("rescue", "0"); + break; + case BOOT_UPDATED: + if (cur_part->retry > 0) { + printf("%s Partition Updated\n", + boot->part_num == PART0 ? "PART0" : "PART1"); + cur_part->retry--; + setenv("bootdelay", "0"); + setenv("rescue", "0"); + /* Handling Booting Fail */ + } else if (cur_part->retry == 0) { + printf("Boot failed from %s\n", + boot->part_num == PART0 ? "PART0" : "PART1"); + cur_part->state = BOOT_FAILED; + if (bak_part->state == BOOT_SUCCESS) { + if (boot->part_num == PART0) + boot->part_num = PART1; + else + boot->part_num = PART0; + boot->state = BOOT_SUCCESS; + setenv("rescue", "1"); + } else { + boot->state = BOOT_FAILED; + } + } + + if (boot->part_num == PART0) + setenv("bootpart", __stringify(CONFIG_BOOT_PART)); + else + setenv("bootpart", __stringify(CONFIG_BOOT1_PART)); + write_flag_partition(); + break; + case BOOT_FAILED: + default: + printf("Booting State = Abnormal\n"); + setenv("bootpart", __stringify(CONFIG_BOOT_PART)); + return -1; + } + + return 0; +} diff --git a/include/artik_ota.h b/include/artik_ota.h new file mode 100644 index 0000000000..2cd88766ae --- /dev/null +++ b/include/artik_ota.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016 Samsung Electronics + * Author: Jaewon Kim + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ARTIK_OTA_H +#define __ARTIK_OTA_H + +#define FLAG_PART_BLOCK_START 0x2000 +#define HEADER_MAGIC "ARTIK_OTA" +#define CMD_LEN 128 +#define MMC_DEV_NUM 0 +#define SD_DEV_NUM 1 + +enum boot_part { + PART0 = 0, + PART1, +}; + +enum boot_state { + BOOT_FAILED = 0, + BOOT_SUCCESS, + BOOT_UPDATED, +}; + +struct part_info { + enum boot_state state; + char retry; + char tag[32]; +}; + +struct boot_info { + char header_magic[32]; + enum boot_part part_num; + enum boot_state state; + struct part_info part0; + struct part_info part1; +}; + +int check_ota_update(void); +#endif