aboutsummaryrefslogtreecommitdiffstats
path: root/package/utils/oseama/src/oseama.c
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2016-01-29 22:21:45 +0000
committerRafał Miłecki <zajec5@gmail.com>2016-01-29 22:21:45 +0000
commite4e7f249209c4782039877cf00d11a763b50336d (patch)
treee87c77e43825f850b5c7abba53c0ac9dcccebcff /package/utils/oseama/src/oseama.c
parent6064710b90b6138c3471129090ab4192710be42c (diff)
downloadupstream-e4e7f249209c4782039877cf00d11a763b50336d.tar.gz
upstream-e4e7f249209c4782039877cf00d11a763b50336d.tar.bz2
upstream-e4e7f249209c4782039877cf00d11a763b50336d.zip
oseama: support creating single Seama entity
This will be needed to handle sysupgrade on NAND in a smart way. We'll need to extract kernel our of provided Seama container, put in in a new Seama entity and flash. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 48552
Diffstat (limited to 'package/utils/oseama/src/oseama.c')
-rw-r--r--package/utils/oseama/src/oseama.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/package/utils/oseama/src/oseama.c b/package/utils/oseama/src/oseama.c
index 81a73d5e2b..37a2171574 100644
--- a/package/utils/oseama/src/oseama.c
+++ b/package/utils/oseama/src/oseama.c
@@ -18,6 +18,8 @@
#include <string.h>
#include <unistd.h>
+#include "md5.h"
+
#if !defined(__BYTE_ORDER)
#error "Unknown byte order"
#endif
@@ -215,6 +217,181 @@ out:
}
/**************************************************
+ * Create
+ **************************************************/
+
+static ssize_t oseama_entity_append_file(FILE *seama, const char *in_path) {
+ FILE *in;
+ size_t bytes;
+ ssize_t length = 0;
+ uint8_t buf[128];
+
+ in = fopen(in_path, "r");
+ if (!in) {
+ fprintf(stderr, "Couldn't open %s\n", in_path);
+ return -EACCES;
+ }
+
+ while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) {
+ if (fwrite(buf, 1, bytes, seama) != bytes) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, seama_path);
+ length = -EIO;
+ break;
+ }
+ length += bytes;
+ }
+
+ fclose(in);
+
+ return length;
+}
+
+static ssize_t oseama_entity_append_zeros(FILE *seama, size_t length) {
+ uint8_t *buf;
+
+ buf = malloc(length);
+ if (!buf)
+ return -ENOMEM;
+ memset(buf, 0, length);
+
+ if (fwrite(buf, 1, length, seama) != length) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", length, seama_path);
+ return -EIO;
+ }
+
+ return length;
+}
+
+static ssize_t oseama_entity_align(FILE *seama, size_t curr_offset, size_t alignment) {
+ if (curr_offset & (alignment - 1)) {
+ size_t length = alignment - (curr_offset % alignment);
+
+ return oseama_entity_append_zeros(seama, length);
+ }
+
+ return 0;
+}
+
+static int oseama_entity_write_hdr(FILE *seama, size_t metasize, size_t imagesize) {
+ struct seama_entity_header hdr = {};
+ uint8_t buf[128];
+ size_t length = imagesize;
+ size_t bytes;
+ MD5_CTX ctx;
+
+ fseek(seama, sizeof(hdr) + metasize, SEEK_SET);
+ MD5_Init(&ctx);
+ while ((bytes = fread(buf, 1, oseama_min(sizeof(buf), length), seama)) > 0) {
+ MD5_Update(&ctx, buf, bytes);
+ length -= bytes;
+ }
+ MD5_Final(hdr.md5, &ctx);
+
+ hdr.magic = cpu_to_be32(SEAMA_MAGIC);
+ hdr.metasize = cpu_to_be16(metasize);
+ hdr.imagesize = cpu_to_be32(imagesize);
+
+ fseek(seama, 0, SEEK_SET);
+ bytes = fwrite(&hdr, 1, sizeof(hdr), seama);
+ if (bytes != sizeof(hdr)) {
+ fprintf(stderr, "Couldn't write Seama entity header to %s\n", seama_path);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int oseama_entity(int argc, char **argv) {
+ FILE *seama;
+ ssize_t sbytes;
+ size_t curr_offset = sizeof(struct seama_entity_header);
+ size_t metasize = 0, imagesize = 0;
+ int c;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "No Seama file passed\n");
+ err = -EINVAL;
+ goto out;
+ }
+ seama_path = argv[2];
+
+ seama = fopen(seama_path, "w+");
+ if (!seama) {
+ fprintf(stderr, "Couldn't open %s\n", seama_path);
+ err = -EACCES;
+ goto out;
+ }
+ fseek(seama, curr_offset, SEEK_SET);
+
+ optind = 3;
+ while ((c = getopt(argc, argv, "m:f:b:")) != -1) {
+ switch (c) {
+ case 'm':
+ sbytes = fwrite(optarg, 1, strlen(optarg) + 1, seama);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to write meta %s\n", optarg);
+ } else {
+ curr_offset += sbytes;
+ metasize += sbytes;
+ }
+
+ sbytes = oseama_entity_align(seama, curr_offset, 4);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to append zeros\n");
+ } else {
+ curr_offset += sbytes;
+ metasize += sbytes;
+ }
+
+ break;
+ case 'f':
+ case 'b':
+ break;
+ }
+ }
+
+ optind = 3;
+ while ((c = getopt(argc, argv, "m:f:b:")) != -1) {
+ switch (c) {
+ case 'm':
+ break;
+ case 'f':
+ sbytes = oseama_entity_append_file(seama, optarg);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to append file %s\n", optarg);
+ } else {
+ curr_offset += sbytes;
+ imagesize += sbytes;
+ }
+ break;
+ case 'b':
+ sbytes = strtol(optarg, NULL, 0) - curr_offset;
+ if (sbytes < 0) {
+ fprintf(stderr, "Current Seama entity length is 0x%zx, can't pad it with zeros to 0x%lx\n", curr_offset, strtol(optarg, NULL, 0));
+ } else {
+ sbytes = oseama_entity_append_zeros(seama, sbytes);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to append zeros\n");
+ } else {
+ curr_offset += sbytes;
+ imagesize += sbytes;
+ }
+ }
+ break;
+ }
+ if (err)
+ break;
+ }
+
+ oseama_entity_write_hdr(seama, metasize, imagesize);
+
+ fclose(seama);
+out:
+ return err;
+}
+
+/**************************************************
* Start
**************************************************/
@@ -224,12 +401,20 @@ static void usage() {
printf("Info about Seama seal (container):\n");
printf("\toseama info <file> [options]\n");
printf("\t-e\t\t\t\tprint info about specified entity only\n");
+ printf("\n");
+ printf("Create Seama entity:\n");
+ printf("\toseama entity <file> [options]\n");
+ printf("\t-m meta\t\t\t\tmeta into to put in header\n");
+ printf("\t-f file\t\t\t\tappend content from file\n");
+ printf("\t-b offset\t\t\tappend zeros till reaching absolute offset\n");
}
int main(int argc, char **argv) {
if (argc > 1) {
if (!strcmp(argv[1], "info"))
return oseama_info(argc, argv);
+ else if (!strcmp(argv[1], "entity"))
+ return oseama_entity(argc, argv);
}
usage();