CHDK porting to SD300 camera


(or how to use the hardware the way it was meant to be)

This camera seems to be slightly different than the other platforms the CHDK has been ported to. The most similar is SD500, but some of the internal firmware functions are non-existant on the SD300. Others are just similar.

Manual effort is being made in finding the equivalents for this platform.

In particular, the keyboard routines seem to be different than A620 or SD500 (the ones I've compared it to so far)


Changes made so far

boot.c

Most of the initialization routines and addresses have been found!

 long *canon_data_src = (void*)0xFFAD7700;
// This is address of "Startofdata" string on the firmware
long *canon_data_dst = (void*)0x1900;
// This is where the boot data is copied during firmware update
long canon_data_len = 0xEB60;
// This is length of data from "Startofdata" to end of firmware dump
long *canon_bss_start = (void*)0x10460;
// = 0xEB60 + 0x1900, just after data
long canon_bss_len = 0x72DC0 - 0x10460;
// The original address of h_usrKernelInit - bss start
 void h_usrInit()
{
asm volatile (
"STR LR, [SP,#-4]!\n"
"BL sub_FF811B20\n"
"MOV R0, #2\n"
"MOV R1, R0\n"
"BL sub_FFABDC68\n"
"BL sub_FFAAA238\n"
"BL sub_FF81125C\n"
"BL sub_FF811838\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_FFABE168\n"
"BL sub_FFAD0C28\n"
"LDR R3, =0xF894\n"
"LDR R2, =0x704A0\n"
"LDR R1, [R3]\n"
"LDR R0, =0x7278C\n"
"MOV R3, #0x100\n"
"BL sub_FFACC464\n"
"LDR R3, =0xF854\n"
"LDR R0, =0xFC74\n"
"LDR R1, [R3]\n"
"BL sub_FFACC464\n"
"LDR R3, =0xF910\n"
"LDR R0, =0x72760\n"
"LDR R1, [R3]\n"
"BL sub_FFACC464\n"
"BL sub_FFAD57A8\n"
"BL sub_FF811348\n"
"MOV R4, #0\n"
"MOV R3, R0\n"
"MOV R12, #0x800\n"
"LDR R0, =h_usrRoot\n"
"MOV R1, #0x4000\n"
"LDR R2, =0xA2DC0\n" // 0x72DC0 + 0x30000
"STR R12, [SP]\n"
"STR R4, [SP,#4]\n"
"BL sub_FFACDE68\n"
"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_FF811BA0\n"
"MOV R1, R4\n"
"MOV R0, R5\n"
"BL sub_FFAC4450\n" // memInit
"MOV R1, R4\n"
"MOV R0, R5\n"
"BL sub_FFAC4EC8\n" // mmPartLibInit
// "BL sub_FF811928\n" // Initialize_MMU does not work and is not on SD500...
"BL sub_FF811814\n"
"MOV R0, #0x32\n"
"BL sub_FFAC6938\n" // selectInit
"BL sub_FF811BE4\n"
"BL sub_FF811BC4\n"
"BL sub_FF811C10\n"
"BL sub_FFAC61F8\n" //selTaskDeleteHookAdd
"BL sub_FF811B94\n"
);
_taskCreateHookAdd(createHook);
_taskDeleteHookAdd(deleteHook);

drv_self_hide();

asm volatile (
"LDMFD SP!, {R4,R5,LR}\n"
"B sub_FF811408\n"
);
}
Edit summary:





This is a minor editWatch this page





lib.c

 void *hook_raw_fptr()
{
return (void*)0x2F490; // NOT FOUND YET!!! 0x2F490 is from SD500...
}

void *hook_raw_ret_addr()
{
return (void*)0xFF8D0824;
}

char *hook_raw_image_addr()
{
return (char*)0x10A795A8; // extracted from sub_FF8B6C4C
}

long hook_raw_size()
{
return 0x50D750; // extracted from sub_FF8B6C4C
}

void *vid_get_viewport_live_fb()
{
return (void*)0x0;
}

void *vid_get_bitmap_fb()
{
return (void*)0x108CEB20;
}

void *vid_get_viewport_fb()
{
return (void*)0x10A6A760;
//return (void*)0x10B02560;
//return (void*)0x109CBD20;
}

void *vid_get_viewport_fb_d()
{
//return (void*)0x10A6A760;
//return (void*)0x10B02560;
return (void*)0x109CBD20;
}

long vid_get_bitmap_width()
{
return 360;
}

long vid_get_bitmap_height()
{
return 240;
}

long vid_get_viewport_height()
{
return ((mode_get()&MODE_MASK) == MODE_PLAY)?240:230;
}
Edit summary:





This is a minor editWatch this page





 

 stubs_entry_2.S

These are functions equivalent to what was defined for SD500 but on the SD300 firmware dump.

#include "stubs_asm.h"

//Manually entered
NHSTUB(AllocateMemory, 0xFF81F56C)
NHSTUB(Close, 0xFF871688)
NHSTUB(CreatePhysicalVram, 0xFF927B0C)
NHSTUB(DisplayImagePhysicalScreen, 0xFF927098)
NHSTUB(ExecuteEventProcedure, 0xFF81756C)
NHSTUB(FreeMemory, 0xFF81F578)
NHSTUB(FreeUncacheableMemory, 0xFF8152BC)
NHSTUB(GetPropertyCase, 0xFF82CB54)
NHSTUB(Mount_FileSystem, 0xFF8702E4)
NHSTUB(Open, 0xFF87167C)
NHSTUB(Read, 0xFF8716E8)
NHSTUB(Remove, 0xFF871694)
NHSTUB(SetPropertyCase, 0xFF82CAD0)
NHSTUB(VbattGet, 0xFFA5BCC4)
NHSTUB(Write, 0xFF8716F4)
NHSTUB(GetCurrentMachineTime, 0xFF81FEFC)
NHSTUB(SetTimerWhen, 0xFF815828)
NHSTUB(free, 0xFFAC5900)

//Keyboard stuff - Check it, not very similar to SD500
//NHSTUB(kbd_p1_f_cont, 0xFF830AB4)
//NHSTUB(kbd_p1_f_cont, 0xFF830990)
//NHSTUB(platformsub_kbd_fetch_data, 0xFF830E90)
//NHSTUB(kbd_p1_1, 0xFF830A80)
//NHSTUB(kbd_p1_2, 0xFF830AE8)
//NHSTUB(kbd_p1_3, 0xFF829848)
//NHSTUB(PhySw_testgpio, 0xFF82FA8C)

// Hmmm... look similar but not exactly the same
NHSTUB(GetParameterData, 0xFF95A55C)
NHSTUB(SetParameterData, 0xFF95A49C)
//NHSTUB(GetFocusLensSubjectDistance, 0xFFA5FA64)

// Add redefinitions of auto-found functions present on SD500....
NHSTUB(GetZoomLensCurrentPoint, 0xFFA52174)
NHSTUB(GetCurrentAvValue, 0xFFA69300)
NHSTUB(GetZoomLensCurrentPosition, 0xFFA52180)
NHSTUB(GetFocusLensSubjectDistance, 0xFFA49E8C)
NHSTUB(MoveFocusLensToDistance, 0xFFA6B0EC)


//null stub
NHSTUB(SetZoomActuatorSpeedPercent, 0xFFAAAED0)
NHSTUB(kbd_p1_f, 0xFFAAAED0)
NHSTUB(kbd_p2_f, 0xFFAAAED0)
NHSTUB(kbd_read_keys_r2, 0xFFAAAED0)
NHSTUB(IsStrobeChargeCompleted, 0xFFAAAED0)
NHSTUB(UniqueLedOn, 0xFFAAAED0)
NHSTUB(UniqueLedOff, 0xFFAAAED0)

 

 The HackingHood