|
The Rockbox Sansa v2 Firmware
Sansa v2 Porting Status
It is yet impossible to generate valid firmware files because we are missing the signification of the FirmwareHeader structure byte at 0x14.
No firmware recovery procedure has been found on any v2 device yet, so it is very risky and unpractical to try experimental firmwares yet.
As raised on the forums, it could probably be possible to create a development firmware replacing the Firmware block (block 1) in a first pass, thus allowing development without completely understanding library and resource blocks. To be confirmed.
Overview
All v2 devices use the same SoC as their main processing unit: the AS3525.
The v2 firmware file is divided in a bunch of blocks. The M200v2 v4.1.08A firmware has been used for analysis, but it seems that the file format is (almost) the same for other models.
In the M200 firmware, there seem to be 32 blocks. The following table shows the firmware file blocks details for that specific firmware version:
| Block Index |
Address |
Description |
| 0 |
0x000000 |
Firmware header |
| 1 |
0x000400 |
Boot code of the firmware |
| 2 to 18 |
0x400 + (Index * Block Multiplier) |
Library blocks |
| 19 |
0x21AC00 |
Empty library block (filled with 0xFF) |
| 20 to 26 |
Unregular, read below |
Resource blocks |
| 27 |
0x4D5400 |
Empty resource block (filled with DEADBEEF) |
| 28 |
0x4D5600 |
Unknown data block |
| 29 |
0x4D5800 |
Unknown data block 2 (only contains 0xDF0 at 0x4D5800) |
| 30 |
0x4D5A00 |
Unicode certificate data |
| 31 |
0x4D6800 |
Empty ending block (filled with DEADBEEF) |
Blocks Description
This section describes the actual firmware file blocks.
Every block has fixed length, but the effective code or data it contains can be smaller than this. There are 2 different padding types used in the firmware file: 0xFF paddings and 0xDEADBEEF paddings. Every byte following the effective block length is padded as 0xFF up to a 0x200 size boundary. Starting from that boundary up to the complete block size, 0xDEADBEEF padding is used.
Firmware Header (Block 0)
The firmware header is present at the very beginning of the firmware file. There are only 2 structures in this header, the first one being at 0x00000000, and the second one at 0x00000200. The second one is a mirror on the first one with a single exception, the FWHeaderIndex field is 1 while it was 0 in the first copy. The FirmwareHeader structure is as follow:
| Structure Offset |
Size |
Name |
Value |
Description |
| 0x00 |
4 |
FirmwareHeaderIndex |
0 for the first copy, 1 for the second |
FirmwareHeader structure index |
| 0x04 |
4 |
FirmwareChecksum |
Sum of all dwords present in block 1 effective section |
Firmware checksum |
| 0x08 |
4 |
CodeBlockSizeMultiplier |
0xE4, 0xE8, 0xEA, 0xEC or 0xED |
Number that, multiplied by 0x200, gives the size of the firmware and library blocks |
| 0x0C |
4 |
FirmwareSize |
Effective size of the firmware block |
Effective size of the firmware block |
| 0x10 |
4 |
Unknown1 |
3 |
Still unknown |
| 0x14 |
1 |
Unknown2 |
Variable |
Still unknown |
| 0x15 |
1 |
ModelId |
0x22: Clip, 0x23: C200, 0x24: E200, 0x25: M200 |
Sansa model identifier |
| 0x16 |
2 |
Zero |
0 |
Unknown, but seems to always be 0 |
| 0x18 |
4 |
FourthyHex |
0x40 |
Unknown, but seems to always be 0x40 |
| 0x1C |
4 |
One |
1 |
Unknown, but seems to always be 1 |
| 0x3C |
4 |
FiveThousandHex |
0x5000 |
Unknown, but present in the E200 firmwares only. Seems to always be 0x5000 |
Every byte not included in the above structure is 0xFF.
Firmware (Block 1)
The firmware block is the block that is loaded at address 0x00000000 in ROM/FLASH/whatever non-volatile memory in the device. The actual code hasn't been thoroughly analyzed, but we can deduce that it contains all the code needed for the device operation, except for specific libraries contained in library blocks.
It seems that the Firmware block actually contains the usual ARM vector table right off at the block's beginning (0x400 offset from beginning of firmware file). In the M200 firmware, only the reset, IRQ and FIQ seems to be handled though. The reserved vector is simply a NOP, while all the (four) others are simply infinite loops, so if they ever happen, the device is frozen. The following table shows the vector table of the specific analyzed firmware file:
| Address |
Function |
Handler summary |
| 0x400 |
Reset |
Main code at 0x4B8 |
| 0x404 |
Undefined instruction |
Infinite loop |
| 0x408 |
Software Interrupt |
Infinite loop |
| 0x40C |
Prefetch Abort |
Infinite loop |
| 0x410 |
Data Abort |
Infinite loop |
| 0x414 |
Reserved |
NOP, effectively calling the IRQ handler |
| 0x418 |
Interrupt Request |
Interrupt handler at 0x8468 |
| 0x41C |
Fast Interrupt Request |
Interrupt handler at 0x8468 |
In short, this is a "standard" image file for a processor to execute.
Libraries (Block 2 to 18)
The following table describes the library blocks header (offsets are relative to each block base address):
| Offset |
Value(s) |
Description |
| 0x00 |
LibraryName |
Offset to the library name |
| 0x04 |
LibraryBaseAddress |
Base address of the library |
| 0x08 |
LibraryEndAddress |
Seems to be the library end address, but seems to include extra space(?) |
| 0x0C |
LibraryBlockSize |
Size of effective data in this block |
| 0x10 |
Unknown1 |
Still unknown. Needed space for variables? |
| 0x14 |
ExportCount |
Number of publicly exported functions |
| 0x18 |
Exports |
An array of ExportCount addresses which points to library functions |
The 17 library blocks from the M200 firmware are tagged with the following "library names":
| Block Index |
Library Name |
| 2 |
usb_functio |
| 3 |
mp3_decoder |
| 4 |
otg_functio |
| 5 |
wav_codec |
| 6 |
acp_decoder |
| 7 |
aud_decoder |
| 8 |
drm10_nonpk |
| 9 |
drm10_pkcpt |
| 10 |
drm10__Init |
| 11 |
wma_decoder |
| 12 |
wma_decInit |
| 13 |
wma_decPlay |
| 14 |
drm10_InitT |
| 15 |
drm10_host_ |
| 16 |
wmaPDDRMini |
| 17 |
wmaPDDRMper |
| 18 |
sd_reload__ |
Resources (Block 20 to 26)
These blocks are still mostly misunderstood, but they seems to contain various resources (localized strings, etc.). Resource blocks size is understood to be the next 0x200 bytes boundary after the block effective size. For example, a resource block with an effective size of 0x1234 would end 0x1400 bytes after the block beginning.
The resource blocks have the following header:
| Offset |
Value(s) |
Description |
| 0x00 |
ResourceBlockSize |
Size of effective data in this block |
| 0x04 |
ResourceId |
The more plausible signification is a resource ID number |
| 0x08 |
"HEADER" |
The "HEADER" ascii string |
Whole-file checksum
In addition to the checksums in the Firmware Header, the last four bytes of the firmware file contains a whole-file checksum.
This is simply calculated as a 32-bit sum of all the 32-bit words in the firmware file, excluding the last four bytes.
References and Links
|
|
Copyright © 1999-2008 by the contributing authors.
|
|