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

Paul B. Henson henson at acm.org
Thu Apr 11 02:20:06 CEST 2013


Let me just preface this reply with the disclaimer that I'm fairly new
to embedded development, and it sounds like you know a lot more about
what you're talking about than I do ;).

On 4/6/2013 12:18 AM, Trent Piepho wrote:

> 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 did not have any bad blocks before I tried to burn the mxsboot
generated image to nand from Linux using nandwrite. You misunderstood me
though, I was able to exactly replicate the outcome from burning the
image with u-boot using Linux nandwrite. The board successfully booted
from NAND after burning the image with nandwrite, but resulted in the
exact same bad blocks.

> I've now burnt with kobs-ng a working nand image and have no bad
> sectors.

Yes, when I burn the bootstream with kobs-ng, I also do not get any bad
blocks on the nand.

> 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.

I'm not sure what you mean. According to u-boot:

Device 0: nand0, sector size 128 KiB
   Page size      2048 b
   OOB size         64 b

The page size is 2048 bytes, with 64 bytes of oob data, for a total of
2112 bytes.

When I burn the first part of the image with u-boot:

MX28EVK U-Boot > nand write.raw ${loadaddr} 0x0 ${fcb_sz}

NAND write:  540672 bytes written: OK

It writes 540672 bytes, which is evenly divisible by 2112 (256).

If you look at the mxsboot source code:

   for (i = 0; i < STRIDE_PAGES * STRIDE_COUNT; i += STRIDE_PAGES) {
         offset = i * nand_writesize;
        memcpy(buf + offset, fcbblock, nand_writesize + nand_oobsize);
    }

It appears to be writing the FCB including oob data.

> I wonder if the way mxsboot or write.raw work has changed recently
> and one is out of date?

I used the latest git head of the ARM branch when I was testing a few
weeks ago.

> 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.

Unless I am misunderstanding the u-boot instructions, the FCB blocks are
written in raw mode:

MX28EVK U-Boot > nand write.raw ${loadaddr} 0x0 ${fcb_sz}

NAND write:  540672 bytes written: OK

and the rest is not:

MX28EVK U-Boot > setexpr update_off ${loadaddr} + ${update_nand_fcb}
MX28EVK U-Boot > setexpr update_sz ${filesize} - ${update_nand_fcb}
MX28EVK U-Boot > nand write ${update_off} ${update_nand_fcb} ${update_sz}

NAND write: device 0 offset 0x80000, size 0xa80000
  11010048 bytes written: OK

>> 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.

There are no explicit instructions for nandwrite in u-boot, I simply 
split the mxsboot NAND image into two pieces to match the pieces that 
u-boot wrote:

dd if=test.nand bs=2112 count=256 of=test-head.nand
dd if=test.nand bs=1 skip=524288 of=test-tail.nand

And then wrote the first piece with nandwrite -oob at offset 0 and the 
second with regular nandwrite at offset 0x80000. This worked exactly the 
same as using u-boot, including the four blocks being marked as bad by 
Linux.

> U-boot appears to write the OOB data (with all zeros), causing the
> pages to become marked as bad.

If you look at the mxsboot source code, they appear to be trying to 
calculate the ecc and generate the oob data, but maybe they are doing it 
wrong?

> A "smart" flasher like kobs-ng seems more in line with what the
> hardware calls for.

Yes, but unfortunately I'm not sure that's something that could be 
implemented within a running u-boot?

> The smart image generator needs to get told all these by someone
> transcribing them from the system.

The current mxsboot is not that smart :), for the most part it has 
values hardcoded and you would need to recompile it if you wanted to 
change them. But it is just the first iteration while they are trying to 
get something working.

> 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).

Does the ROM IPL pay any attention to bad blocks? I don't know exactly 
how it works, but from what I've heard it doesn't sound like it deals 
with bad blocks very well if at all.

> I'd like to burn from Linux.  It's easier to create an end user
> firmware update system in linux than in u-boot.

Yes, agreed. We've been evaluating our bootloader options for the 
project I'm working on. Initially we were going to have u-boot be the 
bootloader and directly load our production kernel. However, as you say, 
it is somewhat difficult to create a flexible update/recovery system 
within u-boot. Next we looked into using the freescale bootlets to 
directly load a bootloader/recovery linux kernel with a bundled 
initramfs that would be used for the update/recovery process, and then 
have it use kexec to load the production kernel. This worked out pretty 
well.

What I think we're going to go with is actually a hybrid of both u-boot 
and a stripped-down linux/initramfs bootloader/recovery kernel. The 
bootstream actually contains two copies of whatever object is going to 
be loaded (I'm guessing, but I assume that is because the ROM IPL 
doesn't handle bad blocks, so if the first copy can't be read it will 
just try the second). Our recovery kernel/initramfs is probably going to 
be about 5M, so it would take about 10M to be loaded directly. u-boot is 
less than 1M, so by including both, it actually uses *less* space 
(2*1+5=7, vs 2*5=10). In addition, the recommendation seems to be to 
have the IPL load the minimal amount possible, so with this 
implementation the IPL loads a tiny u-boot, which again is a lot smarter 
and more reliable about loading the larger recovery kernel, which can 
then either perform recovery options or kexec the production kernel.

> Why Freescale can't update the BSP I don't know.

Yes, it does seem in the embedded space chip manufacturers release 
something and then let it stagnate :(. I generally prefer to run more up 
to date stuff.

> I ported that kobs-ng to the current kernel, then discovered there
> was the new version that already worked.

I worked on porting it, and got to the point where it wanted to read a 
sysfs node to determine the NAND geometry which no longer existed. I was 
inquiring on the linux mtd mailing list about the possibility of getting 
that information back, when I was directed to a newer version of kobs-ng 
that comes in a different chip's BSP that's supposed to work with a 
current kernel.

> 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.

I'm glad to hear the newer kobs-ng works with a current kernel, I had 
not yet had a chance to try it out. It would be nice if Freescale just 
had a link to the latest kobs-ng, rather than trying to figure out which 
chip BSP has the newest version, but I guess that's not the way they are 
bundling things or want people to work.

At this point, while I think it would be nice in general for the u-boot 
mxsboot utility to be fixed and work correctly, I don't think either of 
us is going to need that? If the latest kobs-ng worked correctly under a 
current kernel, we can just build the u-boot.sb file and use kobs-ng 
under Linux to burn it to NAND.



More information about the U-Boot mailing list