Saturday, December 7, 2013

How to unbrick a Sheevaplug

Sometime, doing development on a board, is possible to end up with the board bricked.
Bricked means that the board is TOTALLY dead, no prompts, no possibility to issue commands, nothing happens.

It happened to me today with a Sheevaplug.
Here how I unbricked my Sheevaplug.

As usual the first thing to do in these cases is to seat down, breath slowly and repeat : DON'T PANIC :)


The first thing to do in these cases is to search for procedures/tools specific for the Sheevaplug.
Of course the main source of information almost always is broken. For example the main website for the Sheevaplug is the Plug website .
Until few months ago there was a nice Wiki containing all the information necessary to unbrick a Sheevaplug, now the wiki is missing.
A lot of posts are pointing to Wiki articles that are not existing anymore.

Unbrick it

There are many procedures that "in theory" can be used to unbrick a Sheevaplug.

However the one described here is the one that is working, found on this forum .

On the host machine connected to the Sheevaplug via USB, is necessary to have installed a package called openocd, telnet and screen.
My host machine is based on Xubuntu 12.04 so :

$ sudo apt-get install telnet screen openocd

At this point, be sure to have the Sheevaplug connected to the host machine via the USB cable (it simulating a serial port) and power it up.
Note ! In my case, the host machine is a virtual machine under VirtualBox, so it is necessary to go on Devices/USB Devices and enable the Sheevaplug serial port (it could be marked as FTDI Sheevaplug JTAGkey).

Then unless to work always with sudo, set the USB serial port to the user (in my case steve).
Usually the connection is set up as ttyUSB0, but better to check :

$ sudo chown steve /dev/ttyUSB0


$ screen /dev/ttyUSB0 115200

It is normal that nothing happens at this point.

Now we have to open a second terminal and run this command :

$ sudo openocd -f /usr/share/openocd/scripts/board/sheevaplug.cfg -s /usr/share/openocd/scripts
If everything is OK we should see something like that :

$ sudo openocd -f /usr/share/openocd/scripts/board/sheevaplug.cfg -s /usr/share/openocd/scripts
[sudo] password for steve:
Open On-Chip Debugger 0.5.0 (2011-12-03-08:57)
Licensed under GNU GPL v2
For bug reports, read
Info : only one transport option; autoselect 'jtag'
2000 kHz
trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain
adapter_nsrst_delay: 200
jtag_ntrst_delay: 200
dcc downloads are enabled
Warn : use 'feroceon.cpu' as target identifier, not '0'
Info : clock speed 2000 kHz
Info : JTAG tap: feroceon.cpu tap/device found: 0x20a023d3 (mfg: 0x1e9, part: 0x0a02, ver: 0x2)
Info : Embedded ICE version 0
Info : feroceon.cpu: hardware has 1 breakpoint/watchpoint unit

At this point nothing should happens.

Now we need to open another terminal and create a temporary directory where to store a bootloader :

$ mkdir temp
$ cd temp
$ wget

In the directory temp now we have a recovery version of the bootloader for the Sheevaplug.

From there we need to open a telnet session with openocd :

$ telnet localhost 4444

We should see something like that :

$ telnet localhost 4444
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger

At this point we can issue the command :

> reset;sheevaplug_init;load_image u-boot.elf;resume 0x00600000

This should load the bootloader and start it.
If everything is OK, on the terminal connected to the Sheevaplug USB cable we should see :

