From: Jaehoon Chung Date: Mon, 17 Jun 2024 23:33:35 +0000 (+0900) Subject: dfu: Support the image flashing about A/B slot X-Git-Tag: accepted/tizen/unified/20240618.195747^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=680171059c60a928d24a03e77ccb7f58ee947e55;p=platform%2Fcore%2Fsystem%2Finitrd-flash.git dfu: Support the image flashing about A/B slot Tizen is using A/B partition. So it needs to update the image about both partitions. This patch supports the image flashing about a/b slot. The Entire time of flashing images (Headed) - Before : 3m 50s - After : 6m 40s Change-Id: I9a3648cc958ba532734c3ea690c7362e173b1bdc Signed-off-by: Jaehoon Chung --- diff --git a/src/dfu.c b/src/dfu.c index 3e62006..d365b8a 100644 --- a/src/dfu.c +++ b/src/dfu.c @@ -37,6 +37,8 @@ #define DFU_INFO_MODE_PARTITION 'p' #define DFU_INFO_MODE_FILE 'f' +#define DFU_INFO_PART_A "a" +#define DFU_INFO_PART_B "b" #define DFU_IOQ_MAXLEN 5 @@ -48,6 +50,7 @@ enum dfu_entry_attr { DFU_INFO_PARTITION, DFU_INFO_NAME, DFU_INFO_PATH, + DFU_INFO_AB, DFU_INFO_MAX, }; @@ -388,9 +391,20 @@ static void *dfu_thread_main(void *ptr) state = DFU_THREAD_STATE_ERROR; } + if (e->fd_b > 0) { + ret = write(e->fd_b, frame->buf, frame->len); + if (ret < frame->len) { + fprintf(stderr, "Error occurs while flashing\n"); + state = DFU_THREAD_STATE_ERROR; + } + } + + progress += frame->len; fsync(e->fd); + if (e->fd_b > 0) + fsync(e->fd_b); pthread_mutex_lock(&ctx->mutex); TAILQ_REMOVE(&ctx->ioq, frame, entry); @@ -425,6 +439,72 @@ static void *dfu_thread_main(void *ptr) return NULL; } +static int find_slot_b(struct dfu_context *ctx, char *name) { + int fd = -1; + char *file = NULL; + int i, ret = 0; + + for (i = 0; i < DFU_ENTRY_LIST_MAXLEN; i++) { + char *entry_name = ctx->dfu_entry_list[i][DFU_INFO_NAME]; + char *entry_ab = ctx->dfu_entry_list[i][DFU_INFO_AB]; + + if (entry_ab && strncmp(entry_ab, DFU_INFO_PART_B, strlen(entry_ab)) == 0) { + if (entry_name && !strncmp(entry_name, name, strlen(entry_name))) { + char **entry = ctx->dfu_entry_list[i]; + switch (*entry[DFU_INFO_MODE]) { + case DFU_INFO_MODE_PARTITION: + file = strdup(entry[DFU_INFO_PARTITION]); + break; + case DFU_INFO_MODE_FILE: + { + int path_prefix = strlen(DFU_MOUNT_PATH); + int path_suffix = strlen(entry[DFU_INFO_PATH]); + int path_name = strlen(entry[DFU_INFO_NAME]); + + ret = mount_dev(entry[DFU_INFO_PARTITION]); + if (ret < 0) + return -EINVAL; + + file = malloc(path_prefix + path_suffix + path_name + 1); + if (!file) { + umount_dev(); + return -ENOMEM; + } + + strncpy(file, DFU_MOUNT_PATH, path_prefix + 1); + strncat(file, entry[DFU_INFO_PATH], path_suffix + 1); + strncat(file, entry[DFU_INFO_NAME], path_name + 1); + break; + } + default: + fprintf(stderr, + "flash entry '%s' has wrong mode\n", + entry_name); + return -EINVAL; + } + } + } + + if (file) + break; + } + + if (!file) + return -EINVAL; + + fd = open(file, O_WRONLY); + if (fd < 0) { + fprintf(stderr, + "cannot open target: %s\n", name); + fd = -EIO; + } + + free(file); + + return fd; +} + +/* Set entry values for dfu */ static int dfu_start_entry(struct dfu_entry *e, char **entry, uint64_t size) { char *file; @@ -480,6 +560,8 @@ static int dfu_start_entry(struct dfu_entry *e, char **entry, uint64_t size) e->buf_len = 0; e->transfer_done = 0; + /* Check if there is the slot B */ + e->fd_b = find_slot_b(e->ctx, entry[DFU_INFO_NAME]); err: free(file); @@ -515,6 +597,8 @@ struct dfu_entry *dfu_start(struct dfu_context *ctx, if (!e) return NULL; + e->ctx = ctx; + ret = dfu_start_entry(e, entry, size); if (ret < 0) { fprintf(stderr, "Cannot start download: %s\n", filename); @@ -527,7 +611,6 @@ struct dfu_entry *dfu_start(struct dfu_context *ctx, else fprintf(stdout, "\n%s", filename); - e->ctx = ctx; pthread_create(&ctx->thread, NULL, dfu_thread_main, e); return e; @@ -544,6 +627,7 @@ void dfu_sync(struct dfu_entry *e) pthread_mutex_unlock(&ctx->sync_mutex); close(e->fd); + close(e->fd_b); if (*info[DFU_INFO_MODE] == DFU_INFO_MODE_FILE) umount_dev(); diff --git a/src/dfu.h b/src/dfu.h index adceb71..7daf828 100644 --- a/src/dfu.h +++ b/src/dfu.h @@ -25,7 +25,8 @@ struct dfu_context; struct dfu_entry { struct dfu_context *ctx; char **entry; - int fd; + int fd; /* FD of slot A */ + int fd_b; /* FD of Slot B */ uint64_t file_size; /* size of a flashing file */ void *buffer; /* receive buffer for flashing */ unsigned long buf_len; /* filled size of buffer */