Kernel patch: Fix MTD partition detection
The bootloader is only 128KiB on this device, so find_cfe_size() and find_root() are modified to look for the TRX magic beginning at that point. Also, init_mtd_partitions() is cleaned up slightly and modified to treat 128KiB like the 256KiB case.
More importantly, the serial flash chip is unusual in that it gets erased a page at a time, which means mtd->erasesize is only 512 bytes (!). To account for this,
- find_cfe_size() and find_root() now jump by a minimum of 64KiB at a time, even if erasesize is smaller, to speed up the search.
- init_mtd_partitions() ensures that at least NVRAM_SPACE is allocated for NVRAM, just as the old Broadcom source used to do, rather than assuming one erasesize is enough.
Note that the tiny erasesize means that jffs2 is hard to use with this chip -- at the very least, mkfs.jffs2 doesn't let you create a filesystem with erasesize < 4KiB. A larger virtual erasesize, or rewriting the sflash driver to appear as NAND flash, would probably be useful. squashfs works better.
Index: linux/brcm-2.4/patches/052-init_mtd_partitions.patch
===================================================================
--- linux/brcm-2.4/patches/052-init_mtd_partitions.patch (revision 0)
+++ linux/brcm-2.4/patches/052-init_mtd_partitions.patch (revision 0)
@@ -0,0 +1,108 @@
+diff -u linux-2.4.32.orig/drivers/mtd/maps/bcm947xx-flash.c linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c
+--- linux-2.4.32.orig/drivers/mtd/maps/bcm947xx-flash.c 2006-03-22 19:31:05.000000000 -0500
++++ linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c 2006-03-22 19:46:12.000000000 -0500
+@@ -158,13 +158,15 @@
+ unsigned char buf[512];
+ int off;
+ size_t len;
+- int cfe_size_flag;
++ int blocksize;
+
+ trx = (struct trx_header *) buf;
+
+- cfe_size_flag=0;
++ blocksize = mtd->erasesize;
++ if (blocksize < 0x10000)
++ blocksize = 0x10000;
+
+- for (off = (256*1024); off < size; off += mtd->erasesize) {
++ for (off = (128*1024); off < size; off += blocksize) {
+ memset(buf, 0xe5, sizeof(buf));
+
+ /*
+@@ -178,7 +180,6 @@
+ if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
+ goto done;
+ }
+- cfe_size_flag += 1;
+ }
+
+ printk(KERN_NOTICE
+@@ -187,8 +188,8 @@
+ return -1;
+
+ done:
+- printk(KERN_NOTICE "bootloader size flag: %d\n", cfe_size_flag);
+- return cfe_size_flag;
++ printk(KERN_NOTICE "bootloader size: %d\n", off);
++ return off;
+
+ }
+
+@@ -199,10 +200,15 @@
+ unsigned char buf[512];
+ int off;
+ size_t len;
++ int blocksize;
+
+ trx = (struct trx_header *) buf;
+
+- for (off = (256*1024); off < size; off += mtd->erasesize) {
++ blocksize = mtd->erasesize;
++ if (blocksize < 0x10000)
++ blocksize = 0x10000;
++
++ for (off = (128*1024); off < size; off += blocksize) {
+ memset(buf, 0xe5, sizeof(buf));
+
+ /*
+@@ -237,32 +243,26 @@
+ struct mtd_partition * __init
+ init_mtd_partitions(struct mtd_info *mtd, size_t size)
+ {
++ int cfe_size;
+
+- int cfe_size_flag;
+-
+- /* if cfe_size_flag=0, cfe size is 256 kb, else 384 kb */
+- cfe_size_flag = find_cfe_size(mtd,size);
++ cfe_size = find_cfe_size(mtd,size);
+
+ /* boot loader */
+ bcm947xx_parts[0].offset = 0;
+- if (cfe_size_flag == 0) {
+- bcm947xx_parts[0].size = 1024*256;
+- } else {
+- /* netgear wgt634u has 384 kb bootloader */
+- bcm947xx_parts[0].size = 1024*384;
+- }
++ bcm947xx_parts[0].size = cfe_size;
+
+ /* nvram */
+- if (cfe_size_flag == 0) {
+- bcm947xx_parts[3].offset = size - mtd->erasesize;
++ if (cfe_size != 384 * 1024) {
++ bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
++ bcm947xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
+ } else {
+ /* nvram (old 128kb config partition on netgear wgt634u) */
+ bcm947xx_parts[3].offset = bcm947xx_parts[0].size;
++ bcm947xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
+ }
+- bcm947xx_parts[3].size = mtd->erasesize;
+
+ /* linux (kernel and rootfs) */
+- if (cfe_size_flag == 0) {
++ if (cfe_size != 384 * 1024) {
+ bcm947xx_parts[1].offset = bcm947xx_parts[0].size;
+ bcm947xx_parts[1].size = bcm947xx_parts[3].offset -
+ bcm947xx_parts[1].offset;
+@@ -285,7 +285,7 @@
+ } else {
+ /* legacy setup */
+ /* calculate leftover flash, and assign it to the jffs2 partition */
+- if (cfe_size_flag == 0) {
++ if (cfe_size != 384 * 1024) {
+ bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +
+ bcm947xx_parts[2].size;
+ if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
Download: svn-03-partitions.patch