[U-Boot] freescale i.MX28 mxsboot NAND booting on mx28evk bad blocks

Trent Piepho tpiepho at gmail.com
Sat Apr 6 09:18:10 CEST 2013


On Apr 5, 2013 9:28 PM, "Paul B. Henson" <henson at acm.org> wrote:
>
> On 4/4/2013 3:09 AM, Trent Piepho wrote:
>
>> It's something to do with the way u-boot writes to nand.  If I write
>> with nandwrite it doesn't happen, nandtest doesn't find any bad
>
>
> Hmm, I'm pretty sure I tested burning the u-boot generated nand image with nandwrite under Linux with exactly the same result, it seems to be inherent in the underlying data, not the burn method.

> Did you use the --oob option to nandwrite? The u-boot generated image is actually written in two separate steps, the initial piece is written raw and includes oob data, the second piece is written normally and the ecc/oob is generated by the hardware. To burn it under linux, you need to split the u-boot nand image into those two pieces, and write the first with -oob, and the second normally.

Did you already have the bad sectors when you burnt under Linux?  I
hadn't used --oob under linux, which as you've said doesn't work.
I've now burnt with kobs-ng a working nand image and have no bad
sectors.

I looked into this more and haven't entirely figured it out.  It's
definitely something to do with the raw sectors vs BCH protected
sectors.

I don't think the image u-boot mxsboot generates includes any OOB
data.  For me, it made an image which is *exactly* 24 blocks of 128
kiB each.  If the FCB blocks had OOB data then there would need to be
some multiple of 64 OBB bytes in the image (16 kiB I would think).  I
think maybe this is the problem.  The update_nand_full script calls
"nand write.raw ${loadaddr} 0x0 ${fcb_sz}" and write.raw expects
loadaddr to contain $fcb_sz pages of (2048 + 64) bytes each.  But a
hexdump of the u-boot image:
00000000  00 00 00 00 00 00 00 00  00 00 00 00 d6 fc ff ff  |................|
00000010  46 43 42 20 00 00 00 01  50 3c 19 06 00 00 00 00  |FCB ....P<......|

00020000  00 00 00 00 00 00 00 00  00 00 00 00 d6 fc ff ff  |................|
00020010  46 43 42 20 00 00 00 01  50 3c 19 06 00 00 00 00  |FCB ....P<......|

There is the first FCB block at offset 0.  And the second FCB block at
offset 0x20000.  That's 64 * 2048 bytes, not 64 * 2112 bytes.  No OOB
data.  The next two FCBs are at 0x40000 and 0x60000, again not where
they should be if they contained the OOB data.

So I think the reason flashing with u-boot didn't work for me is that
the u-boot script vs mxsboot are broken.  The script expects OOB data
in the first 4 blocks while mxsboot doesn't put any there.  I wonder
if the way mxsboot or write.raw work has changed recently and one is
out of date?

Now the BCH error correction is interesting.  When it's used, the nand
page does not consist of 2048 bytes of data and 64 oob bytes of ecc.
Instead it's something like 10 bytes metadata, 512 bytes data, 13
bytes ecc, 512 bytes data, 13 ecc, etc.  The data and the ECC are
intermixed!  So if you write a page in BCH mode and then read it in
RAW mode, or vice versa, you get completely incorrect data back.

This is why writing with nandwrite doesn't work.  The ROM bootloader
expects the FCB blocks, which contain the BCH parameters, to be in raw
mode and apparently expects the rest to be in BCH mode.  If you write
with nandwrite everything is in BCH mode and thus the FCBs will be in
the wrong format and not read correctly.  The FCB blocks actually only
use the first 1036 bytes so the OOB data doesn't matter to the
bootloader, but since it's written in BCH mode everything is in the
wrong location.

>> A bad block on that chip is marked with a non-0xff as the first OOB
>> byte in the 1st page of a block.  So, my guess is that when u-boot
>> writes the FCB data it also writes something to the OOB data.
>
>
> Yes, as would linux if you used the --oob option to nandwrite.

