[U-Boot] i.MX3 NAND: trying to understand OOB handling

Philip Paeps philip at paeps.cx
Mon Apr 15 22:50:06 CEST 2013


I am in the process of upgrading a customer's i.MX35-based design to
state-of-the-art U-Boot.  The board previously booted from NAND using a
home-grown SPL.  Since I'm doing some heavy-lifting anyway, I decided to
try out Benoît's patches and use U-Boot's SPL bits and they work well
for me (thanks, Benoît!).

My NAND has 4K pages and speaks ONFI, though I now also have 2K NANDs to
test with.  I managed to hack mxc_nand.c and mxc_nand_spl.c to the point
that I can now boot successfully from 2K and 4K ONFI NANDs.  I'd like to
clean up my changes and contribute them.

That was the good news. :-)

Unfortunately, the more I look at the code (and the Linux code, and
patches on mailing lists and the datasheet), the more confused I'm
getting about the OOB handling.  In particular: where does the NFC
hide the factory bad block markers.

Using a (mostly) unmodified driver, none of the virgin chips I've looked
at have any factory bad blocks on them.  I find that hard to believe.

My NANDs have factory bad block markers in the first spare byte of the
first or the second page of every bad block.  The "or" in the previous
sentence suggests to me that I want to set NAND_BBT_SCAN2NDPAGE in
bbt_{main,mirror}_descr.options.  I probably want to make that bit
conditional on a board option.

The i.MX35 reference manual tells me that 2K and 4K NANDs are read 512
bytes at a time, so that the layout in SRAM will be:

 | 512 + 16 | 512 + 16 | 512 + 16 | 512 + 16 |
 |<------------------ 2112 ----------------->|

or

 | 512 + 26 | 512 + 26  |  [...]  | 512 + 36 |
 |<------------------ 4314 ----------------->|

(the extra spare bytes are appended to the last section)

That would put the factory bad block marker somewhere in the data
section, but depending on how you interpret the datasheet, it could be
at a number of different offsets.  Patches posted to various mailing
lists suggest that 0x7D0 is a popular assumption, but I've not managed
to encounter a convincing reasoning for that offset over any of the
other options.

To confuse matters further, send_{prog,read}_page() in mxc_nand.c does a
little dance to allegedly make the spare data contiguous.  Is this
really spare data in the case of 2K or 4K pages though?  Or is that code
actually corrupting data?  Given that Linux does the same dance, and
that it's doing the same dance both reading and programming, it "works",
but that code makes me a little uneasy.  I feel quite strongly that the
bytes we access through a pointer named "spare" are actually OOB bytes
and not secretly in the data area.

Further down in mxc_nand.c, mxc_nand_read_oob_syndrome() also interprets
the layout of the SRAM buffer, apparently so that it can get the "real"
ECC data.

Bolting on code to make 4K pages work doesn't make this any prettier, so
I'd like to take the opportunity to refactor this a bit.  Before I hack
myself into a corner though, I'd like to make sure that I understand the
mapping between the SRAM buffer and the actual NAND correctly.

I'd be grateful if others who have looked at this code could share their
understanding.

Thanks!

 - Philip

-- 
Philip Paeps
Senior Reality Engineer
Ministry of Information


More information about the U-Boot mailing list