.. post:: 2010-07-30 :category: linux, embedded :author: Jörg Faschingbauer :location: Hart bei Graz, Austria :language: en Beagleboard: How to Repair NAND (also known as 40W) =================================================== .. sidebar:: Contents .. contents:: :local: It happened again. Friends of mine have an alias, .. code-block:: console 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 .. code-block:: console 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. .. code-block:: console 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. .. code-block:: console 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. .. code-block:: console 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). .. code-block:: console 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. .. code-block:: console 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 .. code-block:: console OMAP3 beagleboard.org # help nand instead of ``nand erase``. I suggest you type .. code-block:: console OMAP3 beagleboard.org # nand erase 280000 400000 just like the kernel source says for the kernel partition.