--
MarcinBukat - 2010-05-01
Fuzhou Rockchip Electronic produce a few families of
SoC for portable devices. There are some technical documents floating around for RK27xx family which makes it possible platform for rockbox.
RK27xx SoC components:
- ARM7EJ-S (ARMv5TE architecture) main core max. 200MHz
- ZSP500 DSP core max. 160MHz
- SDRAM controller
- NAND flash controller
- SD card controller
- LCD controller
- 3MPix Sensor for digital camera
- DMA controllers
- USB 2.0 host and device controllers (share the same PHY so only one at a time)
- SPI
- UART 1655
- I2C controller
- I2S controller
- 3 32-bit timers
- 4-channel PWM
- Watchdog module
- RTC module
- 4-channel ADC converter
- CODEC (24bit delta-sigma DAC + 16bit sigma-delta ADC) I2S interface
- 48 GPIO pins with interrupt capability
Devices
There are variety of generic devices build around this
SoC. They share many similarities like around 3" touch display, microSD slot, 2,4,8,16,32 GB of internal flash (usually referred as Samsung flash). Below You will find a few pictures:
Odys MP X66 NEO
This features a RK2708
SoC, 2x 4 GB flash, 2.8" 320x240 TFT, micro SD card slot, built-in speaker, TV-Out, 1.3MP camera and FM Radio.
The firmware extracting methods described below don't work. The device can be put into DFU mode (at least the vid:pid changes to 0x71b:0x3201), but rk27load (as of r30207) fails on stage1 upload.
Firmware extracting methods:
Firmware files are stored on separate, not exposed by default, system partition. In order to make this system partition visible one can put empty file with "magic" name in the root dir of the DAP. The most generic one seems to be RKLDSET.FLW (other possibilities are rkusb.tag, frk.tag, telecast.tag, telecast.sys). After placing such file in the root dir of the player, safely disconnect the device and unplug it from PC. Plugging it again should give you two drives - the main one (few GB in size) and system one (60-90MB in size).
PLEASE BE EXTREMELY CAREFUL and do not delete files form system partition unless you know what you are doing. Removing "magic" file restore default behavior and system partition is not visible.
There seem to be custom scsi commands which yield the same effect.
Boot sequence
The device start execution from 8kB bootrom (base 0x0). The bootrom searches for valid bootloader on nand flash starting from page 0. Data on the flash are stored in 528 bytes chunks (512 bytes of data followed by 3 bytes of metadata and 13 bytes of BCH error correction code) which will be referred as sectors later on. Bootrom checks the presence of magic string 0x55 0xAA 0xF0 0x0F and additionally checks if 3rd byte in metadata equals 0x69 at the beginning of every 64th page (it moves up to 50 times). If checks are passed, rom assumes the following data structure has been found:
ID block 0
offset |
length |
content |
comment |
0 |
4 |
signature |
0x55 0xAA 0xF0 0x0F |
4 |
2 |
firmware year |
|
6 |
2 |
firmware date |
|
8 |
2 |
firmware ver1 |
|
10 |
2 |
firmware ver2 |
|
12 |
2 |
1st stage offset |
expressed in sectors, 0x04 usually |
14 |
2 |
unknown |
|
16 |
20 |
reserved |
|
36 |
2 |
firmware vendor |
|
38 |
470 |
reserved |
|
508 |
2 |
boot code size |
in bytes (dram init + nand bootloader) 64kB max |
510 |
2 |
reserved |
|
ID block 1
offset |
length |
content |
comment |
0 |
2 |
bootloader blocks |
Number of blocks reserved for nand bootloader (and its copies!) |
2 |
2 |
system disk size |
in MB |
4 |
500 |
reserved |
504 |
2 |
1st ID block offset |
in sectors |
506 |
2 |
2nd ID block offset |
in sectors |
508 |
2 |
3rd ID block offset |
in sectors |
510 |
2 |
4th ID block offset |
in sectors |
ID block 0 is encrypted with RC4 encoding, ID block 1 is plain binary. ID block 2 and 3 seem to be unused (reserved for future extensions???). Values are stored in little-endian format.
ROM loader assumes that single nand page contains 4 sectors so in case of nand flash chip with 4096 nand page size bottom half of the page is unused. Bear this in mind when inspecting raw nand dumps!!!
First sector indicated by the 1st stage offset should contain dram initialization binary and is marked with magic 0x52 0x4B 0x32 0x37 ('RK27') at offset 0x1F8 (sector relative). The bootrom copies this initialization image to the buffer at 0x18200E00, executes dram init routine and returns. The rest of the bootloader image is loaded at 0x60000000 (begining of the DRAM) up to the indicated size in the header. Finally bootrom passes control to the loaded bootloader or in case something went wrong with reading bootloader from flash, bootrom falls back to usb DFU mode described in following section. Both dram init image and nand bootloader are stored in RC4 encoded form (separately).
The flash bootloader relocates itself at 0x60700000 and loads BASE.RKW file from the system partition and passes control to the actual firmware. An entrypoint for image stored in BASE.RKW is at 0x60000000. The bootloader supports also USB in MSC mode for both user and system partiton as well as supports custom scsi commands.
There seem to be a few copies of the bootloader in consecutive flash blocks at the beginning of the nand (5 on the device I own).
RK27BOOT.BIN
This is recovery/upgrade file shipped either separately or contained within .img or 'big' .rkw file. It contains header and 4 binary blobs packed together. You can unpack and decode binary images using rk27boottool. The 1st image is dram init code, 2nd is usb upload handler, 3rd is nand bootloader and 4th is handler of the 'other' upgrade mode. The content of 1st and 3rd image matches what has been identified on the nand flash, 2nd and 4th are wild guess. Based on USB sniffing of update procedure on Hifimans upload sequence for 'other' upgrade mode is 1,2,4.
DFU mode
rk27xx has some sort of DFU mode. The handler for this mode sits in 8kB
SoC bootrom at address 0xAF0. The device in DFU mode has VID:PID = 0x71b:0x3201. Rockchip provides dedicated drivers for this mode as well as repair tool (
RK27DM.exe). This tool loads some binary blobs to the device from
Rock27Boot.bin file by means of usb control transfer. You can inspect the content of this binary blobs with help of rkboottool I have written. First image is sdram init and is running from iram. Second image is usb transfer handler for bulk transfers and is running from sdram (load base 0x60000000). The second stage is quite interesting - It has simple encrypt/decrypt based on XOR routine to decode blobs as well as some crc checking. Further transfers are handled by this routines and are of bulk type.
Clock settings
Datasheet floating around is misleading in section concerning clocks setup. SCU_DIVCON1 register bit2 selects the way ARMclk and HCLK are derived. If this bit is cleared ARMclk equals PLL out and HCLK equals PLL out/2. If this bit is set both ARMclk and HCLK are equal PLL out/2. Measurements show that SDRAM performance is related to HCLK (but not quite directly). Synchronous ARM:HCLK gives worst ram throughput than async setting with the same AHB bus frequency. LCD framerate is also related to HCLK.
test_mem results
ARMclk/HCLK/PCLK |
read |
write |
memset |
memcpy |
200/100/50 |
97.0 MB/s |
50.7 MB/s |
50.7 MB/s |
49.2 MB/s |
100/100/50 |
80.0 MB/s |
50.7 MB/s |
50.7 MB/s |
43.8 MB/s |
264/132/66 (overclocked) |
133.3 MB/s |
68.0 MB/s |
68.0 MB/s |
66.6 MB/s |
132/132/66 |
106.6 MB/s |
66.6 MB/s |
66.6 MB/s |
57.1 MB/s |
132/66/66 |
66.6 MB/s |
34.0 MB/s |
33.3 MB/s |
33.3 MB/s |
132/66/33 |
66.6 MB/s |
34.0 MB/s |
33.3 MB/s |
33.3 MB/s |
NAND controller
ECC
Nand controller uses BCH codes for error correction. It uses m=13, t=8, gen_poly=0x25af. Bits order is reversed in each input byte. 13 output bytes are reversed again and then xor'ed with masking polynomial 0x4e, 0x8c, 0x9d, 0x52, 0x2d, 0x6c, 0x7c, 0xcb, 0xc3, 0x12, 0x14, 0x19, 0x37 so empty nand page gives all 0xff.
FTL
There seems to be a few incompatible ftl versions distributed with SDK. Anything below refers to FTL found in my rk27generic dap (FTLv2 ?). Hifimans use DIFFERENT newer version (FTLv3 ?).
This is the place where I will document my findings about Flash Transition Layer (FTL for short) used in rk27xx players. SDK ships FTL component as static lib with limited to the public functions and data struct definitions .h files.
The smallest data chunk, as described earlier, is sector. This is 512 bytes of data + 3 bytes of metadata + 13 bytes of BCH checksum. The whole flash area is logically divided into equal sized Zones. According to reserved memory there can't be more then 64 Zones. Each Zone contains 256 (0x100) logical blocks (lBLK). Each logical block contains 256 (0x100) physical pages (pPGE) which seems to come from the number of pPGE in pBLK multiplied by the number of planes. The very first Zone is special. It contains reserved blocks at the very beginning (ID blocks + nand bootloader). Moreover there is bitmap of the lBLKs offsets within Zone to ???, there are also 20 lBLKs reserved for some other purposes (exchange blocks?). At the end of each Zone there are 2 special blocks containing valid blocks bitmap for this Zone.
The data below comes from the simulations of nand access when executing nand bootloader in controlled environment. All numbers are for ideal nand chip (i.e without ANY badblocks which is unrealistic on real piece of silicon). Simulated nand was Micron
MT29F32G08 with pPGE of 4096 + 218 bytes, 128 pPGE per pBLK and 8192 pBLKs.
The first mentioned table is stored in first Zone, lBLK 0xf6 and contains 0xdf, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7 (16 bytes) padded with 0 to the total size of 64 bytes (which coresponds to max 64 possible Zones). Valid blocks bitmap is stored in two copies in lBLKs 0xfe and 0xff of each Zone. It is 0x03, 0x04, ..., 0xff, 0x00, 0x00, 0x02 for the first Zone and 0x00, 0x01, ..., 0xff for others. The sector containing this bitmaps is marked with 0x52 3rd metadata byte. The presence of the sequence 0x00, 0x02 is checked when scanning valid bitmap for the sys zone (offset 0xfe and 0xff respectively in sector with bitmap data).
Copyright © by the contributing authors.