board: artik710_raptor: add update check feature for ota
authorJaewon Kim <jaewon02.kim@samsung.com>
Tue, 2 May 2017 06:59:46 +0000 (15:59 +0900)
committerJaewon Kim <jaewon02.kim@samsung.com>
Tue, 2 May 2017 10:01:57 +0000 (19:01 +0900)
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: I18591e409fcaae8024082119ca5fc07e37790955
Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
board/s5p6818/artik710_raptor/Kconfig
board/s5p6818/artik710_raptor/Makefile
board/s5p6818/artik710_raptor/board.c
board/s5p6818/artik710_raptor/ota.c [new file with mode: 0644]

index 1773ae51f94de9d1eaa8ffd720247a59c70a42ca..2a6a6d846a14d6f640b4b7d9352e3043d1289a54 100644 (file)
@@ -3,5 +3,12 @@ if TARGET_ARTIK710_RAPTOR
 config SYS_BOARD
        default "artik710_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
 
index 95ab99dfc2e418d44db24aa0eef20bfcb7f0de21..a312eecea64617f86badb943d2fe6aab83a7014d 100644 (file)
@@ -6,3 +6,4 @@
 #
 
 obj-y  := board.o
+obj-$(CONFIG_ARTIK_OTA)        += ota.o
index 13344340164cb5038eed7029ce8e50270fe616c2..e91f60f0ebdc2010fc72d50f5e786b854041da33 100644 (file)
 #include <sensorid.h>
 #include <sensorid_artik.h>
 #endif
+
+#ifdef CONFIG_ARTIK_OTA
+#include <artik_ota.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_REVISION_TAG
@@ -298,6 +303,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/s5p6818/artik710_raptor/ota.c b/board/s5p6818/artik710_raptor/ota.c
new file mode 100644 (file)
index 0000000..184cfce
--- /dev/null
@@ -0,0 +1,125 @@
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mapmem.h>
+#include <errno.h>
+#include <artik_ota.h>
+
+#ifndef CONFIG_FLAG_INFO_ADDR
+#define CONFIG_FLAG_INFO_ADDR  0x49000000
+#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));
+}
+
+static inline void update_partition_env(enum boot_part part_num)
+{
+       if (part_num == PART0) {
+               setenv("bootpart", __stringify(CONFIG_BOOT_PART));
+               setenv("modulespart", __stringify(CONFIG_MODULES_PART));
+       } else {
+               setenv("bootpart", __stringify(CONFIG_BOOT1_PART));
+               setenv("modulespart", __stringify(CONFIG_MODULES1_PART));
+       }
+}
+
+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);
+               update_partition_env(boot->part_num);
+               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;
+                       }
+               }
+
+               update_partition_env(boot->part_num);
+               write_flag_partition();
+               break;
+       case BOOT_FAILED:
+       default:
+               printf("Booting State = Abnormal\n");
+               update_partition_env(PART0);
+               return -1;
+       }
+
+       return 0;
+}