firmware-utils: bcm4908img: extract parsing code
Move code parsing existing firmware file to separated function. This
cleans up existing code and allows reusing parsing code for other
commands.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
(cherry picked from commit 7d5f743942)
			
			
This commit is contained in:
		| @@ -49,6 +49,13 @@ struct bcm4908img_tail { | |||||||
| 	uint32_t flags; | 	uint32_t flags; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /* Info about BCM4908 image */ | ||||||
|  | struct bcm4908img_info { | ||||||
|  | 	size_t file_size; | ||||||
|  | 	uint32_t crc32;			/* Calculated checksum */ | ||||||
|  | 	struct bcm4908img_tail tail; | ||||||
|  | }; | ||||||
|  |  | ||||||
| char *pathname; | char *pathname; | ||||||
| static size_t prefix_len; | static size_t prefix_len; | ||||||
| static size_t suffix_len; | static size_t suffix_len; | ||||||
| @@ -138,6 +145,61 @@ uint32_t bcm4908img_crc32(uint32_t crc, uint8_t *buf, size_t len) { | |||||||
| 	return crc; | 	return crc; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /************************************************** | ||||||
|  |  * Existing firmware parser | ||||||
|  |  **************************************************/ | ||||||
|  |  | ||||||
|  | static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) { | ||||||
|  | 	struct bcm4908img_tail *tail = &info->tail; | ||||||
|  | 	struct stat st; | ||||||
|  | 	uint8_t buf[1024]; | ||||||
|  | 	size_t length; | ||||||
|  | 	size_t bytes; | ||||||
|  | 	int err = 0; | ||||||
|  |  | ||||||
|  | 	memset(info, 0, sizeof(*info)); | ||||||
|  |  | ||||||
|  | 	/* File size */ | ||||||
|  |  | ||||||
|  | 	if (fstat(fileno(fp), &st)) { | ||||||
|  | 		err = -errno; | ||||||
|  | 		fprintf(stderr, "Failed to fstat: %d\n", err); | ||||||
|  | 		return err; | ||||||
|  | 	} | ||||||
|  | 	info->file_size = st.st_size; | ||||||
|  |  | ||||||
|  | 	/* CRC32 */ | ||||||
|  |  | ||||||
|  | 	fseek(fp, prefix_len, SEEK_SET); | ||||||
|  |  | ||||||
|  | 	info->crc32 = 0xffffffff; | ||||||
|  | 	length = info->file_size - prefix_len - sizeof(*tail) - suffix_len; | ||||||
|  | 	while (length && (bytes = fread(buf, 1, bcm4908img_min(sizeof(buf), length), fp)) > 0) { | ||||||
|  | 		info->crc32 = bcm4908img_crc32(info->crc32, buf, bytes); | ||||||
|  | 		length -= bytes; | ||||||
|  | 	} | ||||||
|  | 	if (length) { | ||||||
|  | 		fprintf(stderr, "Failed to read last %zd B of data\n", length); | ||||||
|  | 		return -EIO; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* Tail */ | ||||||
|  |  | ||||||
|  | 	if (fread(tail, 1, sizeof(*tail), fp) != sizeof(*tail)) { | ||||||
|  | 		fprintf(stderr, "Failed to read BCM4908 image tail\n"); | ||||||
|  | 		return -EIO; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* Standard validation */ | ||||||
|  |  | ||||||
|  | 	if (info->crc32 != le32_to_cpu(tail->crc32)) { | ||||||
|  | 		fprintf(stderr, "Invalid data crc32: 0x%08x instead of 0x%08x\n", info->crc32, le32_to_cpu(tail->crc32)); | ||||||
|  | 		return -EPROTO; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| /************************************************** | /************************************************** | ||||||
|  * Check |  * Check | ||||||
|  **************************************************/ |  **************************************************/ | ||||||
| @@ -158,12 +220,7 @@ static void bcm4908img_check_parse_options(int argc, char **argv) { | |||||||
| } | } | ||||||
|  |  | ||||||
| static int bcm4908img_check(int argc, char **argv) { | static int bcm4908img_check(int argc, char **argv) { | ||||||
| 	struct bcm4908img_tail tail; | 	struct bcm4908img_info info; | ||||||
| 	struct stat st; |  | ||||||
| 	uint8_t buf[1024]; |  | ||||||
| 	uint32_t crc32; |  | ||||||
| 	size_t length; |  | ||||||
| 	size_t bytes; |  | ||||||
| 	FILE *fp; | 	FILE *fp; | ||||||
| 	int err = 0; | 	int err = 0; | ||||||
|  |  | ||||||
| @@ -177,12 +234,6 @@ static int bcm4908img_check(int argc, char **argv) { | |||||||
| 	optind = 3; | 	optind = 3; | ||||||
| 	bcm4908img_check_parse_options(argc, argv); | 	bcm4908img_check_parse_options(argc, argv); | ||||||
|  |  | ||||||
| 	if (stat(pathname, &st)) { |  | ||||||
| 		fprintf(stderr, "Failed to stat %s\n", pathname); |  | ||||||
| 		err = -EIO; |  | ||||||
| 		goto out; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	fp = fopen(pathname, "r"); | 	fp = fopen(pathname, "r"); | ||||||
| 	if (!fp) { | 	if (!fp) { | ||||||
| 		fprintf(stderr, "Failed to open %s\n", pathname); | 		fprintf(stderr, "Failed to open %s\n", pathname); | ||||||
| @@ -190,34 +241,13 @@ static int bcm4908img_check(int argc, char **argv) { | |||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fseek(fp, prefix_len, SEEK_SET); | 	err = bcm4908img_parse(fp, &info); | ||||||
|  | 	if (err) { | ||||||
| 	crc32 = 0xffffffff; | 		fprintf(stderr, "Failed to parse %s\n", pathname); | ||||||
| 	length = st.st_size - prefix_len - sizeof(tail) - suffix_len; |  | ||||||
| 	while (length && (bytes = fread(buf, 1, bcm4908img_min(sizeof(buf), length), fp)) > 0) { |  | ||||||
| 		crc32 = bcm4908img_crc32(crc32, buf, bytes); |  | ||||||
| 		length -= bytes; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (length) { |  | ||||||
| 		fprintf(stderr, "Failed to read last %zd B of data from %s\n", length, pathname); |  | ||||||
| 		err = -EIO; |  | ||||||
| 		goto err_close; | 		goto err_close; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (fread(&tail, 1, sizeof(tail), fp) != sizeof(tail)) { | 	printf("Found a valid BCM4908 image (crc: 0x%08x)\n", info.crc32); | ||||||
| 		fprintf(stderr, "Failed to read BCM4908 image tail\n"); |  | ||||||
| 		err = -EIO; |  | ||||||
| 		goto err_close; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (crc32 != le32_to_cpu(tail.crc32)) { |  | ||||||
| 		fprintf(stderr, "Invalid data crc32: 0x%08x instead of 0x%08x\n", crc32, le32_to_cpu(tail.crc32)); |  | ||||||
| 		err =  -EPROTO; |  | ||||||
| 		goto err_close; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	printf("Found a valid BCM4908 image (crc: 0x%08x)\n", crc32); |  | ||||||
|  |  | ||||||
| err_close: | err_close: | ||||||
| 	fclose(fp); | 	fclose(fp); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Rafał Miłecki
					Rafał Miłecki