aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorRafał Miłecki <rafal@milecki.pl>2021-04-02 15:04:46 +0200
committerRafał Miłecki <rafal@milecki.pl>2021-04-05 10:05:09 +0200
commit6af45b842bd22633fa3ccd57edaf073a759525bb (patch)
tree9f9aa2abdb65cda13af2ec648710a555c6a7a6c6 /tools
parent9b9184f1782489163eb204f3b238de778ae1214b (diff)
downloadupstream-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.c31
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: