oseama: small util for reading Seama image format info
It's similar to otrx, we need this tool for handling sysupgrade. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 48533
This commit is contained in:
parent
2911212962
commit
92443f7041
3 changed files with 287 additions and 0 deletions
43
package/utils/oseama/Makefile
Normal file
43
package/utils/oseama/Makefile
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#
|
||||||
|
# Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=oseama
|
||||||
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Package/oseama
|
||||||
|
SECTION:=utils
|
||||||
|
CATEGORY:=Base system
|
||||||
|
TITLE:=Utility for handling Seama firmware images
|
||||||
|
MAINTAINER:=Rafał Miłecki <zajec5@gmail.com>
|
||||||
|
DEPENDS:=@TARGET_bcm53xx
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/oseama/description
|
||||||
|
This package contains an utility that allows handling Seama images.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Prepare
|
||||||
|
mkdir -p $(PKG_BUILD_DIR)
|
||||||
|
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||||
|
CC="$(TARGET_CC)" \
|
||||||
|
CFLAGS="$(TARGET_CFLAGS) -Wall"
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/oseama/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/bin
|
||||||
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/oseama $(1)/usr/bin/
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,oseama))
|
7
package/utils/oseama/src/Makefile
Normal file
7
package/utils/oseama/src/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
all: oseama
|
||||||
|
|
||||||
|
oseama:
|
||||||
|
$(CC) $(CFLAGS) -o $@ oseama.c -Wall
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f oseama
|
237
package/utils/oseama/src/oseama.c
Normal file
237
package/utils/oseama/src/oseama.c
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
/*
|
||||||
|
* oseama
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <byteswap.h>
|
||||||
|
#include <endian.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#if !defined(__BYTE_ORDER)
|
||||||
|
#error "Unknown byte order"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
#define cpu_to_be32(x) (x)
|
||||||
|
#define be32_to_cpu(x) (x)
|
||||||
|
#define cpu_to_be16(x) (x)
|
||||||
|
#define be16_to_cpu(x) (x)
|
||||||
|
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
#define cpu_to_be32(x) bswap_32(x)
|
||||||
|
#define be32_to_cpu(x) bswap_32(x)
|
||||||
|
#define cpu_to_be16(x) bswap_16(x)
|
||||||
|
#define be16_to_cpu(x) bswap_16(x)
|
||||||
|
#else
|
||||||
|
#error "Unsupported endianness"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SEAMA_MAGIC 0x5ea3a417
|
||||||
|
|
||||||
|
struct seama_seal_header {
|
||||||
|
uint32_t magic;
|
||||||
|
uint16_t reserved;
|
||||||
|
uint16_t metasize;
|
||||||
|
uint32_t imagesize;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct seama_entity_header {
|
||||||
|
uint32_t magic;
|
||||||
|
uint16_t reserved;
|
||||||
|
uint16_t metasize;
|
||||||
|
uint32_t imagesize;
|
||||||
|
uint8_t md5[16];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
char *seama_path;
|
||||||
|
int entity_idx = -1;
|
||||||
|
|
||||||
|
static inline size_t oseama_min(size_t x, size_t y) {
|
||||||
|
return x < y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* Info
|
||||||
|
**************************************************/
|
||||||
|
|
||||||
|
static void oseama_info_parse_options(int argc, char **argv) {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
while ((c = getopt(argc, argv, "e:")) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'e':
|
||||||
|
entity_idx = atoi(optarg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oseama_info_entities(FILE *seama) {
|
||||||
|
struct seama_entity_header hdr;
|
||||||
|
size_t bytes, metasize, imagesize;
|
||||||
|
uint8_t buf[1024];
|
||||||
|
char *end, *tmp;
|
||||||
|
int i = 0;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
while ((bytes = fread(&hdr, 1, sizeof(hdr), seama)) == sizeof(hdr)) {
|
||||||
|
if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) {
|
||||||
|
fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic));
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
metasize = be16_to_cpu(hdr.metasize);
|
||||||
|
imagesize = be32_to_cpu(hdr.imagesize);
|
||||||
|
|
||||||
|
if (entity_idx >= 0 && i != entity_idx) {
|
||||||
|
fseek(seama, metasize + imagesize, SEEK_CUR);
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metasize >= sizeof(buf)) {
|
||||||
|
fprintf(stderr, "Too small buffer (%zu B) to read all meta info (%zd B)\n", sizeof(buf), metasize);
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity_idx < 0)
|
||||||
|
printf("\n");
|
||||||
|
printf("Entity offset:\t%ld\n", ftell(seama) - sizeof(hdr));
|
||||||
|
printf("Entity size:\t%zd\n", sizeof(hdr) + metasize + imagesize);
|
||||||
|
printf("Meta size:\t%zd\n", metasize);
|
||||||
|
printf("Image size:\t%zd\n", imagesize);
|
||||||
|
|
||||||
|
bytes = fread(buf, 1, metasize, seama);
|
||||||
|
if (bytes != metasize) {
|
||||||
|
fprintf(stderr, "Couldn't read %zd B of meta\n", metasize);
|
||||||
|
err = -EIO;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = (char *)&buf[metasize - 1];
|
||||||
|
*end = '\0';
|
||||||
|
for (tmp = (char *)buf; tmp < end && strlen(tmp); tmp += strlen(tmp) + 1) {
|
||||||
|
printf("Meta entry:\t%s\n", tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(seama, imagesize, SEEK_CUR);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int oseama_info(int argc, char **argv) {
|
||||||
|
FILE *seama;
|
||||||
|
struct seama_seal_header hdr;
|
||||||
|
size_t bytes;
|
||||||
|
uint16_t metasize;
|
||||||
|
uint32_t imagesize;
|
||||||
|
uint8_t buf[1024];
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
fprintf(stderr, "No Seama file passed\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
seama_path = argv[2];
|
||||||
|
|
||||||
|
optind = 3;
|
||||||
|
oseama_info_parse_options(argc, argv);
|
||||||
|
|
||||||
|
seama = fopen(seama_path, "r");
|
||||||
|
if (!seama) {
|
||||||
|
fprintf(stderr, "Couldn't open %s\n", seama_path);
|
||||||
|
err = -EACCES;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes = fread(&hdr, 1, sizeof(hdr), seama);
|
||||||
|
if (bytes != sizeof(hdr)) {
|
||||||
|
fprintf(stderr, "Couldn't read %s header\n", seama_path);
|
||||||
|
err = -EIO;
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
metasize = be16_to_cpu(hdr.metasize);
|
||||||
|
imagesize = be32_to_cpu(hdr.imagesize);
|
||||||
|
|
||||||
|
if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) {
|
||||||
|
fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic));
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metasize >= sizeof(buf)) {
|
||||||
|
fprintf(stderr, "Too small buffer (%zu B) to read all meta info (%d B)\n", sizeof(buf), metasize);
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imagesize) {
|
||||||
|
fprintf(stderr, "Invalid Seama image size: 0x%08x (should be 0)\n", imagesize);
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes = fread(buf, 1, metasize, seama);
|
||||||
|
if (bytes != metasize) {
|
||||||
|
fprintf(stderr, "Couldn't read %d B of meta\n", metasize);
|
||||||
|
err = -EIO;
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity_idx < 0) {
|
||||||
|
char *end, *tmp;
|
||||||
|
|
||||||
|
printf("Meta size:\t%d\n", metasize);
|
||||||
|
printf("Image size:\t%d\n", imagesize);
|
||||||
|
|
||||||
|
end = (char *)&buf[metasize - 1];
|
||||||
|
*end = '\0';
|
||||||
|
for (tmp = (char *)buf; tmp < end && strlen(tmp); tmp += strlen(tmp) + 1) {
|
||||||
|
printf("Meta entry:\t%s\n", tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oseama_info_entities(seama);
|
||||||
|
|
||||||
|
err_close:
|
||||||
|
fclose(seama);
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* Start
|
||||||
|
**************************************************/
|
||||||
|
|
||||||
|
static void usage() {
|
||||||
|
printf("Usage:\n");
|
||||||
|
printf("\n");
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
if (argc > 1) {
|
||||||
|
if (!strcmp(argv[1], "info"))
|
||||||
|
return oseama_info(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue