NSLU2-Linux
view · edit · print · history

I managed to corrupt the FLASH memory of my unit while playing with the APEX bootloader. (It's my finger's fault not APEX ;)

This was due to replacing the bootloader inside the NSLU2. This does not occur during normal firmware upgrades and therefore this is guide is only relevant if you have modified the bootloader.

These are the steps that I took to reprogram the flash via JTAG. These steps are specific to the type of adapter used (Macraigor Wiggler clone) and therefore need to be modified slightly for another adapter.

--- kinsa

Most of the steps detailed in kinsa's guide is credited to Stewart Heitmann of the openwince-list.

*WARNING: Messing with JTAG could potentially damage your hardware beyond repair. Use with caution.*

*WARNING: This WILL DEFINITELY void your NSLU2's warranty!*

Preparation

You will need a JTAG adapter of some kind. The JTAG port has been tested and found to be working with:

 * Altera ByteBlaster MV cable,
 * Digilent Xilinx III clone cable (JTAG3)
 * Macraigor Wiggler clone cable
 * BDI2000 JTAG interface (requires license for Xscale IXP42x)

The JTAG interface was connected directly to the pads on the NSLU2. No pull-up resistors were needed. TDI has 6.8k and TCK has 10k pullup, respectively.

!!NOTE 1!! This uses different printer port pins than those used by HairyDairyMaid's WRT54G unbuffered programmer.

If you do not have a suitable cable and wish to build one yourself then follow the steps outlined here. However, it has been reported that you don't need all the control signals (i.e., TRSTn?) and the schematic below should suffice.


Modified JTAG interface circuit.

 25wayD Male                                                      NSLU2 board

 17-25 <-----------+----------------------------+--+-----------<  (-) pin of C21
                   |                            |  |              
                   |       AC244          200nF =  = 4.7uF
                   |    +------------+  Vcc     |  |                         
      TDI       0v +----| 1       20 |-+--------+--+-----------<  (+) pin of C21
  5  >------------------| 2 -->   19 |-+
      TMS          |    | 3    `- 18 |-----XXXX---------------->  to R133   
  3  >------------------| 4 -->   17 |     51R
      TCLK         |    | 5    `- 16 |-----XXXX---------------->  to R132
  4  >------------------| 6 -->   15 |     51R
                   |    | 7    `- 14 |-----XXXX---------------->  to R134
             +----------| 8 -->   13 |     51R
             |     |    | 9    `- 12 |-----XXXX---+
             |  0v +----| 10      11 |     51R    |
             |          +------------+            |
             |                                    |
             +-------------------------------------------------<  to R137
      TDO                                         |
 11 <---------------------------------------------+

Either solder this circuit temporarily to the board or attach a 6 pin header as shown on this photo. Note that the rightmost pin is not connected to anything. I had mine connected to the (+) side of capacitor C21.


I performed the operation with a VERY simple cable:

 GND  17-25 <----------------------------------------------------<  GND pin of C21

 TDI     5  >---------------XXXX--------------------------------->  => R133

 TMS     3  >---------------XXXX--------------------------------->  => R132

 TCLK    4  >---------------XXXX--------------------------------->  => R134

 TDO     11 <---------------XXXX--------------------------------->  => R137

       25 pins male         4 resistors 51 ohms or 75 ohms          NSLU2

This is the most simple cable you can imagine!

JJ

This cable don't work in urjtag, don't waste your time and immediately make Wiggler cable


New Section regarding UrJTAG

  • Download UrJTAG sources. Assume saved to /tmp directory.
  • Confirm software supports your JTAG programmer. Specifically, the Macraigor (uses parallel-port). I assume you'll use the same hardware as above.
  • Confirm JTAG-aware parts: Intel IXP425 and Intel 28F128J3A (128Mbit NOR flash) or Intel 28F064J3A (64Mbit NOR flash). This says it does.
  • Cygwin is supported but this suggests it's necessary to run the command ioperm -i to install the IOPERM.SYS driver in the system.
  • Follow 2.4.3 of UrJTAG book.

It seems that there is also a version of the slug which hasn't one of the two steppings so i edited the STEPPINGS file in urjtag-0.8\data\intel\ixp425 and changed the "0001" in the B0 row to "0010" and built the programm again. I don't now if there is another way to solve this but for me it worked and i was able to go on flashing the memory.


$ cd /tmp
$ tar xjvf urjtag-0.8.tar.bz2
$ cd urjtag-0.8
$ ./configure --with-includes
$ make; make install
  • Now connect the power supply to the NSLU2, and JTAG programmer to parallel port (or applicable programmer). Press the power button on the NSLU2. Then go back to the console.
$ jtag

jtag> cable WIGGLER parallel 0x378
Initializing parallel port at 0x378
jtag> detect
IR length: 7
Chain length: 1
Device Id: 00011001001001110111000000010011 (0x0000000019277013)
  Manufacturer: Intel
  Part(0):         IXP425-266MHz
  Stepping:     B0
  Filename:     /usr/local/share/urjtag/intel/ixp425/ixp425
Please use the 'include' command instead of 'script'
-E- Error: Illegal character # (/043) at line 1:
jtag> print chain
 No. Manufacturer       Part            Stepping  Instruction  Register
-------------------------------------------------------------------------
  0  Intel              IXP425-266MHz   B0        BYPASS       BR
  • Note the error message above. I was originally worried about it, but it doesn't seem to cause any harm.
jtag> detectflash 0
Query identification string:
        Primary Algorithm Command Set and Control Interface ID Code: 0x0001 (Intel/Sharp Extended Command Set)
        Alternate Algorithm Command Set and Control Interface ID Code: 0x0000 (null)
Query system interface information:
        Vcc Logic Supply Minimum Write/Erase or Write voltage: 2700 mV
        Vcc Logic Supply Maximum Write/Erase or Write voltage: 3600 mV
        Vpp [Programming] Supply Minimum Write/Erase voltage: 0 mV
        Vpp [Programming] Supply Maximum Write/Erase voltage: 0 mV
        Typical timeout per single byte/word program: 64 us
        Typical timeout for maximum-size multi-byte program: 128 us
        Typical timeout per individual block erase: 1024 ms
        Typical timeout for full chip erase: 0 ms
        Maximum timeout for byte/word program: 256 us
        Maximum timeout for multi-byte program: 1024 us
        Maximum timeout per individual block erase: 4096 ms
        Maximum timeout for chip erase: 0 ms
Device geometry definition:
        Device Size: 16777216 B (16384 KiB, 16 MiB)
        Flash Device Interface Code description: 0x0002 (x8/x16)
        Maximum number of bytes in multi-byte program: 32
        Number of Erase Block Regions within device: 1
        Erase Block Region Information:
                Region 0:
                        Erase Block Size: 131072 B (128 KiB)
                        Number of Erase Blocks: 128
  • Note that my detected flash is 16MiB, whereas NSLU2 stock flash should be 8MiB.
  • Next, you'll need to erase the flash RedBoot area, so you can re-program it. This is found between 0x50000000-0x5003FFFF. This constitutes 4 blocks (I think?). More information can be found here
  • Now, in another window, prepare the old image, including Redboot. You can get RedBoot from the Firmware Download page. You'll also need slugimage. I renamed it to slugimage.pl and performed chmod 755 slugimage.pl on it. The file wholeflash-8MB.img is whatever firmware you downloaded. Note that if you have your old RedBoot, that is clearly preferred.
  • If necessary (i.e., you had no flash image backup), reference the use of slugimage to modify the downloaded image with your MAC address. You'll need your MAC address as the binary images above won't have your unique device's MAC address. This page may help but newer devices may have newer MAC address prefixes. Specifically, if your MAC address has all zeros, it is known that this is not a valid MAC address and you won't be able to get network access to your NSLU2. Similarly with all FF's for a MAC address - that's a broadcast address!
$ mkdir oldflash
$ cd oldflash/
$ ../slugimage.pl -u -i ../wholeflash-8MB.img
Read 2 blocks into <RedBoot>
Read 0x00006 bytes into <EthAddr>
Read 1 blocks into <SysConf>
Read 0x0B26C bytes into <Loader>
Read 10 blocks into <Kernel>
Read 24 blocks into <Ramdisk>
Read 1 blocks into <FIS directory>
Read 0x00010 bytes into <Trailer>
Wrote 0x00040000 bytes from <RedBoot> into "RedBoot"
Wrote 0x00020000 bytes from <SysConf> into "SysConf"
Wrote 0x0000B26C bytes from <Loader> into "apex.bin"
Wrote 0x001219F4 bytes from <Kernel> into "vmlinuz"
Wrote 0x002F766A bytes from <Ramdisk> into "ramdisk.gz"
Wrote 0x00000010 bytes from <Trailer> into "Trailer"

$ ls
RedBoot  SysConf  Trailer  apex.bin  ramdisk.gz  vmlinuz

jtag> eraseflash 0x50000000 4
Manufacturer: Intel
Chip: 28F128J3A
  • note: my flash is 128Mib but yours is probably 64Mib. That would have a part number of 28F064J3A.
Erasing 4 Flash blocks from address 0x50000000
(100% Completed) FLASH Block 10245 : Unlocking ... Erasing ... Ok.

Erasing Completed.
jtag> endian
Endianess for external files: little
jtag> endian big
jtag> endian
Endianess for external files: big
  • note: change to Big Endian as RedBoot is Big Endian format.
jtag> flashmem 0x50000000 RedBoot
Manufacturer: Intel
Chip: 28F128J3A
program:
addr: 0x5003FF00
verify:

Done.
  • Now, remove power from the NSLU2, remove the JTAG programmer, and power on the NSLU2. Connect a serial console (if available), or use the standard Telnet into RedBoot technique. Reference the AddASerialPort page if necessary.
+Ethernet eth0: MAC address 00:0f:66:xx:yy:zz
IP: 192.168.0.1/255.255.255.0, Gateway: 192.168.0.1
Default server: 0.0.0.0, DNS server IP: 0.0.0.0

RedBoot(tm) bootstrap and debug environment [ROMRAM]
Red Hat certified release, version 1.92 - built 15:16:07, Feb  3 2004

Platform: IXDP425 Development Platform (XScale)
Copyright (C) 2000, 2001, 2002, Red Hat, Inc.

RAM: 0x00000000-0x02000000, 0x000723a0-0x01ff3000 available
FLASH: 0x50000000 - 0x51000000, 128 blocks of 0x00020000 bytes each.
== Executing boot script in 2.000 seconds - enter ^C to abort
^C
RedBoot> ^C

  • Now, continue with the normal processes of FLASH programming per the UpSlug2 wiki or equivalent.

End of New Section regarding UrJTAG

OLD instructions left below for legacy reasons.

Next, download and compile INCLUDE-0.3.2 (use exactly this version; other versions, even if more recent, will not work!!) and JTAG-0.5.1 from the OpenWinCE project. This will work with Cygwin as well. Do this as follows:

cd include-0.3.2
./configure --with-include
make install
(note: "make" says 'nothing to do')

