NAND flash organization
The memory of a NAND flash is organized in a hierarchy of:
The Hynix HY27UF084G2B consists of 4096 blocks. Each block of a NAND Flash consists of 64 pages. Each page consists of 4 sectors of data (512 Byte each) and 4 small sectors (16 Byte) of spare data, i.e. a single page consists of 2112 Byte where 2048 Bytes are data and 64 Bytes are spare. 2112 Byte blocks are also called “large block” opposed to “small blocks” of 528 Bytes (holding 512 Bytes of data and 16 Bytes of spare data).
Memory: 4096 blocks × 64 pages/block × 4 sectors/page × 512 Byte/sector = 512 MiB
Spare memory: 4096 blocks × 64 pages/block × 4 sectors/page × 16 Byte/sector = 16 MiB
Overall memory: 512 MiB + 16 MiB = 528 MiB
Flash memory is read and written in pages and erased in blocks of data. Memory must be erased before it is written to! This is also true for single byte writes.
Content of the spare areas: those out of band (OOB) area store data for error detection (e.g. a checksum), correction coding (ECC, most algorithms are based on Hamming codes) and bad block markers (if ECC cannot handle the amount of errors anymore). But can also contain data for the logical/virtual organization (blocks, pages) of physical blocks and pages. The ECC is usually a vendor/model dependent algorithm.
Creating a flash dump
Know your chip
Sometimes the interface to update firmware (e.g. via JTAG or serial port) is not exposed or not easy to find. It may then be an option to take the NAND flash device from the printed circuit board. The desoldering process is followed by dumping the flash memory, sometimes referred to as “off-chip forensics” (used in security analysis and data recovery).
In a next step the device is taken and put into a NAND flash reader/writer. There are commercial tools, but they can also be built from some basic hardware. A popular choice is to build a serial/parallel to USB adapter*. The FTDI FT2232H (and a breakout board) is a good starting point as you can toggle various GPIO pins in “bit bang” mode via its USB interface (mostly used as dual-port USB/serial converter). There’s also a project about using an Arduino NAND flash reader (no focus on speed).
It’s also good to know the NAND flash memory chip’s parameters and pinout in advance. Those specifications can be read from the datasheet, if you can read the labels written on the IC package. It is possible that your flash complies with the Open NAND Flash Interface specifications.
Taking the Hynix HY27UF084G2B again as an example:
- 512M x 8bit NAND flash
- package: 48-TSOP1, dimensions: 12x20x1mm, 0.5mm pitch
- supply voltage: 3.3V (Vcc range: 2.7V..3.6V)
- memory organization already mentioned above;
page organization: separate data and spare areas, i.e. main field with 4x 512 Byte of data comes first, followed by 4x 16 Bytes spare
- timings can be read from the datasheet
- interface pins
- x8 bus width I/O interface, i.e. IO0..IO7
- nCE: chip enable
- nWE: write enable
- nRE: read enable
- RnB: ready/busy indication
- CLE: command latch enable
- ALE: address latch enable
- nWP: write protect
(8 + 7 = 15 pins needed)
- capacitance between Vcc and Vss as a buffer: 0.1 uF
- address cycle map: which address bit is latched when on the I/O interface?
- the HY27UF084G2B has 5 cycles, i.e. 5 x 8 bit = 40 potential bits
- 512M addresses needed: log2(512M)=29, i.e. only 30 bits required (A29..A0) and 10 bits to be kept at a low logic level
- definition of the device’s command set; some commands are single byte operations, others are composed of multiple bytes e.g.
- READ1 (0x00 in 1st cycle, 0x30 in 2nd cycle)
- READ ID (0x90 in 1st cycle)
- RESET (0xFF)
The READ ID command is a good one to test if the connection with the flash can be established successfully and without causing a potentially high damage to the flash device. However, you should know what you do.
The ID to be read for my chip is: 0xAD 0xDC 0x10 0x95 0x54. Those bytes can be interpreted in the following way:
- Manufacturer Code: 0xAD (=Hynix)
- Device Identifier: 0xDC
- Device Identifier Description: 0x10 = 0b00010000
- Write Cache: not supported
- Interleave program between multiple chips: not supported
- Number of simultaneously programmed pages: 2
- Cell type: 2 level cell
- Die/package: 1
- Device Identifier Description:0x95 = 0b10010101
- Serial access time: 25 ns
- Organization: X8
- Block size (w/o spare area): 128K (see above: 64 pages × 2KB/page)
- Spare area size (Bytes per 512 Byte): 16
- Page size (w/o spare area): 2KB
- Device Identifier Description (Multiplane information): 0x54 = 0b01010100
- Plane size: 2 Gbit = 256 MByte
- Plane number: 2
(*Side note: our flash IC is a parallel flash, but a similar approach could be taken for an SPI flash as well, using an SPI to USB bridge.)
Building the hardware for a DIY NAND flash reader
- TSOP-48 socket
- 0.1uF capacitor
- wires & jumper wires
- breakout board with the FTDI FT2232H (to read/write data from/to the NAND flash; communication with a host PC)
- USB cable
The pins of the TSOP-48 socket (being directly connected with NAND flash memory device) are wired with the pins of the FTDI FT2232H.
(Side note: the TSOP socket may also be used to get the NAND flash memory working in it’s embedded system environment and eavesdropping on how it is accessed with a logic analyzer – flash memory at which addresses and when, e.g. at boot.)
Using software with the DIY NAND flash reader
I will run my DIY NAND flash reader under a Linux operating system. Therefore tools which already work under Windows are not applicable here. But at least the source code of spritesmods.com ftdinandreader (Download) and Bjoern Kerler’s advancement NAND Reader FTDI can help here. I may start from scratch but also may re-use some source code.
First I got the source code and build files for libftdi. The build process and the dependencies for libftdi in turn (e.g. libusb-*-dev) are documented well in README and README.build. Afterwards I could run one of the examples coming with libftdi as I had a small breakout board with an FTDI 232RQ laying around.
$ lsusb Bus 002 Device 004: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC (...)
Let’s use the example:
/libftdi1-1.3/build/examples $ ./find_all_pp -v 0x0403 -p 0x6001 Found devices ( VID: 0x403, PID: 0x6001 ) ------------------------------------------------ FTDI (0x228c950): , , (Open FAILED)
Using higher access rights results in:
/libftdi1-1.3/build/examples $ ./find_all_pp -v 0x0403 -p 0x6001 Found devices ( VID: 0x403, PID: 0x6001 ) ------------------------------------------------ FTDI (0xd64cb0): FTDI, FT232R USB UART, <#serial> (Open OK)
There’s another example, shipped with libftdi, to access the FTDI’s internal EEPROM memory:
/libftdi1-1.3/build/examples $ ./eeprom Chip type 3 ftdi_eeprom_size: 128 0x000: 00 40 03 04 01 60 00 00 a0 2d 08 00 00 00 98 0a .@...`.. .-...... 0x010: a2 20 c2 12 23 10 05 00 0a 03 46 00 54 00 44 00 . ..#... ..F.T.D. 0x020: 49 00 20 03 46 00 54 00 32 00 33 00 32 00 52 00 I. .F.T. 2.3.2.R. 0x030: 20 00 55 00 53 00 42 00 20 00 55 00 41 00 52 00 .U.S.B. .U.A.R. 0x040: 54 00 12 03 XX 00 XX 00 XX 00 XX 00 XX 00 XX 00 T...X.X. X.X.X.X. 0x050: XX 00 XX 00 c4 7a 34 70 00 00 00 00 00 00 00 00 X.X..z4p ........ 0x060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ 0x070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 38 fd ........ ......8. 0x080: 28 04 d7 fb 00 00 c4 7a 34 70 42 00 00 00 00 00 (......z 4pB..... 0x090: 00 00 00 00 00 00 00 00 37 41 59 53 54 4c 46 43 ........ 7AYSTLFC VID: 0x0403 PID: 0x6001 Release: 0x0000 Bus Powered: 90 mA USB Remote Wake Up Manufacturer: FTDI Product: FT232R USB UART Serial: <#serial> Checksum : <#checksum> Internal EEPROM Oscillator: Internal Enable Remote Wake Up PNP: 1 Channel A has Mode UART VCP C0 Function: TXLED C1 Function: RXLED C2 Function: TXDEN C3 Function: PWREN C4 Function: SLEEP
In a next step I used some of the example code and used it in my own first C file. I compiled it using a simple Makefile and the gcc build tools.
- getting the required hardware
- assemble the parts
- unsolder the flash IC
- use/develop software to dump the NAND flash memory
- analyze the dump
- A little bit of everything – From NAND chip to files
- SpritesMods.com – FT2232H NAND flash reader
- Practical Reverse Engineering
- NAND Flash Data Recovery Cookbook