diff options
author | Rafał Miłecki <rafal@milecki.pl> | 2021-04-02 15:04:46 +0200 |
---|---|---|
committer | Rafał Miłecki <rafal@milecki.pl> | 2021-04-05 10:05:09 +0200 |
commit | 6af45b842bd22633fa3ccd57edaf073a759525bb (patch) | |
tree | 9f9aa2abdb65cda13af2ec648710a555c6a7a6c6 /tools | |
parent | 9b9184f1782489163eb204f3b238de778ae1214b (diff) | |
download | upstream-6af45b842bd22633fa3ccd57edaf073a759525bb.tar.gz upstream-6af45b842bd22633fa3ccd57edaf073a759525bb.tar.bz2 upstream-6af45b842bd22633fa3ccd57edaf073a759525bb.zip |
firmware-utils: bcm4908img: find cferom size
It's important for modifying / extracting firmware content. cferom is
optional image content at the file beginning.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/firmware-utils/src/bcm4908img.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/tools/firmware-utils/src/bcm4908img.c b/tools/firmware-utils/src/bcm4908img.c index 56a790423b..b04916443b 100644 --- a/tools/firmware-utils/src/bcm4908img.c +++ b/tools/firmware-utils/src/bcm4908img.c @@ -22,11 +22,19 @@ #define le32_to_cpu(x) bswap_32(x) #define cpu_to_be32(x) (x) #define be32_to_cpu(x) (x) +#define cpu_to_le16(x) bswap_16(x) +#define le16_to_cpu(x) bswap_16(x) +#define cpu_to_be16(x) (x) +#define be16_to_cpu(x) (x) #elif __BYTE_ORDER == __LITTLE_ENDIAN #define cpu_to_le32(x) (x) #define le32_to_cpu(x) (x) #define cpu_to_be32(x) bswap_32(x) #define be32_to_cpu(x) bswap_32(x) +#define cpu_to_le16(x) (x) +#define le16_to_cpu(x) (x) +#define cpu_to_be16(x) bswap_16(x) +#define be16_to_cpu(x) bswap_16(x) #else #error "Unsupported endianness" #endif @@ -57,6 +65,7 @@ struct bcm4908img_tail { struct bcm4908img_info { size_t file_size; size_t vendor_header_size; /* Vendor header size */ + size_t cferom_size; uint32_t crc32; /* Calculated checksum */ struct bcm4908img_tail tail; }; @@ -203,6 +212,7 @@ static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) { struct chk_header *chk; struct stat st; uint8_t buf[1024]; + uint16_t tmp16; size_t length; size_t bytes; int err = 0; @@ -229,6 +239,26 @@ static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) { if (be32_to_cpu(chk->magic) == 0x2a23245e) info->vendor_header_size = be32_to_cpu(chk->header_len); + /* Sizes */ + + for (; info->vendor_header_size + info->cferom_size <= info->file_size; info->cferom_size += 0x20000) { + if (fseek(fp, info->vendor_header_size + info->cferom_size, SEEK_SET)) { + err = -errno; + fprintf(stderr, "Failed to fseek to the 0x%zx\n", info->cferom_size); + return err; + } + if (fread(&tmp16, 1, sizeof(tmp16), fp) != sizeof(tmp16)) { + fprintf(stderr, "Failed to read while looking for JFFS2\n"); + return -EIO; + } + if (be16_to_cpu(tmp16) == 0x8519) + break; + } + if (info->vendor_header_size + info->cferom_size >= info->file_size) { + fprintf(stderr, "Failed to find cferom size (no bootfs found)\n"); + return -EPROTO; + } + /* CRC32 */ fseek(fp, info->vendor_header_size, SEEK_SET); @@ -294,6 +324,7 @@ static int bcm4908img_info(int argc, char **argv) { } printf("Vendor header length:\t%zu\n", info.vendor_header_size); + printf("cferom size:\t0x%zx\n", info.cferom_size); printf("Checksum:\t0x%08x\n", info.crc32); err_close: |