OpenWrt Forum Archive

Topic: Belkin F5D7230-4 v2000

The content of this topic has been archived between 20 Apr 2018 and 28 Apr 2018. Unfortunately there are posts – most likely complete pages – missing.

Not sure, I think that should be all you need to do.  Did you do this with a clean build?  Once it creates the patched
kernel tree, it won't recreate it when the patches change.  You could try starting fresh, or maybe just apply the patch to build_mipsel/linux manually.

Yes I downloaded everything fresh from SVN then copied the patch. However, I already applied it manually, and indeed it seems to be much more stable. But there was another problem, with the current kamikaze build there was some strange behaviour, especially if i used an ImageBuilder image. If it worked at all, the configuration of the bridge was all screwed up. I finally took the new compiled kernel and it's modules and inserted them into the ImageBuilder version I used before.

Have to test it for a few days to see if it's completely stable. Thank you VERY much for sharing your knowledge.

@fruitloaf: will send you an updated version of the image builder when I find the time.

Fantastic, don't worry about speed though I'm swamped with exams at the moment so I've not been able to do more than follow this thread at the moment.

It looks good at the moment though, between OpenWRT and DDmicro there could be a useful firmware for the Belkin yet.

I just wired up the USB port for my v2000. I'm planning to connect an old 2.5" HDD in an enclosure to it. How do I extract the OpenWRT image to copy to the ext3 partition on the USB HDD? And how do I make a "bootloader" image to boot from USB?

jimparis wrote:

Kernel patch: Add driver for serial flash

The F5D7230-4 v2000 router has a serial flash chip rather than the much more common parallel flash.  The "sflash" MTD driver included in the original Broadcom and Belkin source releases is missing from OpenWRT.  This patch re-adds that driver.

Index: trunk/openwrt/target/linux/brcm-2.4/config
===================================================================
--- trunk/openwrt/target/linux/brcm-2.4/config  (revision 3440)
+++ trunk/openwrt/target/linux/brcm-2.4/config  (working copy)
@@ -246,6 +246,7 @@
 #
 # Self-contained MTD device drivers
 #