__ __ _ _
| \/ | __ _ _ ____ _____| | |
| |\/| |/ _` | '__\ \ / / _ \ | |
| | | | (_| | | \ V / __/ | |
|_| |_|\__,_|_| \_/ \___|_|_|
_ _ ____ _
| | | | | __ ) ___ ___ | |_
| | | |___| _ \ / _ \ / _ \| __|
| |_| |___| |_) | (_) | (_) | |_
\___/ |____/ \___/ \___/ \__|

U-Boot 1.1.4 (Apr 9 2009 - 12:23:12) Marvell version: 3.4.16
U-Boot code: 00600000 -> 0067FFF0 BSS: -> 006CEE60
Soc: MV88F6281 Rev 3 (DDR2)
CPU running @ 1200Mhz L2 running @ 400Mhz
SysClock = 400Mhz , TClock = 200Mhz

DRAM CAS Latency = 5 tRP = 5 tRAS = 18 tRCD=6
DRAM CS[0] base 0x00000000 size 256MB
DRAM CS[1] base 0x10000000 size 256MB
DRAM Total size 512MB 16bit width
Flash: 0 kB
Addresses 8M - 0M are saved for the U-Boot usage.
Mem malloc Initialization (8M - 7M): Done
*** Warning - bad CRC or NAND, using default environment

CPU : Marvell Feroceon (Rev 1)

Streaming disabled
Write allocate disabled
USB 0: host mode
PEX 0: interface detected no Link.
Net: egiga0 [PRIME], egiga1
Hit any key to stop autoboot: 0

Better to hit any key to stop the autoboot.
A Marvel prompt will appear.

At this point a bootload is running on the Sheevaplug but it is necessary to write it in the NAND, otherwise the next time the unit is powering up, the unit will remain bricked !

There are many ways to save a bootloader in the NAND.
The first step is to retrieve a bootloader.
For this test I used a bootloader suggested from a blog describing how to install a Debian distribution on the Sheevaplug.
Here the link :

I used  a TFTP server to load the bootloader on the Sheevaplug.
In the TFTP server (usually a directory called tftpboot) put the bootloader you want to be installed, it is usually named u-boot.kwb.

Then on the terminal connected to the serial port, at the prompt Marvel :

Marvell>> setenv serverip
Marvell>> setenv ipaddr

These two lines assign the IP address for the server hosting the TFTP and the IP address of the board.
A bootloader called u-boot.kwb is loaded in the tftpboot directory of the server.

Marvell>> tftpboot 0x0800000 u-boot.kwb
Using egiga0 device
TFTP from server; our IP address is
Filename 'u-boot.kwb'.
Load address: 0x800000
Loading: #################################################################
Bytes transferred = 372544 (5af40 hex)
Marvell>> nand erase 0x0 0x60000

At this point we have the bootloader code loaded in the Sheevaplug RAM.
We need to clean up the NAND and load the bootloader in it.

NAND erase: device 0 offset 0x0, size 0x60000
Erasing at 0x40000 -- 100% complete.

Marvell>> nand write 0x0800000 0x0 0x60000
NAND write: device 0 offset 0x0, size 0x60000
393216 bytes written: OK

If everything is OK, the new bootloader is loaded in the NAND.
Resetting the Sheevaplug we obtain :

U-Boot 2011.12 (Mar 11 2012 - 18:59:46)
Marvell-Sheevaplug - eSATA - SD/MMC

SoC: Kirkwood 88F6281_A1
DRAM: 512 MiB
WARNING: Caches not enabled
NAND: 512 MiB
NAND read from offset 60000 failed -74
*** Warning - readenv() failed, using default environment

In: serial
Out: serial
Err: serial
Net: egiga0

88E1116 Initialized on egiga0
Hit any key to stop autoboot: 0

We are almost done !
The last step is to assign the correct MAC address to the Sheevaplug.
To do so, first write down the MAC address of the board. The MAC address assigned to the board is present on a label on the bottom of the Sheevaplug.

Then, at the Marvell prompt :

Marvell>> setenv macaddr xx.xx.xx.xx.xx.xx  # where xx are the digits of the MAC address
Marvell>> saveenv   # save the new address

The Sheevaplug is unbricked and ready for a fresh new installation.

Useful links

Here some links that helped me.


  1. Thanks.

    There's one error: "apt-get install telnet, screen, openocd" → no commas → "apt-get install telnet screen openocd".

    Also, it didn't work for me: Even though I was located in the ./temp directory that had u-boot.elf, "reset;sheevaplug_init;load_image u-boot.elf;resume 0x00600000" said: "Error: couldn't open u-boot.elf".

    1. Thanks to point it out. I'll fix the text.
      However on my distro the comma doesn't cause any error, but you're right, the comma should not be there.
      Sorry to hear it didn't work. On my it worked (I'm glad of that :) )

  2. Found it: Before launching the OpenOCD server, change to the ./temp directory where u-boot.elf was copied for OpenOCD to find the file.

  3. "Resetting the Sheevaplug we obtain": This doesn't mean using a pin to push on the reset button next to the mini-USB port: This means typing the "reset" command. Using the pin doesn't work.