dev builds
themes manual
device status forums
mailing lists
IRC bugs
dev guide

Search | Go
Wiki > Main > CreativeZVMPort

Rockbox on the Creative Zen Vision:M


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

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


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

  • 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
  • Control
    • I²C <= DM320
  • Audio
    • unknown <= TEA5761UK
    • DSP mode <= C5409 DSP
  • 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

  1. The boot loader (named FBOOT in the firmware) decrypts and loads the Rescue Mode software (FRESC), all from flash memory.
  2. 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.
    1. 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
    2. 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
    3. Check the internal database if file type was CENC
      if(true): decode and execute data
      else: show error and go to Rescue Mode
    4. 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:
  1. location 0x0 contains a jump to the reset vector
  2. 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:
    1. there are 2 main variables in RAM (called mappings1 and mappings2 here);
      0x900000 is stored in mappings1 and (0x904000 | 0x13) in mappings2
    2. more info to come...
    3. USER_DATA (starts at 0x1C00004) is parsed as this:
      1. first 4 bytes are read into buffer (=length of data)
        if (buffer==NULL) return;
      2. next 4 bytes are read into second buffer (=address of data)
      3. 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]; }
      4. go back to step 1
  3. finally INC_INITIALIZE(first_available_memory); is called with first_available_memory pointing to the start of USER DATA MAPPINGS (=0x01C00000)
  4. INC_Initialize_State is set to INC_START_INITIALIZE and INC_INITIALIZE() initializes all basic Nucleus kernel entities
  5. Application_Initialize(first_available_memory); is called (this isn't part of the Nucleus core)
  6. INC_Initialize_State is set to INC_END_INITIALIZE and TCT_Schedule(); is called (starting the main Nucleus threading loop)


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:
analyzed version:
function spi_send_block(char arg_0, char arg_1) {
    IO_GIO_BITSET2 &= (1 << 0x5);
    spi_send_byte(arg_0 & 0xFF);
    IO_GIO_BITCLR2 &= (1 << 0x5);
    IO_GIO_BITSET2 &= (1 << 0x5);
    spi_send_byte( (arg_1 >> 8) & 0xFF);
    spi_send_byte(arg_1 & 0xFF);
    IO_GIO_BITCLR2 &= (1 << 0x5);

LCD init function:

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:

  • 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


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];
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:
local int i = 0x239C;
local uint j = 0;
local uint temp = 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);
 i -= 4;
 if(i<4) break;
 temp = ReadUInt(FTell());
 j += temp + (temp>>16);
 i -= 4;
 if(i<4) break;
 temp = ReadUInt(FTell());
 j += temp + (temp>>16);
 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)



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:
  1. 'Make firmware'
  2. 'Select your player'
  3. choose your player from the list and press OK
  4. 'Add block'
  5. select the newly added block
  6. change type to 'DATA'
  7. check 'Use file instead of data'
  8. type 'Hjukebox2.jrm' in 'Filename' textarea
  9. choose the file
  10. press 'Create Firmware'
  11. press 'Yes'
  12. press 'OK'
  13. in main window: press 'Upload Firmware'
  14. choose your firmware and upload it to your player


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]

I Attachment Action Size Date Who Comment
DiskDump.rarrar DiskDump.rar manage 87.8 K 20 Apr 2008 - 11:25 MaurusCuelenaere A diskdump of a freshly formatted Creative ZVM (see RAR comments)
Pmcu0.asmasm Pmcu0.asm manage 205.9 K 23 Apr 2008 - 12:38 MaurusCuelenaere asm dump of the PIC's firmware
ZEN_X-Fi_cnv2uni.btbt manage 1.1 K 13 Aug 2008 - 12:26 MaurusCuelenaere 010 Editor cnv2uni.tbl structure template
ZVM-Blocks.btbt manage 1.4 K 21 Nov 2007 - 17:28 MaurusCuelenaere 010 Editor block structure template
ZVM-EXT0.btbt manage 0.9 K 21 Nov 2007 - 17:32 MaurusCuelenaere 010 Editor EXT0 block structure template
ZVM-Firm.btbt manage 1.1 K 17 Feb 2008 - 12:06 MaurusCuelenaere 010 Editor Jukebox2.jrm structure template
ZVM-JBM2.btbt manage 0.4 K 21 Nov 2007 - 17:29 MaurusCuelenaere 010 Editor Splash.jbm structure template
ZVM-Jukebox-grs.btbt manage 1.3 K 21 Nov 2007 - 17:30 MaurusCuelenaere 010 Editor Jukebox.grs structure template
ZVM-Jukebox2-jrs.btbt manage 1.3 K 21 Nov 2007 - 17:31 MaurusCuelenaere 010 Editor Jukebox2.jrs structure template edoc2elf.c manage 6.1 K 14 Sep 2008 - 10:44 MaurusCuelenaere Converts EDOC to ELF files
fboot_decrypt.cppcpp fboot_decrypt.cpp manage 3.4 K 17 Feb 2008 - 11:10 MaurusCuelenaere FBOOT decryption code
flash.rarrar flash.rar manage 570.0 K 18 May 2008 - 20:18 MaurusCuelenaere Flash dump of the ZVM
idc_utils.zipzip manage 9.8 K 14 Sep 2008 - 10:42 MaurusCuelenaere Zook's IDA Utility scripts
mkzenboot.exeexe mkzenboot.exe manage 95.0 K 29 Aug 2008 - 00:14 MaurusCuelenaere Windows build of mkzenboot
sendfirm.zipzip manage 42.8 K 29 Aug 2008 - 00:16 MaurusCuelenaere Windows build of sendfirm
zenldr.zipzip manage 34.0 K 27 Aug 2008 - 16:47 MaurusCuelenaere IDA FRESC/TL structure parser
r160 - 02 Apr 2021 - 20:46:06 - UnknownUser

Copyright © by the contributing authors.