Does this work for you?  As I see it, one would need to first generate
an image with OOB data, i.e. 2112 bytes pages, for the FCB blocks and
mxsboot doesn't do that.  Then you would need to get this written in
RAW mode.  I don't think nandwrite will do this, even with the --oob
option.  It's still in ECC mode.  The GPMI driver does not support
writing OOB data (see gpmi_ecc_write_oob(), all it does is return
-EPERM).  It does have a RAW mode write option, which is what kobs-ng
uses to write the FCB blocks.

>> You said you've booted from NAND.  Did you have to program any of the
>> OTP fuses to do this?
>
>
> No. All I did was install the actual NAND chip and update the boot dip switches. Testing u-boot, I followed the script in the default environment other than updating it to load the firmware from SD rather than tftp. For testing under Linux, I used dd to split the u-boot nand image into two pieces, corresponding to the u-boot burn instructions.

What instructions are those?  I didn't see anything in the
README.mx28_common file about that.  I think that could work, if you
re-blocked the FCB pages with ibs=2048 obs=2112 count=256.

I think this explains why the pages become "bad".  If you did this
then the OOB data added by dd with be all zero.  That first byte not
being 0xff anymore would mark the page as bad.  The bootloader doesn't
care since it ignores those marks, but Linux doesn't ignore them.  The
solution would be for u-boot to not write into the OOB data when
writing the FCBs.  This is what the kobs-ng program does.  It puts the
nand driver into raw mode and then writes 2048 byte pages for the FCB,
leaving the OOB data untouched.  U-boot appears to write the OOB data
(with all zeros), causing the pages to become marked as bad.

I think the u-boot method is somewhat problematic with regards to how
the NAND and ROM bootloader work.  It's nice to have a "smart" image
generator that does everything to make a raw image that you then flash
with any "dumb" flasher.  That's how we used to do things with NOR.
So much easier.  But the hardware really doesn't lend itself to this
anymore.  A "smart" flasher like kobs-ng seems more in line with what
the hardware calls for.

1) To create a correct image one needs to have all these details of
the hardware.  Page size, block size, BCH mode, ROM bootloader stride
and count configuration for the FCB and for the DBBT, nand timing to
put in FCB, etc.  A smart flasher can just query the drivers and get
all these values directly.  The smart image generator needs to get
told all these by someone transcribing them from the system.  Some can
be calculated, but then the code for that duplicates the code in the
driver and must be kept up to date as hardware and drivers change.  It
also means the image generated by the smart image generator can is
very hardware specific and can not cope with minor hardware changes.
E.g., the .sb file can be flashed onto any nand chip but the .nand
file can't be.

2) Some parts of the image needs to be written in raw mode, some in
ecc mode.  The image doesn't say.  So the "dumb" flasher still needs
to figure that out, by duplicating calculations from block size, ROM
bootloader stride and count fuse settings, etc. that the image
generator also did.

3) Lots of the image is actually blank.  There is a difference between
not programming a NAND page and programming a NAND page to all 1s.

4) This seems like the big problem to me.  The mxsboot system can't
cope with bad blocks.  It just creates a blank DBBT table.  What you
need to do is query the mtd driver and get the bad block list and then
use that to construct an accurate DBBT and then not use those bad
blocks.  kobs-ng can do this (not sure if it actually does).

> Are you targeting burning the nand with u-boot or linux? If you are using an older kernel, the kobs-ng that comes with the mx28 BSP works fine. It does not work with newer kernels though, there is a newer version of kobs-ng that comes with a different chip BSP that I've heard will work correctly on current kernels, it is on my to do list to try it out.

I'd like to burn from Linux.  It's easier to create an end user
firmware update system in linux than in u-boot.  The kobs-ng that
comes with the BSP does indeed not support the mainline kernel.  Why
Freescale can't update the BSP I don't know.  So maybe easy to fix
bugs.  I ported that kobs-ng to the current kernel, then discovered
there was the new version that already worked.  This does work to
flash u-boot or a kernel to nand from linux.  It doesn't write the OOB
data when it flashes the FCBs and so the blocks don't get marked bad.


More information about the U-Boot mailing list