CHDK Wiki
Advertisement


Firmware info

Version

The trick with the ver.req file works on the A550 as well, with the following result:

Canon PowerShot A550
P-ID:3150 PAL V
firmware ver GM1.00C
No error
Dec 4 2006 07:46:45

Memory map

Tested on A550 with blink G7 firmware dump.

Led

0xc0220080: AF beam:           (0x46 ON - 0x44 OFF) 
0xc0220084: blue print:        (0x46 ON - 0x44 OFF)
0xc0220088: viewfinder orange: (0x46 ON - 0x44 OFF)

Blinker Firmware compilation

Serial port download solution is the choice for dump firmware.
Blink G7 source code (main.c) must be modified in according with led memory map

long* led=(long*)0xc0220080;

The blink G7 firmware was compiled using cygwin in the pack 'ready-to-use' environment downloadable here.
Before compile must be edit the last row of the make.bat.

pakwif PS.FIR main 0x3150

where 0x3150 is the P-ID viewed with ver.req trick.

Firmware is dumped

I have made dump from 0xFFC00000 to 0xFFFFFFFF, and this is the result: Firmware A550 100c

Compile the CHDK

First of all download svn clien and then execute:

Using A560 source as the base code.

  • Modify folder structure: change folders names of platform\a560\sub\100a in platform\a550\sub\100c and loader\a560 in loader\a550
  • Copy the PRIMARY.BIN in platform\a550\sub\100c (dump of the camera)
  • Modify file core\rav.h:
#elif defined (CAMERA_a620) || defined (CAMERA_a710) || defined (CAMERA_a550) || defined (CAMERA_a560)...  
#define ROWPIX 3152   // for 7 MP
#define ROWS   2340   // for 7 MP
  • Add the new camera to the Makefile.Inc (root folder)
PLATFORM=a550
PLATFORMSUB=100c
  • Modify Makefile.Inc --> in platform\a550\sub\100c
#0x3150
PLATFORMID=12624
  • Modify boot.c

Start from function kernelinit found with IDA and called in h_usrKernelInit. Walk back (XREF) in IDA until function boot...

Rename the fuction call with your address:

ex. excVecInit => sub_FFCB6DB8

this (right or wrong) is the result:

void boot()
{
   long *canon_data_src = (void*)0xFFEEB4D0;
   long *canon_data_dst = (void*)0x1900;
   long canon_data_len = 0xB540;
   long *canon_bss_start = (void*)0xCE40; // just after data
   long canon_bss_len = 0x9F2B0 - 0xCE40;
   long i;
 [...]
}
void h_usrInit()
{
   asm volatile (
     "STR     LR, [SP,#-4]!\n"
     "BL      sub_FFC01968\n"
     "MOV     R0, #2\n"
     "MOV     R1, R0\n"
     "BL      sub_FFCC1CEC\n"      //unknown_libname_201
     "BL      sub_FFCB6DB8\n"      //excVecInit
     "BL      sub_FFC011C4\n"
     "BL      sub_FFC01728\n"
     "LDR     LR, [SP],#4\n"
     "B       h_usrKernelInit\n"
   );
}
void  h_usrKernelInit()
{
   asm volatile (
     "STMFD   SP!, {R4,LR}\n"
     "SUB     SP, SP, #8\n"
     "BL      sub_FFCC21EC\n"      //classLibInit
     "BL      sub_FFCD2318\n"      //taskLibInit
     "LDR     R3, =0x4E60\n"
     "LDR     R2, =0x9C4C0\n"
     "LDR     R1, [R3]\n"
     "LDR     R0, =0x9D010\n"
     "MOV     R3, #0x100\n"
     "BL      sub_FFCCDF08\n"      //qInit
     "LDR     R3, =0x4E20\n"
     "LDR     R0, =0x51C0\n"
     "LDR     R1, [R3]\n"
     "BL      sub_FFCCDF08\n"      //qInit
     "LDR     R3, =0x4EDC\n"
     "LDR     R0, =0x9CFE4\n"
     "LDR     R1, [R3]\n"
     "BL      sub_FFCCDF08\n"      //qInit
     "BL      sub_FFCD66D4\n"      //workQInit
     "BL      sub_FFC012B0\n"
     "MOV     R4, #0\n"
     "MOV     R3, R0\n"
     "MOV     R12, #0x800\n"
     "LDR     R0, =h_usrRoot\n"
     "MOV     R1, #0x4000\n"
     "LDR     R2, =0xCF2B0\n"   // 0x9F2B0 + 0x30000
     "STR     R12, [SP]\n"
     "STR     R4, [SP,#4]\n"
     "BL      sub_FFCCF558\n" //kernelInit
     "ADD     SP, SP, #8\n"
     "LDMFD   SP!, {R4,PC}\n"
   );
}
[...]
void  h_usrRoot()
{
   asm volatile (
     "STMFD   SP!, {R4,R5,LR}\n"
     "MOV     R5, R0\n"
     "MOV     R4, R1\n"
     "BL      sub_FFC019D0\n"
     "MOV     R1, R4\n"
     "MOV     R0, R5\n"
     "BL      sub_FFCC6CA4\n"      //memInit
     "MOV     R1, R4\n"
     "MOV     R0, R5\n"
     "BL      sub_FFCC771C\n"      //memPartLibInit
     //"BL      sub_FFC017E8\n"      //nullsub_1
     "BL      sub_FFC01704\n"
     "BL      sub_FFC01A0C\n"
     "BL      sub_FFC019F0\n"
     "BL      sub_FFC01A38\n"
     "BL      sub_FFC019C4\n"
   );
[...]
   asm volatile (
     "LDMFD   SP!, {R4,R5,LR}\n"
     "B       sub_FFC0136C\n"      //IsEmptyWriteCache_2
   );
}

