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>
(cherry picked from commit 6af45b842b)
			
			
This commit is contained in:
		| @@ -22,11 +22,19 @@ | |||||||
| #define le32_to_cpu(x)	bswap_32(x) | #define le32_to_cpu(x)	bswap_32(x) | ||||||
| #define cpu_to_be32(x)	(x) | #define cpu_to_be32(x)	(x) | ||||||
| #define be32_to_cpu(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 | #elif __BYTE_ORDER == __LITTLE_ENDIAN | ||||||
| #define cpu_to_le32(x)	(x) | #define cpu_to_le32(x)	(x) | ||||||
| #define le32_to_cpu(x)	(x) | #define le32_to_cpu(x)	(x) | ||||||
| #define cpu_to_be32(x)	bswap_32(x) | #define cpu_to_be32(x)	bswap_32(x) | ||||||
| #define be32_to_cpu(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 | #else | ||||||
| #error "Unsupported endianness" | #error "Unsupported endianness" | ||||||
| #endif | #endif | ||||||
| @@ -57,6 +65,7 @@ struct bcm4908img_tail { | |||||||
| struct bcm4908img_info { | struct bcm4908img_info { | ||||||
| 	size_t file_size; | 	size_t file_size; | ||||||
| 	size_t vendor_header_size;	/* Vendor header size */ | 	size_t vendor_header_size;	/* Vendor header size */ | ||||||
|  | 	size_t cferom_size; | ||||||
| 	uint32_t crc32;			/* Calculated checksum */ | 	uint32_t crc32;			/* Calculated checksum */ | ||||||
| 	struct bcm4908img_tail tail; | 	struct bcm4908img_tail tail; | ||||||
| }; | }; | ||||||
| @@ -203,6 +212,7 @@ static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) { | |||||||
| 	struct chk_header *chk; | 	struct chk_header *chk; | ||||||
| 	struct stat st; | 	struct stat st; | ||||||
| 	uint8_t buf[1024]; | 	uint8_t buf[1024]; | ||||||
|  | 	uint16_t tmp16; | ||||||
| 	size_t length; | 	size_t length; | ||||||
| 	size_t bytes; | 	size_t bytes; | ||||||
| 	int err = 0; | 	int err = 0; | ||||||
| @@ -229,6 +239,26 @@ static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) { | |||||||
| 	if (be32_to_cpu(chk->magic) == 0x2a23245e) | 	if (be32_to_cpu(chk->magic) == 0x2a23245e) | ||||||
| 		info->vendor_header_size = be32_to_cpu(chk->header_len); | 		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 */ | 	/* CRC32 */ | ||||||
|  |  | ||||||
| 	fseek(fp, info->vendor_header_size, SEEK_SET); | 	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("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); | 	printf("Checksum:\t0x%08x\n", info.crc32); | ||||||
|  |  | ||||||
| err_close: | err_close: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Rafał Miłecki
					Rafał Miłecki