Rockbox on the Creative Zen Vision:M
About
Watch the
ZVM Port Thread and
FS#8686
Port Status
- The LCD driver works
- The button driver works, but there hasn't been a polling-method implemented; currently it is only interrupt based
- The ATA driver works
- The I²C(Inter-Integrated Circuit) driver works
- The SPI(Serial Port Interface) driver should work, but is untested
- The UART(Universal Asynchronous Receiver/Transmitter) driver should work, but is untested
- The USB driver works partly(EP0SETUP is received!), but there's something wrong with the interrupts
- System rebooting works (3/4 of the times)
Install Method
NOTE: THIS DOESN'T MEAN ROCKBOX IS AVAILABLE FOR THE ZVM!
Currently, all the bootloader does is load the original firmware.
- Linux
- set up a Rockbox build environment and check out latest SVN (HINT: use the VMWare image)
- Compile Rockbox as a bootloader:
cd [ROCKBOXDIR]
mkdir build; cd build
../tools/configure; make
- Download the latest original firmware updater program from Creative
- Compile mkzenboot:
cd ../tools
make mkzenboot
- Execute mkzenboot (here using ZENVisionM_30GB_PCFW_L21_1_62_02.exe as example):
./mkzenboot ZENVisionM_30GB_PCFW_L21_1_62_02.exe ../build/rockbox.zvmboot nk.bin "Zen Vision:M"
(HINT: ./mkzenboot
lists all possible player names)
- Use either utils/MTP/sendfirm or an other MTP utility to upload the firmware (nk.bin):
cd ../utils/MTP
make sendfirm
./sendfirm ../../tools/nk.bin
- Windows
- Get a ZVM bootloader file (rockbox.zvmboot); currently only available through Linux compiling...
- Download the latest original firmware updater program from Creative
- Compile mkzenboot:
cd ../tools
mingw32-make mkzenboot.exe
Or download it here
- Execute mkzenboot (here using ZENVisionM_30GB_PCFW_L21_1_62_02.exe as example):
mkzenboot ZENVisionM_30GB_PCFW_L21_1_62_02.exe rockbox.zvmboot nk.bin "Zen Vision:M"
- Use either utils/MTP/sendfirm or an other MTP utility (CreativeWizard) to upload the firmware (nk.bin):
cd ../utils/MTP
mingw32-make sendfirm.exe
sendfirm ../../tools/nk.bin
Or download it here
Information about the ZVM 30GB
Pictures/scans
Internal components
Component |
Info |
30 |
60 |
ZV |
ZVW |
TI TMS320DM320 |
Dual Core ARM9/C5409 DSP System On Chip - ARM926EJ-S product specs & datasheet |
X |
X |
X |
X |
Spansion S29GL032M |
4MB (=32Mb) flash memory |
X |
X |
X |
? |
Infineon HYB 25L256160AF-7.5 (x2) |
total of 64MB RAM: product is discontinued |
X |
X |
X |
? |
Philips ISP1583BS |
USB 2.0/ATA (IDE) controller |
X |
|
X |
? |
Philips ISP1761ET |
USB 2.0(OTG/Client) / ATA (IDE) controller Linux Host and Device driver |
|
X |
|
? |
Toshiba MK3006GAL (and this) Hitachi C4k60 (pdf) |
The Hitachi appears to be a zif connector while the Toshiba is an IDE |
X |
X |
? |
? |
Samsung LTV250QV-F02 |
LCD has quite a few numbers on it: V250QVF02S6516J12, USP5280371, GA060525 AO, DA060124BC. Similar used in the Cowon D2 |
X |
X |
|
? |
Sharp LS037V7DD06 |
LCD has quite a few numbers on it: 52015893, DUNTB0022PZZ 52, 018818. |
|
|
X |
? |
SKC LPCS285385 battery |
rated at 1250mAH at 3.7v |
X |
|
? |
? |
TEA5761UK (datasheet) |
FM Radio Markings: TEA5 VCPOM θ 0.6θ5W433Y |
X |
X |
? |
? |
Microchip/Motorola PIC18LF4320 |
Microcontroller, used for dock, buttons, etc Compatible compiler Markings: -I/ML (e3)** 06061HO |
X |
X |
X |
? |
TI TLV320AIC23BZ (datasheet) |
Stereo Audio CODEC, 8-to 96-KHz, With Integrated Headphone Amplifier |
X |
X |
? |
? |
RTC |
This component hasn't been identified yet |
X |
X |
? |
? |
lLC08A |
Quadruple 2-input positive-AND gate |
X |
X |
? |
? |
LW053A |
Triple 2-channel CMOS analog multiplexers/demultiplexers (located right of onboard flash [possibly TV out]) |
X |
X |
? |
? |
TI CN211 |
24 - bit low voltage switch bus |
X |
X |
? |
? |
Linear Technology LTC3455 (datasheet) |
Dual DC/DC Converter with USB Power Manager and Li-Ion Battery Charger |
X |
X |
? |
? |
Toshiba TC200G04SPG |
Gate Array ASIC (Maybe used as CF controller?) |
|
|
X |
? |
* This was a circle with "e3" in it.
How internals are connected
DM320:
- I²C
- PIC (at 0x07)
- TLV320 (at 0x1A? unverified)
- TEA5761UK (at 0x24? unverified)
- RTC (at 0x51)
- EMIF
- HDD (at 0x50FEE000)
- Unknown (at 0x50FFC000)
- ISP1583 (at 0x60FFC000)
- SDRAM Controller
- 64MB Infineon RAM (at 0x00900000)
- FLASH Memory Interface
- 4MB Spansion flash memory (at 0x00100000)
- SPI
- LCD (slave select pin is BITSET2/CLR2 |= (1 << 5) )
- UART
- LCD doesn't seem to work if UART isn't enabled
- GIO
- GIO0 is used as an interrupt triggered by the PIC
- GIO2 is used as an interrupt triggered by the HDD
- GIO7 is used as an interrupt triggered by the ISP1583
- GIO26, GIO34 are used as the Video Encoder clock
- GIO29, GIO32, GIO36, GIO35, GIO37, GIO40 are related to the LCD
- GIO3, GIO5, GIO14 are related to the ATA controller/HDD
TLV320:
- Control
- Audio
- unknown <= TEA5761UK
- DSP mode <= C5409 DSP
PIC:
- buttons
- buttons backlight (unverified)
- (piezo) clicker (unverified)
- touchpad
- headphones detection
- dock connector
- USB connector
- power connector
- TV out connector (unverified)
- hold switch LED (unverified)
- LCD backlight (unverified)
- probably other stuff too...
Original Firmware
Firmware Info
The firmware used by Creative is
Nucleus RTOS.
They use Nucleus PLUS and the ARM925 TI v. 1.14 toolchain to compile it according to strings found in FBOOT.
This is based on MicroWindows (Nano-X), as several assert messages are found pointing to (open source) source code. (even
NeurosTechnology uses Nano-X)
Also
libpng is incorporated (and zlib of course).
Other strings of companies working on the firmware:
- Copyright MGC 2004 - Nucleus PLUS - ARM925 TI v. 1.14
- Accelerated Technology Internal Use Only - Serial Number: NP0000
- Copyright(c) Founder Corporation.2005
Modifying the firmware
Modifying the firmware is as easy as deleting a block/block data, inserting the new data, adjusting the Size attribute of the block and the CIFF block and computing the NULL checksum of the CIFF block (so
without the NULL block).
You don't have to fill the entire firmware with all the blocks, if you for example just want to replace Hdeviceinfo.xml with another one, you only have to make a CIFF, CINF, DATA and NULL block (so you do not have to include all the others).
Another way is using
CreativeWizard (Windows only and requires .NET 2.0).
Uploading a firmware
You can either compile the program located in utils/MTP/ in Rockbox SVN or you can get the
hacked version of the official firmware updater.
Firmware Boot
- The boot loader (named FBOOT in the firmware) decrypts and loads the Rescue Mode software (FRESC), all from flash memory.
- The Rescue Mode software decrypts, decompresses and loads the actual player software (CENC/TL) from a file named jukebox2.jrm on the HDD.
If the validation checks fails or switch is hold to ON/OFF, it'll load a Rescue Mode menu, which allows you to "reload" the firmware amongst other things.
- Try opening jukebox2.jrm(load it into RAM, disable MMU and I/Dcache and jump to 0x1EE0000), if it fails show error and go to Rescue Mode
- Check the internal database if file type was ©TL
if(true): decrypt and decode and execute data
else: show error and go to Rescue Mode
- Check the internal database if file type was CENC
if(true): decode and execute data
else: show error and go to Rescue Mode
- If file type is different: execute data
Note: prior to executing data, the first 4 bytes are checked if they match 'EDOC'; if check fails: show error and go to Rescue Mode.
The 'actual firmware loading' goes as follows:
- location 0x0 contains a jump to the reset vector
- the reset vector initializes the coprocessor and maps several memory addresses (including the USER DATA MAPPINGS; all of this isn't part of the Nucleus core)
The mapping consist of these steps:
- there are 2 main variables in RAM (called mappings1 and mappings2 here);
0x900000 is stored in mappings1 and (0x904000 | 0x13) in mappings2
- more info to come...
- USER_DATA (starts at 0x1C00004) is parsed as this:
- first 4 bytes are read into buffer (=length of data)
if (buffer==NULL) return;
- next 4 bytes are read into second buffer (=address of data)
- if !(buffer2 & 3) { [copy data from (end of buffer2) to *(buffer2) for (buffer) bytes]; }
else { buffer2-= 4; [copy data in pairs of 4 bytes from (end of buffer2) to *(buffer2) for (buffer) bytes]; }
- go back to step 1
- finally INC_INITIALIZE(first_available_memory); is called with first_available_memory pointing to the start of USER DATA MAPPINGS (=0x01C00000)
- INC_Initialize_State is set to INC_START_INITIALIZE and INC_INITIALIZE() initializes all basic Nucleus kernel entities
- Application_Initialize(first_available_memory); is called (this isn't part of the Nucleus core)
- INC_Initialize_State is set to INC_END_INITIALIZE and TCT_Schedule(); is called (starting the main Nucleus threading loop)
0x1EE0000
This is the FRESCUE structure parsing code, located at 0x228 in FBOOT in ZVM firmware.
It disables all caches and MMU and cleans it. Then it parses the loaded data (given by arguments R0->memory pointer and R1->size) and loads it into the corresponding memory addresses.
Several checksum checks are done (described at
jukebox2.jrm) and if one fails, code jumps to an infinite loop.
After all loading is done, code jumps to 0x0.
Below is a C code example for loading a firmware image.
#define OF_firmware_load(mem_addr, size) asm volatile ( \
"mov r1, %1
" \
"mov r0, %0
" \
"ldr pc, =0x1EE0000
" \
: \
: "r"(mem_addr), "r"(size)\
);
OF_firmware_load(ptr_to_loaded_image, size_of_loaded_image);
Upload Code To The Player
The code you want to upload should be ELF format. Scramble is included in Rockbox SVN. If you run it like this:
scramble -creative=zvm inputfile outputfile
It will take an ELF format file and output a Hjukebox2.jrm file wrapped up in a CIFF structure (while mapping the several memory locations in ELF format to EDOC format).
LCD info
The LCD is controlled via the serial interface of the TMS320 (a driver in Rockbox is present) and the built-in OSD facilities (serial is only LCD on/off).
Some uncategorized data:
raw dump of spi_send_block:
http://pastecode.com/?show=f627241eb
analyzed version:
function spi_send_block(char arg_0, char arg_1) {
IO_GIO_BITSET2 &= (1 << 0x5);
spi_send_byte(0x74);
spi_send_byte(0);
spi_send_byte(arg_0 & 0xFF);
spi_send_byte(0x25);
IO_GIO_BITCLR2 &= (1 << 0x5);
IO_GIO_BITSET2 &= (1 << 0x5);
spi_send_byte(0x76);
spi_send_byte( (arg_1 >> 8) & 0xFF);
spi_send_byte(arg_1 & 0xFF);
spi_send_byte(0x25);
IO_GIO_BITCLR2 &= (1 << 0x5);
}
LCD init function:
http://mcuelenaere.pastebin.com/f23b3226a
HDD partitioning info
The first sector consists of this structure:
struct partition_struct
{
unsigned int end;
unsigned int start;
char name[8];
};
struct hdd_struct
{
char MBLK[4];
int block_size;
long long total_disk_size;
struct partition_struct minifs;
struct partition_struct cfs;
};
A file header on the minifs partition consists of this (incomplete) structure stored at 0x144200 (= sector 0xA21):
struct minifs_file
{
char name[16];
unsigned int unknown;
unsigned int size;
unsigned int chain1;
unsigned int chain2; /* The same as above */
};
There can be maximum 128 headers (so 32*128=0x1000 bytes)
More info here:
Some interesting links:
Notes:
- The disk available in the Removable Drive option in the OF is stored as a file named VFSYS in the cfs partition. Currently it isn't possible to access it as the cfs file system hasn't been figured out.
- The minifs file system is supposedly based on BFS (not BeFS) which was called minifs in earlier days (now it is in the VSTa OS)
- There is a disk dump available (see RAR comments for more info).
Firmware Format
010 Editor Template
Description
The firmware is in little endian on ARM targets.
A firmware always starts with the ASCII string
FFIC
followed by the total size of the file minus the last (
NULL
) block and possibly some padding bytes. After this 8-byte header comes a block structure, always started with a 4-byte string header (e.g.
FNIC
,
ATAD
,
LLUN
,
CNEC
,
0TXE
or
LT©
), followed by the Size of the block. Then you have, based on the type of block, either a) a data block with size of Size or b) a 32-byte Unicode filename and the data block of (Size-32 bytes).
Overview table
Block Type |
Block Size |
Description |
Extra |
FNIC |
96 bytes |
player name (e.g. Creative Zen Vision:M) |
Unicode formatted |
ATAD |
depends on Size attribute |
|
if name starts with F->Flash, H->HDD |
LLUN |
20 bytes |
contains HMAC-SHA1 checksum of CIFF block |
|
CNEC/LT© |
depends on Size attribute |
encrypted player data(gets written to jukebox2.jrm on HDD) |
has no Description attribute |
0TXE |
depends on Size attribute |
gets written to internal device (either mcu0 or ide0) |
name attribute is 24 bytes long |
Normal files to be found in an official firmware
Block Type |
Name |
Information |
File Format |
FINC |
n.a. |
player string |
|
ATAD |
FBOOT |
flash boot loader |
fboot_decrypt.cpp |
ATAD |
FRESC |
flash rescue mode (key is 'Copyright (C) CTL. - zN0MAD iz v~p0wderful!') |
|
LT© |
n.a. |
hdd firmware file |
jukebox2.jrm |
ATAD |
Hjukebox.grs |
graphics and other UI data |
jukebox.grs |
ATAD |
Hjukebox2.jrs |
multilingual strings |
jukebox2.jrs |
ATAD |
HCreative_T.TTF |
Unicode font |
|
ATAD |
HCreative_S.TTF |
Unicode font |
|
ATAD |
Hsplash.jbm |
hdd boot loader graphics |
JBM2 |
ATAD |
Hdevicon.ico |
icon used in MTP mode |
|
ATAD |
Hdevlogo.png |
picture of 'CreAtive' |
|
ATAD |
Hdeviceinfo.xml |
MTP description |
|
ATAD |
Hjukebox.opt |
player settings (only found in EU firmware -> EU volume cap is present in it) |
|
0TXE |
Pmcu0 (mcu0 = internal used name for the PIC) |
contains the binary code for the PIC |
EXT0 |
LLUN |
n.a. |
firmware checksum |
|
CINF block
The CINF block is the identifier of the firmware i.e. it says if the firmware belongs to a Creative ZVM 30/60GB, Creative ZEN, etc..
For example: the 30GB ZVM contains the
Unicode string 'Creative Zen Vision:M' and the 60GB contains 'Creative Zen Vision:M Go!'.
NULL block
The NULL block in the current Creative ZVM's is a HMAC-SHA-1 computed checksum of the CIFF block using the key for your device.
©TL block
The ©TL block gets written to the ZVM's HDD as jukebox2.jrm
It is encrypted using Blowfish in CBC mode with the key used for your device and after that you have to decompress/decode it using the CENC algorithm (described on
DellDJPort).
EXT0 block
This contains the code uploaded to the PIC. The format is:
char header[4];
char padding[2];
unsigned char length_a;
unsigned char length_b;
total_size = (length_b + (length_a << 8) + 0xA) & 0xFFFF;
jukebox.opt file
This file contains the firmware's factory-set settings; like in the EU firmware it has VMX=0, which defines the EU volume cap. Based on firmware reverse engineering the player also accepts DBG=1 and FM=0.
Presumably the first one sets a debug flag (nothing notable happens, I've tested it myself) and the second one could disable the FM radio functionality (not tested).
jukebox2.jrm file
The format of this file is similar to the nk.bin format: it contains a main block (EDOC), 4 bytes long followed by a WORD which indicates the size of the file.
Then you have another WORD which has a currently unknown value (can be set at 0x0000 without problems).
After that you have an array of this type of struct:
typedef struct {
UINT Address;
UINT Length;
UINT Checksum;
UCHAR Data[Length];
} BLOCK;
Address is the physical address to which Data is loaded.
This array loops until the end of the CODE block.
The checksum is calculated as follows:
FSeek(0xC);
local int i = 0x239C;
local uint j = 0;
local uint temp = 0;
while(i>0){
if(i<4) break;
temp = ReadUInt(FTell()); //FTell() tells us the current stream position and ReadUInt() reads 4 bytes
j += temp + (temp>>16);
FSkip(4); //FSkip() skips x bytes in the stream (ReadUInt() doesn't move the pointer)
i -= 4;
if(i<4) break;
temp = ReadUInt(FTell());
j += temp + (temp>>16);
FSkip(4);
i -= 4;
if(i<4) break;
temp = ReadUInt(FTell());
j += temp + (temp>>16);
FSkip(4);
i -= 4;
if(i<4) break;
temp = ReadUInt(FTell());
j += temp + (temp>>16);
FSkip(4);
i-= 4;
}
j = j << 16;
Printf("%x", j);
At the end of the file you have another block (NULL) - the header is also 4 bytes long - followed by the size in WORD format (which is always 20 bytes) and then (presumed) a SHA-1-HMAC hash of the CODE block; although the key hasn't been found yet; but the device seems to ignore this block if it isn't present.
Flash files
The format used is unknown, as no reverse engineering has been done to find this.
What is presumed, is that following files are on the flash chip:
- BOOT: contains Nucleus kernel + custom software; loads RESC; can be identified by the 'CreAtive' splash screen; contains encrypted data starting at 0xB000: RSA encrypted with 128-byte public key located at 0x410; view fboot_decrypt.cpp code for more info
This is written to the beginning of flash and is executed when the device is reset
- RESC: structure is the same as jukebox2.jrm; contains Nucleus kernel + custom software; loads jukebox2.jrm; can be identified by the 'ZEN' splash screen
- TSIG
- CONF
- TOC0 (not sure)
- PFM1 (not sure)
Flash dump is available
Other Creative players' firmware information
Since these information about the firmware applies to (almost?) the whole Creative Zen line, you'll find here some info for other players (like NULL block key, CINF header, ©TL block key, ...)
Player |
CINF |
NULL key |
©TL |
Creative Zen Vision:M |
Creative Zen Vision:M |
CTL:N0MAD|PDE0.DPMP. |
1sN0TM3D az u~may th1nk*Creative Zen Vision:M |
Creative Zen Vision:M 60GB |
Creative Zen Vision:M Go! |
CTL:N0MAD|PDE0.DPMP. |
1sN0TM3D az u~may th1nk*Creative ZEN Vision:M (DVP-HD0004) |
Creative ZEN |
Creative ZEN |
CTL:Z3N07|PDE0.DPMP. |
1sN0TM3D az u~may th1nk*Creative ZEN |
Creative ZEN X-Fi |
Creative ZEN X-Fi |
CTL:Z3N07|PDE0.DPMP. |
1sN0TM3D az u~may th1nk*Creative ZEN X-Fi |
Creative ZEN Mozaic |
Creative ZEN Mozaic |
CTL:Z3N07|PDE0.DPMP. |
1sN0TM3D az u~may th1nk*Creative ZEN Mozaic |
Creative Zen Vision |
Creative Zen Vision ©TL |
CTL:N0MAD|PDE0.DPMP. |
1sN0TM3D az u~may th1nk*Creative Zen Vision |
Creative Zen Vision W |
Creative Zen Vision W |
CTL:N0MAD|PDE0.DPMP. |
1sN0TM3D az u~may th1nk*Creative ZEN Vision W |
Creative Zen Micro |
|
CTL:N0MAD|PDE0.SIGN. |
1sN0TM3D az u~may th1nk*Creative Zen Micro |
Creative Zen MicroPhoto |
|
CTL:N0MAD|PDE0.SIGN. |
1sN0TM3D az u~may th1nk*Creative Zen MicroPhoto |
Creative Zen Sleek |
|
CTL:N0MAD|PDE0.SIGN. |
1sN0TM3D az u~may th1nk*Creative Zen Sleek |
Creative Zen Sleek Photo |
|
CTL:N0MAD|PDE0.SIGN. |
1sN0TM3D az u~may th1nk*Creative Zen Sleek Photo |
Creative Zen Touch |
|
CTL:N0MAD|PDE0.SIGN. |
1sN0TM3D az u~may th1nk*Creative Zen Touch |
Creative Zen Jukebox Xtra |
|
CTL:N0MAD|PDE0.SIGN. |
1sN0TM3D az u~may th1nk*NOMAD Jukebox Zen Xtra |
Creative Zen V |
Creative ZEN V |
CTL:N0MAD|PDE0.DPFP. |
1sN0TM3D az u~may th1nk*Creative ZEN V |
Creative Zen V Plus |
Creative ZEN V Plus |
CTL:N0MAD|PDE0.DPFP. |
1sN0TM3D az u~may th1nk*Creative ZEN V Plus |
Creative Zen V Video |
Creative ZEN V (Video) |
CTL:N0MAD|PDE0.DPFP. |
1sN0TM3D az u~may th1nk*Creative ZEN V (Video) |
Tools
CreativeWizard
CreativeWizard is a .NET 2.0 application intended for analyzing and modifying Creative Zen firmwares. You can download it at
epiZENter.
For creating a firmware, following steps are required:
- 'Make firmware'
- 'Select your player'
- choose your player from the list and press OK
- 'Add block'
- select the newly added block
- change type to 'DATA'
- check 'Use file instead of data'
- type 'Hjukebox2.jrm' in 'Filename' textarea
- choose the file
- press 'Create Firmware'
- press 'Yes'
- press 'OK'
- in main window: press 'Upload Firmware'
- choose your firmware and upload it to your player
ZenUtils
ZenUtils was made by zook (Rasmus Ry) and is now available in SVN.
External Links
Wiki Links
CategoryFrontpage: Creative Zen Vision:M Port Index [New Ports]
Copyright © by the contributing authors.