I'm not sure this is the correct boot.c, If anyone view some error (in code or procedure), report me....thanks!

  • Finish Makefile.Inc --> in platform\a550\sub\100c
MEMBASEADDR=0x1900
RESTARTSTART=0x50000
MEMISOSTART=0x9F2B0 // find in original h_usrKernelInit()  
MEMISOSIZE=0x30000
ROMBASEADDR=0xffc00000

I know how to find the missing fuction in lib.c and stubs_entry_2.S. It's enought compare a precedent porting CHDK (firmware/source) and find with IDA text search missing fuction in my firmware dump.

  • stubs_entry_2.S
NHSTUB(Close,  0xFFE221A0)	//sync with a560
NHSTUB(Read,   0xFFE22234)	//sync with a560	 
NHSTUB(Write,  0xFFE22240)	//sync with a560 
NHSTUB(Remove, 0xFFE221C0)	//sync with a560
NHSTUB(Mount_FileSystem, 0xFFE214C4)	//sync with a560
NHSTUB(kbd_read_keys_r2, 0xFFDCB384)	//sync with a560
NHSTUB(DisplayImagePhysicalScreen, 0xFFDC0374)	//sync with a560
NHSTUB(free, 0xFFCC8154)	//sync with a560
NHSTUB(SetZoomActuatorSpeedPercent, 0xFFDCD668) //nullsub_130
#overwrite incorrect in stubs_entry.s
NHSTUB(SetPropertyCase, 0xFFC0B68C)	//sync with a560
NHSTUB(FreeMemory, 0xFFC0819C)	//sync with a560
NHSTUB(GetFocusLensSubjectDistance, 0xFFE458AC)	//sync with a560
NHSTUB(GetDrive_ClusterSize, 0xFFE2198C)	//sync with a560
NHSTUB(GetDrive_TotalClusters, 0xFFE219C8)	//sync with a560

same procedure:

  • lib.c:
void *hook_raw_fptr()
{
    return (void*)0x42990;	//sync with a630
}
void *hook_raw_ret_addr()
{
    return (void*)0x0;
}
char *hook_raw_image_addr()
{
    return (char*)0x10E6C640;	//sync with a630
}
long hook_raw_size()	//sync with a560 (on wiki page)
{
    return 0x8CAE10;
}
void *vid_get_viewport_live_fb()
{
    return (void*)0x0;
}
void *vid_get_bitmap_fb()
{
    return (void*)(0x10360000);	//sync with a540
}
void *vid_get_viewport_fb()
{
    return (void*)0x105F0000; //sync with a540
}
void *vid_get_viewport_fb_d()
{
    return (void*)(*(int*)0x3C2E0); //sync with a540
}
long vid_get_bitmap_width()
{
    return 360;
}
long vid_get_bitmap_height()
{
    return 240;
}
long vid_get_viewport_height()
{
    return 240;
}

and also the same for:

  • stubs_min.S:
DEF(physw_status, 0x44818) // sync with a560 and a630
DEF(physw_run, 0x7980)	// sync with a560 and a630	
DEF(zoom_busy, 0x776E0)	// sync with a560 and a630
DEF(focus_busy, 0x76F6C)	// sync with a630 but not sure 
DEF(playrec_mode, 0xBC3C)	// sync with a560
DEF(FlashParamsTable,0xFFEAC254) // sync with a560 and a630
DEF(canon_menu_active,0x2E18)	// sync with a560 and a630
DEF(canon_shoot_menu_active,0x2795) // not found
DEF(recreview_hold, 0x2588)	// sync with a560 and a630


pack of my modified files for a550: http://www.zshare.net/download/6508102fc9112b/


point of contact: http://chdk.setepontos.com/index.php/topic,230.0.html


NOTE: sorry for my english...I'm illiterate Italian man :)

[good] people

I own an A550, and offer my time for testing, to anyone who succeed in get the firmware... ( idleloop-at-hotmail+dot+com)
I also own a A550, and would be glad to offer testing time on it. (jarodthelinuxguy -at- gmail -dot- com)
Advertisement