Beagleboard: How to Repair NAND (also known as 40W)

It happened again. Friends of mine have an alias,

alias faschingbauer="rm -rf ~"

in their .bashrc for a couple of years now, and now I created a creative variation thereof.

I used to have my beagleboard running happily off an SD card, using a root filesystem which I had updated natively from a Gentoo ARM stage3. This is decadent, so I prepared a Busybox-only initramfs linked into the kernel image (cross-built of course, as opposed to the stage3), with the plans to use this as an alternative boot image residing in NAND flash.

It happened to me that, during finding out the correct arguments of U-Boot’s nand erase command, I hit the return key early - expecting that a sole

nand erase

would give me further instructions. U-Boot took it literally though and erased NAND, just like I told it to. A reboot showed the fatal consequences. “40W” was the only thing I saw over the serial terminal (115200/8N1 by the way).

Here in the remainder I write down how to recover from such a fauxpas. The internet has a lot of explanations, but none of them is a walk-through from the beginning to the end. You’ll have to do a couple of things, and most of the instructions you’ll find don’t explain much. This is not what I like, so I researched a bit and write the annotated collected instructions down right here. You might find it useful - I surely will once I’ll brick my beagle again.

Basics

The OMAP has a small boot ROM inside. This is the first of the chain of boot loaders, and it’s where the CPU core jumps to when it’s done with whatever CPU cores do when they are powered on). The boot ROM is programmed to load a second stage boot loader (the “X-Loader” as it is called) into the processor’s SRAM. X-Loader is then responsible for loading another stage - U-Boot in the Linux case - into the external DRAM. It’s the latter two stages - X-Loader and U-Boot - that I faschingbauered away from NAND, and that I’ll recover now.

They key to all that is the ability of the boot ROM to boot from a MMC/SD card when the user button is pressed during its operation. We will prepare one such card, put the boot files on it, and write these to NAND.

Getting X-Loader and U-Boot

The beagleboard guys wrote up a page with board validation instructions. This is where I have most of the information from. There they give links to the images that I want. Take care that you select the ones that match your board revision; the files they use on that page are slightly seasoned. I have a recent C4, and I found it valuable to have a recent U-Boot version that enables power on the USB host controller. This was a change they made from C3 to C4, for example - take care.

Anyway, Angstrom have the most recent stuff. Download X-Loader and U-Boot from there, and additionally another bootloader stage, MLO, which is used during the MMC boot. The filenames change, just browse the directory a choose something that sounds like x-load.bin.ift, u-boot*, MLO*. Save them away for later use. I saved them as x-load.bin.ift and u-boot.bin, and it’s these names that I refer to later on.

Creating a Bootable MMC/SD card

For basic card configuration I refer you to a TI maintained page which is very concise and to the point, and where there is nothing much left to say. I followed the instruction using fdisk, and obvoiusly the card can be read by the boot ROM. There are reports that FAT32 does not work on some cards, and that selecting FAT16 instead helped. You might want to try that out in case.

Once the card is ready and a FAT partition has been created, you mount that partition and put the files on it as follows.

  • First comes MLO, as file MLO, no matter what name you stored it under on your disk. It is read by the boot ROM, and that one is very particular that the file is found in the first sectors.

  • You store the U-Boot image as file u-boot.bin. MLO expects it under that name during MMC boot. (If you intend to use a different U-Boot image for NAND then you store that one under a different name which you use further down when we write NAND.)

  • The X-Loader is not used during MMC boot, so you can choose any name you like.

Insert the card into the MMC/SD slot of the beagle, and boot. In case you erased your NAND only partly and there is still something meaningful in it, be sure to hold down the user button to force the boot ROM to boot from the card.

Repairing the NAND

The following is taken from the reset.scr U-Boot script referred to by the beagleboard validation instructions. I took care to annotate as much as possible in order to understand the steps.

First off, we initialize MMC/SD.

OMAP3 beagleboard.org # mmc init
mmc1 is available

To understand where the numbers in the remainder instructions come from, open the kernel source file arch/arm/mach-omap2/board-omap3beagle.c. I’ll refer to that file in the remainder explanations. Near the top of the file you’ll notice the partition table; you’ll find it insightful.

Writing X-Loader to NAND

First, erase the X-Loader partition. According to the partition table, it starts at offset 0 (where the OMAP’s boot ROM expects it) and is 4*128K=0x80000 bytes long.

The boot ROM relies on hardware to manage error correction code (ECC), as described in the tech note, so we select it.

OMAP3 beagleboard.org # nandecc hw
HW ECC selected

OMAP3 beagleboard.org # nand erase 0 80000
NAND erase: device 0 offset 0x0, size 0x80000
Erasing at 0x60000 -- 100% complete.
OK

According to the tech note again, the OMAP’s boot ROM takes care of bad blocks (unlikely because an intermediate bootloader isn’t written to flash that often, but nevertheless it sounds like a good idea). It checks the first four blocks of the X-Loader partition for a valid image, so we write the image into these four blocks. Again, the erase block size is determined by looking in board-omap3beagle.c - 128K = 0x20000.

Read the image into memory, and write it out 4 times, in the first four erase blocks of the partition.

OMAP3 beagleboard.org # fatload mmc 0 80200000 x-load.bin.ift
reading x-load.bin.ift
20392 bytes read

OMAP3 beagleboard.org # nand write 80200000 0 20000
NAND write: device 0 offset 0x0, size 0x20000
131072 bytes written: OK

OMAP3 beagleboard.org # nand write 80200000 20000 20000
NAND write: device 0 offset 0x20000, size 0x20000
131072 bytes written: OK

OMAP3 beagleboard.org # nand write 80200000 40000 20000
NAND write: device 0 offset 0x40000, size 0x20000
131072 bytes written: OK

OMAP3 beagleboard.org # nand write 80200000 60000 20000
NAND write: device 0 offset 0x60000, size 0x20000
131072 bytes written: OK

Writing U-Boot to NAND

Can’t find which ECC incarnation the X-Loader uses, software seems to be the choice (sounds like the do-nothing-and-cross-fingers approach).

OMAP3 beagleboard.org # nandecc sw
SW ECC selected

According to the kernel sources, U-Boot’s partition starts at offset 0x80000 and is 15*128K=0x1e0000 bytes long.

Erase NAND, load U-Boot from card, write it to the partition.

OMAP3 beagleboard.org # nand erase 80000 1e0000
NAND erase: device 0 offset 0x80000, size 0x1e0000
Erasing at 0x240000 -- 100% complete.
OK

OMAP3 beagleboard.org # fatload mmc 0 80200000 u-boot.bin
reading u-boot.bin
275928 bytes read

OMAP3 beagleboard.org # nand write 80200000 80000 1e0000
NAND write: device 0 offset 0x80000, size 0x1e0000
1966080 bytes written: OK

That’s it. You are now able to boot without the card, up to the U-Boot prompt.

Take care when you flash the kernel. In case you don’t know the correct nand erase parameters, write

OMAP3 beagleboard.org # help nand

instead of nand erase. I suggest you type

OMAP3 beagleboard.org # nand erase 280000 400000

just like the kernel source says for the kernel partition.