mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-17 10:20:01 +00:00
firmware-utils: bcm4908img: extract bootfs without padding
JFFS2 bootfs partition in a BCM4908 image usually includes some padding. For flashing it individually (writing to designed MTD partition) we want just JFFS2 data. Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
parent
dcbde11af1
commit
ed7edf88e2
@ -6,6 +6,7 @@
|
|||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -81,6 +82,7 @@ struct bcm4908img_info {
|
|||||||
size_t file_size;
|
size_t file_size;
|
||||||
size_t cferom_offset;
|
size_t cferom_offset;
|
||||||
size_t bootfs_offset;
|
size_t bootfs_offset;
|
||||||
|
size_t padding_offset;
|
||||||
size_t rootfs_offset;
|
size_t rootfs_offset;
|
||||||
uint32_t crc32; /* Calculated checksum */
|
uint32_t crc32; /* Calculated checksum */
|
||||||
struct bcm4908img_tail tail;
|
struct bcm4908img_tail tail;
|
||||||
@ -247,6 +249,19 @@ struct chk_header {
|
|||||||
char board_id[0];
|
char board_id[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool bcm4908img_is_all_ff(const void *buf, size_t length)
|
||||||
|
{
|
||||||
|
const uint8_t *in = buf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
if (in[i] != 0xff)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) {
|
static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) {
|
||||||
struct bcm4908img_tail *tail = &info->tail;
|
struct bcm4908img_tail *tail = &info->tail;
|
||||||
struct chk_header *chk;
|
struct chk_header *chk;
|
||||||
@ -304,7 +319,7 @@ static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) {
|
|||||||
for (info->rootfs_offset = info->bootfs_offset;
|
for (info->rootfs_offset = info->bootfs_offset;
|
||||||
info->rootfs_offset < info->file_size;
|
info->rootfs_offset < info->file_size;
|
||||||
info->rootfs_offset += 0x20000) {
|
info->rootfs_offset += 0x20000) {
|
||||||
uint32_t magic;
|
uint32_t *magic = (uint32_t *)&buf[0];
|
||||||
|
|
||||||
if (fseek(fp, info->rootfs_offset, SEEK_SET)) {
|
if (fseek(fp, info->rootfs_offset, SEEK_SET)) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
@ -312,13 +327,17 @@ static int bcm4908img_parse(FILE *fp, struct bcm4908img_info *info) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = fread(&magic, 1, sizeof(magic), fp);
|
length = info->padding_offset ? sizeof(*magic) : 256;
|
||||||
if (bytes != sizeof(magic)) {
|
bytes = fread(buf, 1, length, fp);
|
||||||
fprintf(stderr, "Failed to read %zu bytes\n", sizeof(magic));
|
if (bytes != length) {
|
||||||
|
fprintf(stderr, "Failed to read %zu bytes\n", length);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (be32_to_cpu(magic) == UBI_EC_HDR_MAGIC)
|
if (!info->padding_offset && bcm4908img_is_all_ff(buf, length))
|
||||||
|
info->padding_offset = info->rootfs_offset;
|
||||||
|
|
||||||
|
if (be32_to_cpu(*magic) == UBI_EC_HDR_MAGIC)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (info->rootfs_offset >= info->file_size) {
|
if (info->rootfs_offset >= info->file_size) {
|
||||||
@ -394,6 +413,8 @@ static int bcm4908img_info(int argc, char **argv) {
|
|||||||
if (info.bootfs_offset != info.cferom_offset)
|
if (info.bootfs_offset != info.cferom_offset)
|
||||||
printf("cferom offset:\t%zu\n", info.cferom_offset);
|
printf("cferom offset:\t%zu\n", info.cferom_offset);
|
||||||
printf("bootfs offset:\t0x%zx\n", info.bootfs_offset);
|
printf("bootfs offset:\t0x%zx\n", info.bootfs_offset);
|
||||||
|
if (info.padding_offset)
|
||||||
|
printf("padding offset:\t0x%zx\n", info.padding_offset);
|
||||||
printf("rootfs offset:\t0x%zx\n", info.rootfs_offset);
|
printf("rootfs offset:\t0x%zx\n", info.rootfs_offset);
|
||||||
printf("Checksum:\t0x%08x\n", info.crc32);
|
printf("Checksum:\t0x%08x\n", info.crc32);
|
||||||
|
|
||||||
@ -589,7 +610,7 @@ static int bcm4908img_extract(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
} else if (!strcmp(type, "bootfs")) {
|
} else if (!strcmp(type, "bootfs")) {
|
||||||
offset = info.bootfs_offset;
|
offset = info.bootfs_offset;
|
||||||
length = info.rootfs_offset - offset;
|
length = (info.padding_offset ? info.padding_offset : info.rootfs_offset) - offset;
|
||||||
} else if (!strcmp(type, "rootfs")) {
|
} else if (!strcmp(type, "rootfs")) {
|
||||||
offset = info.rootfs_offset;
|
offset = info.rootfs_offset;
|
||||||
length = info.file_size - offset - sizeof(struct bcm4908img_tail);
|
length = info.file_size - offset - sizeof(struct bcm4908img_tail);
|
||||||
|
Loading…
Reference in New Issue
Block a user