November 2013 Archives
2013-11-24 11:09:47
Writing a flash chip with a programming cable
If you have a broken BIOS (BIOS update failed) or if you have "bricked" router then you need some kind of programming device to write a new firmware into the flash chip. Most of these chips are NOR flash chips which can be written by SPI.
I wanted to replace a 4 MB flash with a 8 MB chip and wanted to "burn" at least a boot loader (in this case U-Boot) to the virgin chip. I didn't want to buy a professional programmer like Batronix because I just wanted to write flash chips with SPI which is actually a most simple serial protocol. These were my specs:
- ready to use (no assembling of PCB and soldering)
- writing flash chips by SPI
- software available (also ready to use), with preference of open source software and support for some kind of unix os (Linux, BSD etc.)
- cheap
Searching the web I discovered some "open source" solutions like Openbiosprog-spi or RushSPI. Both projects are well done and even the hardware is published under a free license. Both projects don't offer software of their own but need the free software flashrom. Although the hardware is licensed under the free CC-BY-SA, is cheap and the PCB layouts are available online, they fail on one important spec: ready to use. But both projects use an FTDI chip. Searching FTDI's website I detected a very interesting cable: C232HM-DDHSL-0. Because the chip in this cable is the same chip like used in RushSPI you can also use flashrom as writing software.
I ordered the cable for ~ 20 EUR and connected the flash rom MX25L6406 via a self built adapter to the cable. This is the wiring:
C232HM-DDHSL-0 SPI-Flash SOP8 1 red ------ 8 Vcc 2 orange ------ 6 SCLK 3 yellow ------ 5 SI 4 green ------ 2 SO 5 brown ------ 1 /CS 6 grey ------ 3 /WP (with 4k7 Pullup) 7 purple ------ 7 /HOLD (with 4k7 Pullup) 10 black ------ 4 Gnd
After compiling flashrom (and libftdi) the software said that it couldn't detect a known chip. A quick search lead me to this page: ftdi-d2xx-linux-overcoming-big-problem. I just forgot my serial cable with the latest FTDI VCP serial driver! This "virtual com port" driver already knows the FT232H chip and is able to control these chips when they are connected to USB. After deactivating the support for the FT232H in the VCP driver I was able to "see", read and write my connected flash chip with flashrom and libftdi.
Here are some example commands:
# ./flashrom -p ft2232_spi:type=232H,port=A flashrom v0.9.7-r1711 on Darwin 8.11.0 (Power Macintosh) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... OK. Found Macronix flash chip "MX25L6405(D)" (8192 kB, SPI) on ft2232_spi. Found Macronix flash chip "MX25L6406E/MX25L6436E" (8192 kB, SPI) on ft2232_spi. Found Macronix flash chip "MX25L6445E" (8192 kB, SPI) on ft2232_spi. Multiple flash chip definitions match the detected chip(s): "MX25L6405(D)", "MX25L6406E/MX25L6436E", "MX25L6445E" Please specify which chip definition to use with the -c <chipname> option.
# ./flashrom -p ft2232_spi:type=232H,port=A -V -c \ MX25L6406E/MX25L6436E flashrom v0.9.7-r1711 on Darwin 8.11.0 (Power Macintosh) flashrom is free software, get the source code at http://www.flashrom.org flashrom was built with GCC 4.0.1 (Apple Computer, Inc. build 5370), big endian Command line (5 args): ./flashrom -p ft2232_spi:type=232H, port=A -V -c MX25L6406E/MX25L6436E Calibrating delay loop... OS timer resolution is 1 usecs, 571M loops per second, 10 myus = 9 us, 100 myus = 92 us, 1000 myus = 923 us, 10000 myus = 9307 us, 4 myus = 4 us, OK. Initializing ft2232_spi programmer Using device type FTDI FT232H channel A. Disable divide-by-5 front stage Set clock divisor MPSSE clock: 60.000000 MHz, divisor: 2, SPI clock: 30.000000 MHz No loopback of TDI/DO TDO/DI Set data bits The following protocols are supported: SPI. Probing for Macronix MX25L6406E/MX25L6436E, 8192 kB: probe_spi_rdid_generic: id1 0xc2, id2 0x2017 Found Macronix flash chip "MX25L6406E/MX25L6436E" (8192 kB, SPI) on ft2232_spi. Chip status register is 0x00. Chip status register: Status Register Write Disable (SRWD, SRP, ...) is not set Chip status register: Bit 6 is not set Chip status register: Block Protect 3 (BP3) is not set Chip status register: Block Protect 2 (BP2) is not set Chip status register: Block Protect 1 (BP1) is not set Chip status register: Block Protect 0 (BP0) is not set Chip status register: Write Enable Latch (WEL) is not set Chip status register: Write In Progress (WIP/BUSY) is not set This chip may contain one-time programmable memory. flashrom cannot read and may never be able to write it, hence it may not be able to completely clone the contents of this chip (see man page for details). No operations were specified.
# time ./flashrom -p ft2232_spi:type=232H -c MX25L6406E/ \ X25L6436E -r dump.rom flashrom v0.9.7-r1711 on Darwin 8.11.0 (Power Macintosh) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... OK. Found Macronix flash chip "MX25L6406E/MX25L6436E" (8192 kB, SPI) on ft2232_spi. Reading flash... done. real 2m34.750s user 0m4.224s sys 0m8.098s(To use flashrom on MacOS PPC as shown above you must modify flashrom because it officially supports only Intel/PCI-Macs.)
2013-11-17 21:32:01
Compiling flashrom on MacOS PPC
flashrom is a tool for reading and writing flash chips. It can be used to debrick systems from small routers up to desktop PCs (BIOS) and more.
Unfortunately it does not compile on MacOS PPC although it works on many different OS like Linux, *BSD, MacOS Intel and even Windows. Nevertheless it makes sense to use it on this old architecture in example if you have a FTDI cable or programmer with an FTDI chip connected to your old Mac to write a new image to a flash chip.
All you need is an additional Makefile which does a basic setup by including the "main" Makefile and then compiles flashrom:
# additional Makefile.darwinppc for building flashrom # on Darwin/PPC # lib deps must be installed by i.e. mac ports CFLAGS = -O2 -Wall -Wshadow WARNERROR = no CONFIG_INTERNAL = no CONFIG_SERPROG = no CONFIG_RAYER_SPI = no CONFIG_PONY_SPI = no CONFIG_NIC3COM = no CONFIG_GFXNVIDIA = no CONFIG_SATASII = no CONFIG_ATAHPT = no CONFIG_FT2232_SPI = yes CONFIG_USBBLASTER_SPI = no CONFIG_DRKAISER = no CONFIG_NICREALTEK = no CONFIG_NICNATSEMI = no CONFIG_NICINTEL = no CONFIG_NICINTEL_SPI = no CONFIG_OGP_SPI = no CONFIG_BUSPIRATE_SPI = no CONFIG_DEDIPROG = no CONFIG_SATAMV = no CONFIG_LINUX_SPI = no CONFIG_PRINT_WIKI = no %.o: %.c $(CC) -MMD $(CFLAGS) $(CPPFLAGS) \ $(FLASHROM_CFLAGS) $(FEATURE_CFLAGS) \ $(SVNDEF) -o $@ -c $< ALL: darwinppc include Makefile config: @echo 'FEATURES := yes' >.features @echo 'FTDISUPPORT := yes' >>.features @echo 'FT232H := yes' >>.features @echo 'UTSNAME := yes' >>.features darwinppc: config $(PROGRAM)$(EXEC_SUFFIX) @echo @echo Trying to execute flashrom... @echo ./flashrom -p ft2232_spi:type=232H,divisor=32
Install libusb and libftdi, put this makefile in the flashrom directory and type
make -f Makefile.darwinppc
After it was compiled you can write a flash chip with i.e. the FTDI cable C232HM-DDHSL-0 by a command like this:
# time ./flashrom -p ft2232_spi:type=232H,divisor=32 \ -c MX25L6406E/MX25L6436E -w dump.rom flashrom v0.9.7-r1711 on Darwin 8.11.0 (Power Macintosh) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... OK. Found Macronix flash chip "MX25L6406E/MX25L6436E" (8192 kB, SPI) on ft2232_spi. Reading old flash chip contents... done. Erasing and writing flash chip... Erase/write done. Verifying flash... VERIFIED. real 7m1.731s user 0m12.288s sys 0m22.984s
Here's an example of writing a 128MBit chip:
# ./flashrom -p ft2232_spi:type=232H,divisor=4 -w flash.raw flashrom v0.9.7-r1764 on Darwin 8.11.0 (Power Macintosh) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... OK. Found Winbond flash chip "W25Q128.V" (16384 kB, SPI) on ft2232_spi. Reading old flash chip contents... done. Erasing and writing flash chip... Warning: Chip content is identical to the requested image. Erase/write done.
Warning: If you have installed an FTDI VCP driver (virtual com port) then this driver will take control over a FT232H chip. In this case you must disable the FT232H chip (product ID 0x6014/24596dez) in the VCP driver. This is the patch:
--- tmp/FTDIUSBSerialDriver.kext/Contents/Info.plist \ 2012-08-08 14:01:40.000000000 +0200 +++ /System/Library/Extensions/FTDIUSBSerialDriver.kext/\ Contents/Info.plist 2013-11-17 10:48:54.000000000 +0100 @@ -2014,25 +2014,6 @@ <key>idVendor</key> <integer>1027</integer> </dict> - <key>FT232H</key> - <dict> - <key>CFBundleIdentifier</key> - <string>com.FTDI.driver.FTDIUSBSer.. - <key>IOClass</key> - <string>FTDIUSBSerialDriver</string> - <key>IOProviderClass</key> - <string>IOUSBInterface</string> - <key>bConfigurationValue</key> - <integer>1</integer> - <key>bInterfaceNumber</key> - <integer>0</integer> - <key>bcdDevice</key> - <integer>2304</integer> - <key>idProduct</key> - <integer>24596</integer> - <key>idVendor</key> - <integer>1027</integer> - </dict> <key>FT4232H_A</key> <dict> <key>CFBundleIdentifier</key>
(Update 2014-01-14: Makefile fix and Winbond example.)