IriverNavigation ---+!! Function Memory Mapping %TOC% ---++ What format is the flash? DaveHooper (stripwax) has developed and published decryption & encryption tools for this. (Binary: http://www.beermex.com/@spc/ihpfirm.exe & Source: http://www.beermex.com/@spc/ihpfirm.src.zip). See the IriverToolsGuide for info on how to use this tool. Using the iHP-140 as an example -- the decoded image from the above has a 512 byte encryption header, then a 32 byte "ESTFBINR" header with nothing in it. Following this is the content of the flash, with the entry point at 0x0 as explained in "Reset Logic" below. The flash routine inits the processor, important regs and GPIO, then copies portions of the remaining FLASH data into SDRAM and SDRAM as follows (see offset 0x00001528 for details): Copy 0xD2525-0xD82C9 to 0x10000000 (Start of SRAM)<br> Copy 0xD82C9-0xE0B35 to 0x10005DB0<br> Copy 0xE0B35-0xE1015 to 0x10010120<br> Copy 0xE1015-0xE1955 to 0x10010600<br> Copy 0xE1955-0xE2755 to 0x10011000<br> Copy 0xE2755-0xE3099 to 0x10011E00<br> Copy 0xE3099-0x19D2E9 to 0x31000000 (Start of SDRAM)<br> Copy 0x19D2E9-0x1A1901 to 0x310C9418<br> Copy 0x1A1901-0x1A23D5 to 0x310CDA30<br> Copy 0x1A23D5-0x1C4355 to 0x310CFF70<br> A few well-constructed "dd" commands, and you'll be able to construct two images: one containing the content of the SRAM image and one containing the SDRAM image. The dd would be of the form "dd if=ihp_120.bin of=sdram_img.bin bs=1 skip=$[0xE3099] seek=$[0x0] count=$[0x19D2E9-0xE3099] conv=notrunc" -- that example copies the first block of SDRAM at offset 0x3100000 into offset 0 (seek=0) of sdram_img.bin. There are bits of executable code in both -- some speed critical routines are placed in SRAM, like memcpy(). You can add strings references to the assembly code using the attached [[%ATTACHURL%/add_strings.perl_script][addstrings.pl]] command below. This will add a surprising amount of clarity to the code since there are more than a few error messages that were built into the code (but the error function itself appears to have been ifdeffed out). ---++ Function Address info Can we agree on a common firmware to analyze? I suggest the US firmware? But should it be 1.40 or 1.60? I'm just making up descriptive function names. -- PaulS StephanNielsen: I was wondering which tools and methods you use to analyze the firmware (extract addresses). Disassembler (objdump), A modded MCF5249 emulator, BDM, GDB??? Is it possible that you could inform other interested people about this on a separate WikiPage - unless of course you will rather do all the hard work yourself ;). PaulS: There's not a lot of magic going on here. I think there are other people (and pages) that are much better suited to give a tutorial on disassembly. The tools I've relied on the most are the [[IriverPort#What_format_is_the_flash__][disassembly tools]] I mentioned on the IriverPort page. I wrote a little perl code to build forward and reverse function call trees, but the results of that haven't been very useful so far. Aside from that, I spent a little time getting used to the assembly language, kept a ColdFire Programmers Reference Manual and the CF5259 User Manual by my side and curled up with some code. It didn't take long to get an intuition for loop structure and function call semantics. The important bit of code I found very early on built the Software Memory Map below, which talks about where all the peripheral interfaces are in memory. Just searching for references to the GPIO memory range (mostly in MBAR2) will get you plenty of interesting code to look at and ponder on what it's doing. Again, other people might be better at formalizing this process. Is this short bit worth a separate Wiki page? StephanNielsen: Ok, fair enough. I will make an IriverToolsGuide <nop>WikiPage then, but please forgive me for making mistakes cause inspite of your description, I am still in doubt about a few things. | Function Name | Address| Firmware Version | | Display function | SDRAM 0x31045050 | 1.40US | | draw_string(char *, int, int, int) (draws text at the bottom center) | 0x31053408 | 1.40US | | status_message(char *) | 0x31053BF4 | 1.40US | | memcpy()? Code is in SRAM for speed. | 0x10000400 | 1.40US | | ADC_read(int mux_channel) | 0x310604C0 | 1.40US | | keystroke_decode(int adc_value) | 0x310609A8 | 1.40US | | get_keystroke() | 0x3106104C | 1.40US | | debug_puts(char *) (disabled) | 0x3102CC68 | 1.40US | | debug_print(int) (disabled) | 0x3102CC70 | 1.40US | | putc(char) (serial port) | 0x3102CBE0 | 1.40US | | repaint_display() | 0x3104C51C | 1.40US | | mbus_select() | 0x3102F47C | 1.40US | | i2c_write() | 0x3102E848 | 1.40US | | flash_upgrade_file_exists() | 0x3103EF94 | 1.40US | | set_drive_state() | 0x31035DD4 | 1.40US | | get_drive_state() | 0x31035E20 | 1.40US | | wake_drive() | 0x3105577C | 1.40US | | ide_read_sector() | 0x31030318 | 1.40US | | read_file_into_memory() | 0x31033538 | 1.40US | | firmware_into_ram() | 0x3103EEC8 | 1.40US | | firmware_load_and_decode() | 0x3102284C | 1.40US | | program_new_firmware() | 0x31022A04 | 1.40US | | render_General_menu(int ent_no) | 0x31049C84 | 1.40US | | sel_General_menu() (conditionally calls fw funcs) | 0x31068A38 | 1.40US | | is_flash(char *) - compares string to "IHP_120 HEX" | 0x3103B9EC | 1.40US | | scan_dir() calls is_flash() for each dirent; stores file handle on success | 3103C3B0 | 1.40US | ---++ Software Memory Map The iRiver can map external peripherals in a flexible manner, using the Chip Select Module. There are also base address registers for many other facilities so devices like GPIO registers can float around based on the firmware in question. Here's an attempt to document the 1.40US firmware's setup (and coincidentally the 1.60 appears largely the same) for various important bits. Some of these registers are supervisory registers in the core, accessed by special MOVE instructions. Others, like the chip select regs are actually within the MBAR. | Register Name | Address Range | Description | Contents | | MBAR | 0x40000000 | Module Base Address Register 1 | System Control, Interrupt, Chip Select, Timer, SDRAM and UART regs | | MBAR2 | 0x80000000 | Module Base Address Register 2 | GPIO data and control registers | | RAMBAR0 | 0x10010000 | SRAM Base Address Register 0 | Base address for the first SRAM segment | | RAMBAR1 | 0x10000000 | SRAM Base Address Register 1 | Base address of the second SRAM segment | | VBR | 0x10000000 | Vector Base Register | Lives in SRAM | | CS0 | 0x00000000-0x001FFFFF | Chip Select 0 | ROM address -- Defaults to 0x0 at boot time as well, Control Reg = 0x00000D80 | | CS1/GPIO1 | 0xF0000000 - 0xF3FFFFFF | Chip Select 1 | Connected to the main LCD display chip, Control Reg = 0x00002140 | | CS2/IDE | 0x20000000 - 0x200FFFFF | Chip Select 2 | Setup for integrated IDE controller, Control Reg = 0x00000168 | | SDRAM | 0x31000000 - 0x310FFFFF | External SDRAM | DCR=0x8040, DACR0 = 0x31002520, DMR = 0x03FC0001 | ---++ GPIO Signals Here's a summary of how the ColdFire GPIO pins are used on the iRiver. These are mostly guesses that LinusNielsenFeltzing should be able to confirm or dispute based on his findings. The I/O/F column indicates whether the pin is a GPIO Input, GPIO Output or Function pin (assigned to the ColdFire's special-purpose function, or not used). Pointers are into the 1.40US SDRAM code. |Pin|I/O/F| Description | Code ||Pin| I/O/F | Description | Code | | 0 | F | DDATA0 | || 32 | | Unassigned | | | 1 | F | DDATA1 | || 33* | I | Hold switch *(C)* | 0x3106BDA6 | | 2 | F | DDATA2 | || 34 | O | LCD Related??? | 0x3104BF88 | | 3 | O | I2C Clock (to FM tuner) *(C)* | || 35 | O | LCD A0 *(C)*| 0x31044B62 | | 4 | F | DDATA3 | || 36 | F* | EBUIN1 + EBUOUT1 | | | 5 | O | EEPROM? | 0x31027A20 || 37 | I* | On/Play/Pause key (0=down) *(C)* | 0x31061296 | | 6 | O | Hard Drive Power *(C)* | 0x31020446 || 38 | I* | Remote On/Play/Pause key (0=down) *(C)* | 0x310612B0 | | 7 | O | ADC CS *(C)*| 0x310604C0 || 39 | I* | USB detect *(C)* | | | 8 | F | A25 | || 40 | | Unassigned | | | 9 | O | Disk LED control, set to 1 at init time *(C)*| 0x3105550E || 41 | F* | SDATAI2/SDATAO2 | | | 10 | F | BCLK | || 42 | F* | SDATAI4/MCLK2 | | | 11 | O | LCD Related? | 0x31020026 || 43 | | Unassigned | | | 12 | O | EEPROM I2C CLK *(C)*| 0x31020026 || 44 | F | LRCK2 | | | 13 | F | IDE_DIOR *(C)*| || 45 | I/O | EEPROM I2C SDA *(C)* | 0x3106A7F8 | | 14 | F | IDE_DIOW *(C)*| || 46 | O | LCD CS2??? | 0x310555FE | | 15 | F | SCLK_OUT | || 47 | | Unassigned | | | 16 | O | Remote LCD A0OUT | 0x3104BF88 || 48 | F | SCLK2 | | | 17 | F | BUFENB2 (For ATA buffers) *(C)*| || 49 | O | LCD backlight *(C)* | 0x3102001A | | 18 | O | ATAEN to ISD300 (1=USB controlled disk) *(C)* | 0x31020334 || 50 | O | Remote LCD DATAOUT pin | 0x3104BF88 | | 19 | O | Reset Line for something? | 0x3102FC0E || 51 | O | Write 0 at power off | 0x3102045C | | 20 | F | TA | || 52 | I | Remote Hold switch (1=hold) *(C)* | 0x3106C3B8 | | 21 | O | ADC Data Out *(C)*| 0x310604C0 || 53 | F | SUBR | | | 22 | O | SPI CLK *(C)*| 0x310604C0 || 54 | I | Unknown | 0x31060C1A | | 23 | O | Audio mux select (0=Playback, 1=FM tuner) *(C)* | 0x31020826 || 55 | I/O | I2C Data (to FM tuner) *(C)* | 0x31058770 | | 24 | O | ISD300 power (1=on) *(C)* | 0x3102033A || 56 | O | Unknown | 0x31020218 | | 25 | F | SDATAO1 | || 57 | F | BUFENB1 | | | 26 | F | QSPI_DOUT | || 58 | F | CS1 (LCD) *(C)*| | | 27 | F* | RXD1 + TXD1 | || 59 | F | PST0 | | | 28 | O* | Remote LCD CLKOUT *(C)*| 0x3104BF88 || 60 | F | PST1 | | | 29 | O | Reset line for I2C? | 0x3102CF9C || 61 | F | PST2 | | | 30 | I* | Unknown | 0x3106BCE6 || 62 | F | PST3 | | | 31 | I* | ADC Data In *(C)*| 0x310604C0 || 63 | F | PSTCLK | | "*" indicates that this GPIO or function is actually implemented by two pins on the physical package -- one dedicated input pin and one dedicated output. This means that this logical bit can serve two functions simultaneously. There's only one bit that decides function vs. GPIO, so the composite pin must either both be function pins or a GPI and GPO pin. "(C)" indicates that it is confirmed DaveHooper: Is the battery LED connected to GPIO or is it controller directly by the charging hardware? ---++ Hardware Address info A lot of documentation can be found in the ColdFire manuals. The below list refers to the most important address tables: [[http://www.freescale.com/files/netcomm/doc/ref_manual/COLDFIRE2UM.pdf Exception Vectors (page 98)]]
15 Sep 2004 - 23:13
Small perl script to add string references
r34 - 03 Nov 2004 - 08:39:00 -
Copyright © by the contributing authors.