Telechips NAND Info
Description
This page is intended to collate known information about the Telechips NAND Flash Translation Layer (TNFTL). Various string references to "TNFTL" are present in the Logik DAX, Cowon D2 and iAudio 7 firmwares (and on the flash memory itself) so this information should be applicable to all these devices, and potentialy other Telechips-based devices.
Terminology used in this document:
- "Sector" - 512 byte (+16 spare) section of a physical page
- "Block", "Page" - as per SAMSUNG datasheet
- "Segment" - group of 4 blocks (one from each plane, as per "Memory Map" section of SAMSUNG datasheet)
- "Segment Number" - logical address of a physical segment
NOTE: Information here has been gathered from a 4Gb Cowon D2 (2 banks of SAMSUNG K9LAG08U0M; 2048+64 byte pages, 128 pages per block) and therefore will need confirmation and/or adjustments for other models, eg the 8Gb D2 has 4096+128 byte pages.
Page Layout
Each physical page is divided into a number of 512+16 byte sectors. The 16 bytes of spare/oob data appears immediately after the data for each sector (not at the end of each page as the SAMSUNG datasheet implies) and contains the following data:
Offset |
Size |
Description |
0 |
2 |
Unknown (ECC checksums?) |
2 |
2 |
Page Number (block type 0x15 only) ? |
4 |
1 |
Block Type - see below |
5 |
1 |
Unknown (usually 0x00) |
6 |
2 |
Segment Number (block types x3, x5, x7) |
8 |
8 |
Unknown (ECC checksums?) |
Note that the factory bad block marking scheme suggested by the SAMSUNG datasheet (last page of each bad block has byte 2048 /= 0xFF) appears not to be used, since this byte will usually contain valid page data. It is not currently known how bad blocks are identified - is there a bad block table stored somewhere yet to be discovered?
Block / Segment Layout
All data stored on the device (except for reserved blocks and the NAND Boot area) is arranged in segments of 4 blocks, corresponding to the 4 planes referred to in the "Memory Map" section of SAMSUNG datasheet.
To read sequential data from a segment, use the following sequence:
0: Block n, page 0
1: Block n+0x1000, page 0
2: Block n+1, page 0
3: Block n+0x1001, page 0
4: Block n, page 1
..etc..
Reserved Blocks
The first Segment of each bank (ie. blocks 0, 1, 0x1000 and 0x1001 for
K9LAG08U0M) is reserved and contains the following data in Block 0, Page 0:
Offset |
Size |
Description |
2048 |
4 |
String "BMPM" |
2052 |
1 |
0x02 (number of banks present?) |
For bank 0 only, the following data is also present:
Offset |
Size |
Description |
1536 |
16 |
Serial number? eg. string "0283310033F839B0" |
1552 |
4 |
Unknown eg. 0xb0a861b2 |
1556 |
4 |
String "FWDN" |
1560 |
8 |
zeroes |
1568 |
16 |
Serial number? eg. string "90705170241305D1" |
1584 |
4 |
Unknown eg. 0x424329d6 |
1588 |
4 |
String "FWDN" |
2108 |
1 |
Unknown, eg. 0x04 |
2109 |
2 |
Block number of NAND Boot Area header |
NB: the offsets here may be specific to the particular page size in use - needs confirmation.
Block Types
Excluding the first two blocks of each bank (see above), pages within each block on the device are marked with one of the following block types:
Id |
Description |
Area |
0x12 |
Block Translation Table |
Data Area |
0x13 |
Data |
"" |
0x15 |
Recently-written data |
"" |
0x17 |
Data |
"" |
0x21 |
Signature |
Hidden Data Area |
0x22 |
Block Translation Table |
"" |
0x23 |
Data |
"" |
0x25 |
Recently-written data |
"" |
0x27 |
Data |
"" |
0x31 |
Signature |
"Multi Hidden" Data Area |
0xE0 |
NAND Boot Area |
0xFF |
Unused/Erased |
Block Types 0x12 / 0x22 (Translation Table)
Segments where the first sector is marked 0x12 or 0x22 are used to store logical Segment Number to Physical Address lookup tables for the Main Data area and Hidden Data area, respectively. This consists of a set of 32-bit values in sector 0 of each populated page, where each value represents the physical Block Number / 2. Note that page 0 appears to always be empty, apart from the block type identifier.
Questions:
- there are four 0x12 segments on my D2 - how do I determine the order of data? are they all current or duplicates?
- if the values are Block Number / 2, how do we tell whether this refers to bank 0/1?
I've confirmed that, for the hidden data area (0x22) at least, the translation table contains 9 valid pointers to segments marked with Segment Numbers 0 to 8. The main data area will take more effort to confirm, as there are 3812 sequential segments spread across the two NAND banks.
Block Types 0x13 / 0x23 (Data)
These are the main data storage blocks. Each physical segment is marked with the logical Segment Number that the data belongs to. Sequential data can be read using the scheme detailed in "Block / Segment Layout".
Block Types 0x15 / 0x25 (Recent Writes)
These blocks appear to contain a cache of recently-written page data. Layout / usage TBC.
Block Types 0x17 / 0x27 (Data)
These blocks appear identical to blocks 0x13 and 0x23, except that the first page of the block is marked with an 0x17 identifier. The purpose of this is unknown.
Block Type 0x21 (Hidden Signature)
Block n+0, Page 0 contains the string "TNFTLHIDDENSIGNATURE" plus four 0x00 bytes.
Block n+1, Page 0 contains the 32-bit value 0x1cbb9
Block Type 0x31 (Multi Hidden Signature)
Block n+0, Page 0 contains the string "TNFTLMULTIHIDDENSIGNATURE", then 0x00 0x45 0x00.
Block n+1, Page 0 contains the 32-bit value 0xfed
Block Type 0xE0 (NAND Boot Area)
The NAND Boot Area is a sequence of blocks starting at the Block Number referenced in Bank 0, Block 0, Page 0 (see Reserved Blocks above). It consists of a header block which contains pointers to Block Numbers containing the D2 firmware (4Mb in size). Immediately following this is a second header block, and a second copy of the firmware.
Questions that need answers
To complete read support:
- What is the purpose of 0x17 blocks?
- What is the format of 0x15 Recent Write blocks? Does this data need overlaying over the appropriate 0x13 / 0x17 data during a read operation?
- How do the Translation Table blocks join together to form a coherent mapping table? (nb. this is less important than it looks - simply scanning the flash for 0x13 / 0x17 blocks results in a fully populated translation table in a fraction of a second)
- Investigate ECC checksums
Required for write support:
- Complete understanding of 0x15 & 0x17 blocks
- Complete understanding of translation tables
- How are bad blocks managed / marked / identified ?
- How to calculate ECC checksums
- Is wear levelling required, or can we cheat and replace pages in-situ?
I suspect we do need to implement wear-levelling, since the SAMSUNG datasheet states "even write-intensive systems can take advantage of the
K9LAG08U0M's extended reliability of 5K program/erase cycles
by providing ECC (Error Correction Code) with real time mapping out algorithm".
Less importantly (since we don't care about the hidden areas):
- What is the purpose of the "Signature" blocks?
Copyright © by the contributing authors.