aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
authorMarkus Wigge <mwigge@marcant.net>2010-07-01 16:26:24 +0000
committerMarkus Wigge <mwigge@marcant.net>2010-07-01 16:26:24 +0000
commit25602743d16580389f3140b6227620edc583a456 (patch)
treeda66a21e2be0f54dcca64ba2b8dc608bfa17eeb7 /target
parentd306c9cb215c0346bba06f6957944c4cdc647a23 (diff)
downloadupstream-25602743d16580389f3140b6227620edc583a456.tar.gz
upstream-25602743d16580389f3140b6227620edc583a456.tar.bz2
upstream-25602743d16580389f3140b6227620edc583a456.zip
brcm47xx: added dual image support to flashmap driver
some CFE versions (i.e. WRT54G3Gv2-VF) expect two separate firmware images which each consume half of the available flash space. these changes check for the TRX header version and set the partition size correctly. Tested on G3Gv2-VF and Asus WL-500GP SVN-Revision: 22019
Diffstat (limited to 'target')
-rw-r--r--target/linux/brcm47xx/files/drivers/mtd/maps/bcm47xx-flash.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/target/linux/brcm47xx/files/drivers/mtd/maps/bcm47xx-flash.c b/target/linux/brcm47xx/files/drivers/mtd/maps/bcm47xx-flash.c
index 3ceec403cf..61605d3f4a 100644
--- a/target/linux/brcm47xx/files/drivers/mtd/maps/bcm47xx-flash.c
+++ b/target/linux/brcm47xx/files/drivers/mtd/maps/bcm47xx-flash.c
@@ -222,6 +222,37 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos,
}
+static int __init
+find_dual_image_off (struct mtd_info *mtd, size_t size)
+{
+ struct trx_header trx;
+ int off, blocksize;
+ size_t len;
+
+ blocksize = mtd->erasesize;
+ if (blocksize < 0x10000)
+ blocksize = 0x10000;
+
+ for (off = (128*1024); off < size; off += blocksize) {
+ memset(&trx, 0xe5, sizeof(trx));
+ /*
+ * Read into buffer
+ */
+ if (mtd->read(mtd, off, sizeof(trx), &len, (char *) &trx) ||
+ len != sizeof(trx))
+ continue;
+ /* found last TRX header */
+ if (le32_to_cpu(trx.magic) == TRX_MAGIC){
+ if (le32_to_cpu(trx.flag_version >> 16)==2){
+ printk("dual image TRX header found\n");
+ return size/2;
+ } else {
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
static int __init
@@ -232,7 +263,6 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
int off, blocksize;
u32 i, crc = ~0;
size_t len;
- struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
blocksize = mtd->erasesize;
if (blocksize < 0x10000)
@@ -318,6 +348,7 @@ struct mtd_partition * __init
init_mtd_partitions(struct mtd_info *mtd, size_t size)
{
int cfe_size;
+ int dual_image_offset = 0;
if ((cfe_size = find_cfe_size(mtd,size)) < 0)
return NULL;
@@ -336,10 +367,13 @@ init_mtd_partitions(struct mtd_info *mtd, size_t size)
bcm47xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
}
+ /* dual image offset*/
+ printk("Looking for dual image\n");
+ dual_image_offset=find_dual_image_off(mtd,size);
/* linux (kernel and rootfs) */
if (cfe_size != 384 * 1024) {
bcm47xx_parts[1].offset = bcm47xx_parts[0].size;
- bcm47xx_parts[1].size = bcm47xx_parts[3].offset -
+ bcm47xx_parts[1].size = bcm47xx_parts[3].offset - dual_image_offset -
bcm47xx_parts[1].offset;
} else {
/* do not count the elf loader, which is on one block */
@@ -353,7 +387,7 @@ init_mtd_partitions(struct mtd_info *mtd, size_t size)
/* find and size rootfs */
find_root(mtd,size,&bcm47xx_parts[2]);
- bcm47xx_parts[2].size = size - bcm47xx_parts[2].offset - bcm47xx_parts[3].size;
+ bcm47xx_parts[2].size = size - dual_image_offset - bcm47xx_parts[2].offset - bcm47xx_parts[3].size;
return bcm47xx_parts;
}