Before compiling JTAG-0.5.1, apply this patch first. (Note that IE7 doesn't seem to like the link, use Firefox(approve sites) or SeaMonkey(approve sites)). This is done via:

cd jtag-0.5.1
patch -p0 <../ixp425.patch
./configure --with-include
make
make install

This is assuming patch is one level above the jtag-0.5.1 directory.

Note: the newer, actively developed UrJTAG is based on JTAG-0.5.1 with the IXP425 support integrated, but hasn't been tested with the NSLU2 yet.

Testing

Connect the JTAG interface to your parallel port. Make sure your parallel port is not set to ECP in the BIOS. Take note of the port address (default is 0x378).

Connect the other end of the interface to your NSLU2. Turn the unit on.

If you are running from Cygwin:

  • You need to use an account with administrative privileges.
  • You need to install the parallel port driver shim, or the cable command below will fail. Install the shim via:
ioperm -iv

Run JTAG. You must be root to successfully run this program.

jtag

Issue the following command:

jtag> cable parallel 0x378 WIGGLER

or

jtag> cable parallel 0x378 ByteBlaster (if you have an Altera Cable)

where 0x378 is the address of the parallel port.

The following command will detect your slug. If there is no output, double check your interface and make sure that your printer port is not in ECP mode.

     jtag> detect
     IR length: 7
     Chain length: 1
     Device Id: 00011001001001110111000000010011
       Manufacturer: Intel
       Part:         IXP425-266MHz
       Stepping:     B0
       Filename:     /usr/share/jtag/intel/ixp425/ixp425

If everything is fine, issue the following command to see if it detects your flash memory.

     jtag> detectflash 0
     Query identification string:
            Primary Algorithm Command Set and Control Interface ID Code:
 0x0001 (Intel/Sharp Extended Command Set)
            Alternate Algorithm Command Set and Control Interface ID Code: 0x0000 (null)
     Query system interface information:
            Vcc Logic Supply Minimum Write/Erase or Write voltage: 2700 mV
            Vcc Logic Supply Maximum Write/Erase or Write voltage: 3600 mV
            Vpp [Programming] Supply Minimum Write/Erase voltage: 0 mV
            Vpp [Programming] Supply Maximum Write/Erase voltage: 0 mV
            Typical timeout per single byte/word program: 256 us
            Typical timeout for maximum-size multi-byte program: 256 us
            Typical timeout per individual block erase: 2048 ms
            Typical timeout for full chip erase: 0 ms
            Maximum timeout for byte/word program: 1024 us
            Maximum timeout for multi-byte program: 1024 us
            Maximum timeout per individual block erase: 16384 ms
            Maximum timeout for chip erase: 0 ms
     Device geometry definition:
            Device Size: 8388608 B (8192 [KiB], 8 [MiB])
            Flash Device Interface Code description: 0x0002 (x8/x16)
            Maximum number of bytes in multi-byte program: 32
            Number of Erase Block Regions within device: 1
            Erase Block Region Information:
                    Region 0:
                            Erase Block Size: 131072 B (128 [KiB])
                            Number of Erase Blocks: 64

NOTE 3: The commands "cable" and "detect" are issued every time you start jtag.

To exit jtag, use the command "quit".

Restoring the flash

Before writing any firmware to the flash memory, it needs to be byte-swapped first. This is because RedBoot is running in Big Endian mode, most images are uploaded using RedBoot, and the images are Little Endian.

The following command extracts RedBoot from any NSLU2 firmware and then performs byte-swapping (SEE NOTE 4 - below is not necessary):

$ dd if=images/Unslung-5.5-beta.bin of=redboot.bin ibs=1 count=262144 conv=swab

The following jtag commands performs the actual re-flashing. It takes around 45 minutes to complete the flashing. See NOTE 5 below (removed because it added confusion).

$ jtag
jtag> cable parallel 0x378 WIGGLER
jtag> detect
jtag> detectflash 0
jtag> eraseflash 0x50000000 4
jtag> flashmem 0x50000000 redboot.bin
jtag> quit

Power cycle your board (reset and the power button doesn't work yet) and then perform the steps outlined in RecoverFromABadFlash.

Good luck!

NOTE 4: The byte swapping may not be needed. The wince JTAG tool supports endianness. If you type "endian" it will tell you whether it is currently in Little Endian (the default) or Big Endian mode. Typing "endian big" will set the JTAG tool into big endian mode. Typing "endian" again will show it is now in big endian mode. Take note that RedBoot is run in Big Endian mode, whereas the JTAG tool default is Little Endian mode. Also, the Unslung image is compiled in LE mode.

NOTE 5: (this should be 0x00000000 because 0x50000000 is out of flash adress space - 0x0 worked for me - same below). This has not been verified, and doesn't make sense as flash should be 0x50000000->0x57FFFFFF

Setting the MAC Address

After writing RedBoot to my NSLU2 I got the yellow LED flashing and no access even after the steps in RecoverFromABadFlash. The flashing means that RedBoot is looking for a MAC address.

The following steps use slugimage to write a correct MAC address into the RedBoot image:

Unpack the firmware image

$ slugimage -i NSLU2_V23RA5.bin -u

Build a new image with the right MAC address

$ slugimage -o temp.bin -p -e 00:0F:66:XX:XX:XX

Where XX:XX:XX is the last part of the MAC address that is printed on the label of your NSLU2 (in the format: LKGXXXXXX)

Unpack the Firmware image again and generate a RedBoot image

$ slugimage -i temp.bin -u -b redboot_mac.bin

Do the byte swapping

$ dd if=./redboot_mac.bin of=redboot_mac_swap.bin ibs=1 count=262144 conv=swab

Now you can JTAG the RedBoot image into the NSLU2 as described above.

Changing the line:

jtag> eraseflash 0x50000000 4

to:

jtag> eraseflash 0x50000000 2

causes just the deletion of Redboot and does not overwrite the firmware if you have loaded it previously.

I'm sure there are easier ways to do this but it worked for me.

Backup Entire Flash via JTAG

Let's say you want to make a SLUG with 16MB flash instead of 8MB. Or, your flash is corrupt and you have to replace it (assuming you have an extra flash and the SMT tools required, and definitely a microscope!). You could probably back up the flash using other techniques (from inside the OS), and then if you have a flash programmer and TSOP socket module (i.e., BPMicro or DataIO UniSITE) you could program the flash off the board. Surely, there are easier ways to do this.

If you're using one of the NSLU2 distributions that install packages to flash, you may want to be able to re-use those packages. Maybe you forgot what you installed, or maybe it is working for you right now and you want it to work when you replace the flash w/o having to re-trace your steps. Or maybe you have some extra stuff in the flash that you can't easily reproduce w/o reinstall. Everyone should agree that it's always easier to restore a complete image than reinstall the OS with all optimizations. It should be less time-consuming to figure out what part of the flash contains the important parts, and then only use JTAG for that (if necessary). Unfortunately, copying the flash using JTAG is excruciatingly slow, but if you want to be safe and extract the entire 8MB flash, then proceed below.

To back up the entire contents of the flash using JTAG, you do this:

$ jtag
jtag> cable parallel 0x378 WIGGLER
jtag> detect
jtag> detectflash
jtag> readmem 0x50000000 0x800000 Filename-LE.img

where "Filename-LE.img" is a little-endian version of the complete contents of flash. If you want to create a big-endian version (to be loaded by RedBoot), you would do this:

$ jtag
jtag> cable parallel 0x378 WIGGLER
jtag> detect
jtag> detectflash
jtag> endian big
jtag> readmem 0x50000000 0x800000 Filename-BE.img

This will probably take about 4 hours or more.

To restore the entire contents of flash (once replaced), using JTAG, do the following:

$ jtag
jtag> cable parallel 0x378 WIGGLER
jtag> detect
jtag> detectflash
jtag> eraseflash 0x50000000 64
jtag> endian little
jtag> flashmem 0x50000000 Filename-LE.img

This will probably take more than 8 hours (the flash has to be erased, the file is uploaded, and the file is compared against what was uploaded). Since there are better ways to do this (i.e., back up flash in linux from /dev/mtd* to a file, get the file off the NSLU2, strip out RedBoot using slugimage, then only JTAG RedBoot, then boot into RedBoot and upload with RedBoot via TFTP the entire image), I am not sure why anyone would want to do this, unless there are other issues with doing it as mentioned.

view · edit · print · history · Last edited by jojo.
Based on work by Koeck, Rob Lockhart, kawk, jeanjacquesgoessenswanadoofr, rwhitby, Michael, Simon Ruggier, Szafran, Stelutesoft, alec_v, tman, and kinsa.
Originally by kinsa.
Page last modified on July 27, 2010, at 06:19 PM