diff options
author | Rafał Miłecki <rafal@milecki.pl> | 2021-04-07 07:59:57 +0200 |
---|---|---|
committer | Rafał Miłecki <rafal@milecki.pl> | 2021-04-07 08:02:41 +0200 |
commit | ed7edf88e20c9dd0026e5c5629d8a6500d3e3f80 (patch) | |
tree | 42fd225f50cec6c781eead7084b97142d4d1e927 /tools/firmware-utils/src | |
parent | dcbde11af181055f2d1c77ebc19f50c29bbab96e (diff) | |
download | upstream-ed7edf88e20c9dd0026e5c5629d8a6500d3e3f80.tar.gz upstream-ed7edf88e20c9dd0026e5c5629d8a6500d3e3f80.tar.bz2 upstream-ed7edf88e20c9dd0026e5c5629d8a6500d3e3f80.zip |
firmware-utils: bcm4908img: extract bootfs without padding
JFFS2 bootfs partition in a BCM4908 image usually includes some padding.
For flashing it individually (writing to designed MTD partition) we want
just JFFS2 data.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Diffstat (limited to 'tools/firmware-utils/src')
-rw-r--r-- | tools/firmware-utils/src/bcm4908img.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/tools/firmware-utils/src/bcm4908img.c b/tools/firmware-utils/src/bcm4908img.c index b82303bf6d..d97e54e0f6 100644 --- a/tools/firmware-utils/src/bcm4908img.c +++ b/tools/firmware-utils/src/bcm4908img.c @@ -6,6 +6,7 @@ #include <byteswap.h> #include <endian.h> #include <errno.h> +#include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> @@ -81,6 +82,7 @@ struct bcm4908img_info { size_t file_size; size_t cferom_offset; size_t bootfs_offset; + size_t padding_offset; size_t rootfs_offset; uint32_t crc32; /* Calculated checksum */ struct bcm4908img_tail tail; @@ -247,6 +249,19 @@ struct chk_header { char board_id[0]; }; +static bool bcm4908img_is_all_ff(const void *buf, size_t length) +{ + const uint8_t *in = buf; + int i; + + for (i = 0; i < length; i++) { + if (in[i] != 0xff) + return false; + } + + return true; +} + static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) { struct bcm4908img_tail *tail = &info->tail; struct chk_header *chk; @@ -304,7 +319,7 @@ static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) { for (info->rootfs_offset = info->bootfs_offset; info->rootfs_offset < info->file_size; info->rootfs_offset += 0x20000) { - uint32_t magic; + uint32_t *magic = (uint32_t *)&buf[0]; if (fseek(fp, info->rootfs_offset, SEEK_SET)) { err = -errno; @@ -312,13 +327,17 @@ static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) { return err; } - bytes = fread(&magic, 1, sizeof(magic), fp); - if (bytes != sizeof(magic)) { - fprintf(stderr, "Failed to read %zu bytes\n", sizeof(magic)); + length = info->padding_offset ? sizeof(*magic) : 256; + bytes = fread(buf, 1, length, fp); + if (bytes != length) { + fprintf(stderr, "Failed to read %zu bytes\n", length); return -EIO; } - if (be32_to_cpu(magic) == UBI_EC_HDR_MAGIC) + if (!info->padding_offset && bcm4908img_is_all_ff(buf, length)) + info->padding_offset = info->rootfs_offset; + + if (be32_to_cpu(*magic) == UBI_EC_HDR_MAGIC) break; } if (info->rootfs_offset >= info->file_size) { @@ -394,6 +413,8 @@ static int bcm4908img_info(int argc, char **argv) { if (info.bootfs_offset != info.cferom_offset) printf("cferom offset:\t%zu\n", info.cferom_offset); printf("bootfs offset:\t0x%zx\n", info.bootfs_offset); + if (info.padding_offset) + printf("padding offset:\t0x%zx\n", info.padding_offset); printf("rootfs offset:\t0x%zx\n", info.rootfs_offset); printf("Checksum:\t0x%08x\n", info.crc32); @@ -589,7 +610,7 @@ static int bcm4908img_extract(int argc, char **argv) { } } else if (!strcmp(type, "bootfs")) { offset = info.bootfs_offset; - length = info.rootfs_offset - offset; + length = (info.padding_offset ? info.padding_offset : info.rootfs_offset) - offset; } else if (!strcmp(type, "rootfs")) { offset = info.rootfs_offset; length = info.file_size - offset - sizeof(struct bcm4908img_tail); |