+CONFIG_MTD_SFLASH=y
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_MTDRAM is not set
Index: trunk/openwrt/target/linux/brcm-2.4/patches/051-sflash.patch
===================================================================
--- trunk/openwrt/target/linux/brcm-2.4/patches/051-sflash.patch        (revision 0)
+++ trunk/openwrt/target/linux/brcm-2.4/patches/051-sflash.patch        (revision 0)
@@ -0,0 +1,333 @@
+diff -urN linux-2.4.32.orig/drivers/mtd/devices/Config.in linux-2.4.32/drivers/mtd/devices/Config.in
+--- linux-2.4.32.orig/drivers/mtd/devices/Config.in    2006-03-22 18:16:57.000000000 -0500
++++ linux-2.4.32/drivers/mtd/devices/Config.in 2006-03-22 18:06:49.000000000 -0500
+@@ -5,6 +5,7 @@
+ mainmenu_option next_comment
+ 
+ comment 'Self-contained MTD device drivers'
++bool '  Broadcom Chipcommon Serial Flash support' CONFIG_MTD_SFLASH
+ dep_tristate '  Ramix PMC551 PCI Mezzanine RAM card support' CONFIG_MTD_PMC551 $CONFIG_MTD $CONFIG_PCI
+ if [ "$CONFIG_MTD_PMC551" = "y" -o  "$CONFIG_MTD_PMC551" = "m" ]; then
+    bool '    PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
+diff -urN linux-2.4.32.orig/drivers/mtd/devices/Makefile linux-2.4.32/drivers/mtd/devices/Makefile
+--- linux-2.4.32.orig/drivers/mtd/devices/Makefile     2006-03-22 18:16:57.000000000 -0500
++++ linux-2.4.32/drivers/mtd/devices/Makefile  2006-03-22 18:06:49.000000000 -0500
+@@ -3,6 +3,8 @@
+ #
+ # $Id: Makefile,v 1.4 2001/06/26 21:10:05 spse Exp $
+ 
++EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include
++
+ O_TARGET      := devlink.o
+ 
+ #                       *** BIG UGLY NOTE ***
+@@ -12,6 +14,7 @@
+ # here where previously there was none.  We now have to ensure that
+ # doc200[01].o are linked before docprobe.o
+ 
++obj-$(CONFIG_MTD_SFLASH)      += sflash.o
+ obj-$(CONFIG_MTD_DOC1000)     += doc1000.o
+ obj-$(CONFIG_MTD_DOC2000)     += doc2000.o
+ obj-$(CONFIG_MTD_DOC2001)     += doc2001.o
+diff -urN linux-2.4.32.orig/drivers/mtd/devices/sflash.c linux-2.4.32/drivers/mtd/devices/sflash.c
+--- linux-2.4.32.orig/drivers/mtd/devices/sflash.c     1969-12-31 19:00:00.000000000 -0500
++++ linux-2.4.32/drivers/mtd/devices/sflash.c  2006-03-22 18:17:12.000000000 -0500
+@@ -0,0 +1,298 @@
++/*
++ * Broadcom SiliconBackplane chipcommon serial flash interface
++ *
++ * Copyright 2001-2003, Broadcom Corporation   
++ * All Rights Reserved.   
++ *    
++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY   
++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM   
++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS   
++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.   
++ *
++ * $Id: sflash.c,v 1.1.1.3 2003/11/10 17:43:38 hyin Exp $
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/mtd/compatmac.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/errno.h>
++#include <linux/pci.h>
++#include <linux/delay.h>
++#include <asm/io.h>
++
++#ifdef CONFIG_MTD_PARTITIONS
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/minix_fs.h>
++#include <linux/ext2_fs.h>
++#include <linux/romfs_fs.h>
++#include <linux/cramfs_fs.h>
++#include <linux/jffs2.h>
++#endif
++
++#include <typedefs.h>
++#include <bcmdevs.h>
++#include <bcmutils.h>
++#include <osl.h>
++#include <bcmutils.h>
++#include <bcmnvram.h>
++#include <sbconfig.h>
++#include <sbchipc.h>
++#include <sflash.h>
++#include <trxhdr.h>
++
++#ifdef CONFIG_MTD_PARTITIONS
++extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size);
++#endif
++
++struct sflash_mtd {
++      chipcregs_t *cc;
++      struct semaphore lock;
++      struct mtd_info mtd;
++      struct mtd_erase_region_info regions[1];
++};
++
++/* Private global state */
++static struct sflash_mtd sflash;
++
++static int
++sflash_mtd_poll(struct sflash_mtd *sflash, unsigned int offset, int timeout)
++{
++      int now = jiffies;
++      int ret = 0;
++
++      for (;;) {
++              if (!sflash_poll(sflash->cc, offset)) {
++                      ret = 0;
++                      break;
++              }
++              if (time_after(jiffies, now + timeout)) {
++                      printk(KERN_ERR "sflash: timeout\n");
++                      ret = -ETIMEDOUT;
++                      break;
++              }
++              if (current->need_resched) {
++                      set_current_state(TASK_UNINTERRUPTIBLE);
++                      schedule_timeout(timeout / 10);
++              } else
++                      udelay(1);
++      }
++
++      return ret;
++}
++
++static int
++sflash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
++{
++      struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
++      int bytes, ret = 0;
++
++      /* Check address range */
++      if (!len)
++              return 0;
++      if ((from + len) > mtd->size)
++              return -EINVAL;
++
++      down(&sflash->lock);
++
++      *retlen = 0;
++      while (len) {
++              if ((bytes = sflash_read(sflash->cc, (uint) from, len, buf)) < 0) {
++                      ret = bytes;
++                      break;
++              }
++              from += (loff_t) bytes;
++              len -= bytes;
++              buf += bytes;
++              *retlen += bytes;
++      }
++
++      up(&sflash->lock);
++
++      return ret;
++}
++
++static int
++sflash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
++{
++      struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
++      int bytes, ret = 0;
++
++      /* Check address range */
++      if (!len)
++              return 0;
++      if ((to + len) > mtd->size)
++              return -EINVAL;
++
++      down(&sflash->lock);
++
++      *retlen = 0;
++      while (len) {
++              if ((bytes = sflash_write(sflash->cc, (uint) to, len, buf)) < 0) {
++                      ret = bytes;
++                      break;
++              }
++              if ((ret = sflash_mtd_poll(sflash, (unsigned int) to, HZ / 10)))
++                      break;
++              to += (loff_t) bytes;
++              len -= bytes;
++              buf += bytes;
++              *retlen += bytes;
++      }
++
++      up(&sflash->lock);
++
++      return ret;
++}
++
++static int
++sflash_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
++{
++      struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
++      int i, j, ret = 0;
++      unsigned int addr, len;
++
++      /* Check address range */
++      if (!erase->len)
++              return 0;
++      if ((erase->addr + erase->len) > mtd->size)
++              return -EINVAL;
++
++      addr = erase->addr;
++      len = erase->len;
++
++      down(&sflash->lock);
++
++      /* Ensure that requested region is aligned */
++      for (i = 0; i < mtd->numeraseregions; i++) {
++              for (j = 0; j < mtd->eraseregions[i].numblocks; j++) {
++                      if (addr == mtd->eraseregions[i].offset + mtd->eraseregions[i].erasesize * j &&
++                          len >= mtd->eraseregions[i].erasesize) {
++                              if ((ret = sflash_erase(sflash->cc, addr)) < 0)
++                                      break;
++                              if ((ret = sflash_mtd_poll(sflash, addr, 10 * HZ)))
++                                      break;
++                              addr += mtd->eraseregions[i].erasesize;
++                              len -= mtd->eraseregions[i].erasesize;
++                      }
++              }
++              if (ret)
++                      break;
++      }
++
++      up(&sflash->lock);
++
++      /* Set erase status */
++      if (ret)
++              erase->state = MTD_ERASE_FAILED;
++      else 
++              erase->state = MTD_ERASE_DONE;
++
++      /* Call erase callback */
++      if (erase->callback)
++              erase->callback(erase);
++
++      return ret;
++}
++
++#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
++#define sflash_mtd_init init_module
++#define sflash_mtd_exit cleanup_module
++#endif
++
++mod_init_t
++sflash_mtd_init(void)
++{
++      struct pci_dev *pdev;
++      int ret = 0;
++      struct sflash *info;
++      uint bank, i;
++#ifdef CONFIG_MTD_PARTITIONS
++      struct mtd_partition *parts;
++#endif
++
++      if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_CC, NULL))) {
++              printk(KERN_ERR "sflash: chipcommon not found\n");
++              return -ENODEV;
++      }
++
++      memset(&sflash, 0, sizeof(struct sflash_mtd));
++      init_MUTEX(&sflash.lock);
++
++      /* Map registers and flash base */
++      if (!(sflash.cc = ioremap_nocache(pci_resource_start(pdev, 0),
++                                        pci_resource_len(pdev, 0)))) {
++              printk(KERN_ERR "sflash: error mapping registers\n");
++              ret = -EIO;
++              goto fail;
++      }
++
++      /* Initialize serial flash access */
++      info = sflash_init(sflash.cc);
++
++      if (!info) {
++              printk(KERN_ERR "sflash: found no supported devices\n");
++              ret = -ENODEV;
++              goto fail;
++      }
++
++      /* Setup banks */
++      sflash.regions[0].offset = 0;
++      sflash.regions[0].erasesize = info->blocksize;
++      sflash.regions[0].numblocks = info->numblocks;
++      if (sflash.regions[0].erasesize > sflash.mtd.erasesize)
++              sflash.mtd.erasesize = sflash.regions[0].erasesize;
++      if (sflash.regions[0].erasesize * sflash.regions[0].numblocks) {
++              sflash.mtd.size += sflash.regions[0].erasesize * sflash.regions[0].numblocks;
++      }
++      sflash.mtd.numeraseregions = 1;
++      ASSERT(sflash.mtd.size == info->size);
++
++      /* Register with MTD */
++      sflash.mtd.name = "sflash";
++      sflash.mtd.type = MTD_NORFLASH;
++      sflash.mtd.flags = MTD_CAP_NORFLASH;
++      sflash.mtd.eraseregions = sflash.regions;
++      sflash.mtd.module = THIS_MODULE;
++      sflash.mtd.erase = sflash_mtd_erase;
++      sflash.mtd.read = sflash_mtd_read;
++      sflash.mtd.write = sflash_mtd_write;
++      sflash.mtd.priv = &sflash;
++
++#ifdef CONFIG_MTD_PARTITIONS
++      parts = init_mtd_partitions(&sflash.mtd, sflash.mtd.size);
++      for (i = 0; parts[i].name; i++);
++      ret = add_mtd_partitions(&sflash.mtd, parts, i);
++#else
++      ret = add_mtd_device(&sflash.mtd);
++#endif
++      if (ret) {
++              printk(KERN_ERR "sflash: add_mtd failed\n");
++              goto fail;
++      }
++
++      return 0;
++
++ fail:
++      if (sflash.cc)
++              iounmap((void *) sflash.cc);
++      return ret;
++}
++
++mod_exit_t
++sflash_mtd_exit(void)
++{
++#ifdef CONFIG_MTD_PARTITIONS
++      del_mtd_partitions(&sflash.mtd);
++#else
++      del_mtd_device(&sflash.mtd);
++#endif
++      iounmap((void *) sflash.cc);
++}
++
++module_init(sflash_mtd_init);
++module_exit(sflash_mtd_exit);

Download: svn-02-sflash.patch

How am I supposed to use the patch? It doesn't appear to work.

dd-wrt now supports the f5d7230-4 v1444 and other belkin.

Please check: http://www.dd-wrt.com/

i hope openwrt will do the same soon!

Sorry .. but it did brick my V2000 , or it off in some odd IP address that i havent found yet ...

Any progress on this unit?
I got one (for free) and would like to use it with OpenWrt

The kernel sflash driver is not working on current kamikaze ... It's in the wrong directory, should be in /arch/mips/bcm947xx..
The actual kernel module is not included and what Jimparis made doesn't work anymore .. as do the other versions of /drivers/mtd/devices/sflash.c floating around the net..

It should be fixed now.

This v2000 router doesn't have a parallel flash chip -----If i change the flash to 32mb and ram to 64mb it can work with openwrt? ..but i don not konw any code about linux or the other if i supply the flash and ram version any one can make me a fireware-_- I can replace the flash and ram by my self!! anyone can help me ?

(Last edited by soilfish on 16 Jan 2011, 08:00)

The discussion might have continued from here.