mirror of
https://github.com/openwrt/openwrt.git
synced 2024-11-29 12:54:11 +08:00
firmware-utils: bcm4908img: support extracting image data
It's useful for upgrading cferom, firmware, etc. Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
parent
6af45b842b
commit
9c039d56a1
@ -469,6 +469,86 @@ out:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* Extract
|
||||||
|
**************************************************/
|
||||||
|
|
||||||
|
static int bcm4908img_extract(int argc, char **argv) {
|
||||||
|
struct bcm4908img_info info;
|
||||||
|
const char *pathname = NULL;
|
||||||
|
uint8_t buf[1024];
|
||||||
|
const char *type;
|
||||||
|
size_t offset;
|
||||||
|
size_t length;
|
||||||
|
size_t bytes;
|
||||||
|
FILE *fp;
|
||||||
|
int c;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
while ((c = getopt(argc, argv, "i:t:")) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'i':
|
||||||
|
pathname = optarg;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
type = optarg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fp = bcm4908img_open(pathname, "r");
|
||||||
|
if (!fp) {
|
||||||
|
fprintf(stderr, "Failed to open BCM4908 image\n");
|
||||||
|
err = -EACCES;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = bcm4908img_parse(fp, &info);
|
||||||
|
if (err) {
|
||||||
|
fprintf(stderr, "Failed to parse BCM4908 image\n");
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(type, "cferom")) {
|
||||||
|
offset = 0;
|
||||||
|
length = info.cferom_size;
|
||||||
|
if (!length) {
|
||||||
|
err = -ENOENT;
|
||||||
|
fprintf(stderr, "This BCM4908 image doesn't contain cferom\n");
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(type, "firmware")) {
|
||||||
|
offset = info.vendor_header_size + info.cferom_size;
|
||||||
|
length = info.file_size - offset - sizeof(struct bcm4908img_tail);
|
||||||
|
} else {
|
||||||
|
err = -EINVAL;
|
||||||
|
fprintf(stderr, "Unsupported extract type: %s\n", type);
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!length) {
|
||||||
|
err = -EINVAL;
|
||||||
|
fprintf(stderr, "No data to extract specified\n");
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fp, offset, SEEK_SET);
|
||||||
|
while (length && (bytes = fread(buf, 1, bcm4908img_min(sizeof(buf), length), fp)) > 0) {
|
||||||
|
fwrite(buf, bytes, 1, stdout);
|
||||||
|
length -= bytes;
|
||||||
|
}
|
||||||
|
if (length) {
|
||||||
|
err = -EIO;
|
||||||
|
fprintf(stderr, "Failed to read last %zd B of data\n", length);
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_close:
|
||||||
|
bcm4908img_close(fp);
|
||||||
|
err_out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************
|
/**************************************************
|
||||||
* Start
|
* Start
|
||||||
**************************************************/
|
**************************************************/
|
||||||
@ -485,6 +565,11 @@ static void usage() {
|
|||||||
printf("\t-f file\t\t\t\tadd data from specified file\n");
|
printf("\t-f file\t\t\t\tadd data from specified file\n");
|
||||||
printf("\t-a alignment\t\t\tpad image with zeros to specified alignment\n");
|
printf("\t-a alignment\t\t\tpad image with zeros to specified alignment\n");
|
||||||
printf("\t-A offset\t\t\t\tappend zeros until reaching specified offset\n");
|
printf("\t-A offset\t\t\t\tappend zeros until reaching specified offset\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Extracting from a BCM4908 image:\n");
|
||||||
|
printf("\tbcm4908img extract <options>\n");
|
||||||
|
printf("\t-i <file>\t\t\t\tinput BCM490 image\n");
|
||||||
|
printf("\t-t <type>\t\t\t\tone of: cferom, bootfs, rootfs, firmware\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
@ -494,6 +579,8 @@ int main(int argc, char **argv) {
|
|||||||
return bcm4908img_info(argc, argv);
|
return bcm4908img_info(argc, argv);
|
||||||
else if (!strcmp(argv[1], "create"))
|
else if (!strcmp(argv[1], "create"))
|
||||||
return bcm4908img_create(argc, argv);
|
return bcm4908img_create(argc, argv);
|
||||||
|
else if (!strcmp(argv[1], "extract"))
|
||||||
|
return bcm4908img_extract(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
usage();
|
usage();
|
||||||
|
Loading…
Reference in New Issue
Block a user