Powershot A420
A BETA version of CHDK is available for the Powershot A420 with firmware version 1.00b from the Autobuild Server |
Reviews: Digital Cameras Review, DPR review
Firmware information[]
The trick with the ver.req file works on the A420 as well, with the following result:
Canon PowerShot A420 P-ID:310F PAL Firmware Ver GM1.00B No error Dec 6 2005 09:17:55
pressing DISP button again results in:
Canon PowerShot A420 P-ID:310F PAL Adj Ver.005.001
Technical data[]
- Digic II image processor
- VxWorks operating system
- Sensor: 4 MP, 1/3-inch CCD type
- Lens: 39-125mm equiv, F2.8-5.1, 3.2x optical zoom
- LCD Monitor: 1.8-inch TFT, ~77,000 pixels
- Optical Viewfinder
- 5-point AiAF/1-point AF (fixed to center)
- Storage: SD / MMC
- Power: 2x AA, optional AC Adapter Kit ACK800
- Dimensions: 103.3 x 51.8 x 40.2 mm , Weight: 150g (5.29 oz.)
For developers[]
LEDs[]
Firmware dumps[]
- firmware version 1.00B
Download location for firmware dumps: |
Porting[]
Stubs.s first try[]
Stubs.s was copied from A610 sub 100e and edited by firmware comparison. kbd_pwr_off and kbd_pwr_on was not found entirely. I've replaced them with a null function.
If you want to copy it to a file, it's easier from the wiki edit mode.
The functions before kbd_p1_f may need some revision.
stubs_entry.s
#include "stubs_asm.h" NSTUB(AllocateMemory, 0xffc01b20) NSTUB(AllocateUncacheableMemory, 0xffc048f4) NSTUB(Close, 0xFFC5A42C) NSTUB(CreatePhysicalVram, 0xFFD092F0) NSTUB(CreateTask, 0xffc11260) NSTUB(CreateTaskStrict, 0xffc12300) NSTUB(DisableDispatch, 0xffc11084) NSTUB(DisplayImagePhysicalScreen, 0xFFD0859C) NSTUB(EnableDispatch, 0xffc11100) NSTUB(ExecuteEventProcedure, 0xFFC0680C) NSTUB(ExitTask, 0xffc11620) NSTUB(FreeMemory, 0xffc01b38) NSTUB(FreeUncacheableMemory, 0xffc04928) NSTUB(GetCurrentAvValue, 0xFFE5BF44) NSTUB(GetCurrentTargetDistance, 0xFFE5E054) NSTUB(GetFocusLensSubjectDistance, 0xFFE52234) NSTUB(GetParameterData, 0xFFD3D590) NSTUB(GetPropertyCase, 0xFFC143EC) NSTUB(GetSystemTime, 0xFFC04B2C) NSTUB(GetZoomLensCurrentPoint, 0xFFE41344) NSTUB(GetZoomLensCurrentPosition, 0xFFE41358) NSTUB(IsStrobeChargeCompleted, 0xFFD22EF0) NSTUB(LockMainPower, 0xFFD38918) NSTUB(MakeDirectory, 0xFFC5CB08) NSTUB(Mount_FileSystem, 0xFFC596CC) NSTUB(MoveFocusLensToDistance, 0xFFE5E2F4) NSTUB(MoveZoomLensWithPoint, 0xFFE41224) NSTUB(Open, 0xFFC5A404) NSTUB(PhySw_testgpio, 0xFFC17B68) NSTUB(ProtectFile, 0xFFC55194) NSTUB(Read, 0xFFC5A4C0) NSTUB(RefreshPhysicalScreen, 0xFFD4EAE0) NSTUB(Remove, 0xFFC5A44C) NSTUB(SetParameterData, 0xFFD3D4B0) NSTUB(SetPropertyCase, 0xFFC143EC) NSTUB(SleepTask, 0xFFC11174) NSTUB(TakeSemaphore, 0xFFC10C70) NSTUB(UnlockMainPower, 0xFFD389CC) NSTUB(Unmount_FileSystem, 0xFFC59750) NSTUB(UpdateMBROnFlash, 0xFFC59938) NSTUB(VbattGet, 0xFFC1B014) NSTUB(Write, 0xFFC5A4CC) NSTUB(_log, 0xFFE9381C) NSTUB(_log10, 0xFFE8FCF4) NSTUB(_pow, 0xFFE8FE7C) NSTUB(_sqrt, 0xFFE91B1C) NSTUB(chdir, 0xFFEA00F0) NSTUB(close, 0xFFE9FA30) NSTUB(closedir, 0xFFE9CEB8) NSTUB(free, 0xFFC01B38) NSTUB(ints_disable, 0xFFC0D6E0) NSTUB(ints_enable, 0xFFC0D6EC) NSTUB(ioctl, 0xFFE9FB70) NSTUB(iosDevAdd, 0xFFEA0C50) NSTUB(iosDrvInstall, 0xFFEA0F14) NSTUB(isalpha, 0xFFE96F5C) NSTUB(isdigit, 0xFFE96F8C) NSTUB(islower, 0xFFE96FBC) NSTUB(isspace, 0xFFE97004) NSTUB(isupper, 0xFFE9701C) NSTUB(kbd_p1_f, 0xFFC16910) NSTUB(kbd_p1_f_cont, 0xFFC1691C) NSTUB(kbd_p2_f, 0xFFC16CEC) NSTUB(kbd_pwr_off, 0xFFEA8F80) //null stub //not found NSTUB(kbd_pwr_on, 0xFFEA8F80) //null stub //not found NSTUB(kbd_read_keys_r2, 0xFFC17618) NSTUB(localtime, 0xFFE9B6AC) NSTUB(lseek, 0xFFE9FB74) NSTUB(malloc, 0xFFEA2A70) NSTUB(memcmp, 0xFFE9AA8C) NSTUB(memcpy, 0xFFE9AAC8) NSTUB(memset, 0xFFE9AB40) NSTUB(mkdir, 0xFFC5A614) NSTUB(open, 0xFFEA0074) NSTUB(opendir, 0xFFE9CEEC) NSTUB(qsort, 0xFFE86FC0) NSTUB(rand, 0xFFE9A310) NSTUB(read, 0xFFE9FA90) NSTUB(readdir, 0xFFE9CE84) NSTUB(rename, 0xFFEA007C) NSTUB(rewinddir, 0xFFE9CEAC) NSTUB(srand, 0xFFE9A334) NSTUB(stat, 0xFFE9CF80) NSTUB(strcat, 0xFFE9AB60) NSTUB(strchr, 0xFFE9AB8C) NSTUB(strcmp, 0xFFE9ABB0) NSTUB(strcpy, 0xFFE9AD44) NSTUB(strlen, 0xFFE9AEA8) NSTUB(strncmp, 0xFFE9AF0C) NSTUB(strncpy, 0xFFE9AF50) NSTUB(strpbrk, 0xFFE9AF98) NSTUB(strrchr, 0xFFE9AFD4) NSTUB(strtol, 0xFFE9A728) NSTUB(taskCreateHookAdd, 0xFFEA56D0) NSTUB(taskDeleteHookAdd, 0xFFEA560C) NSTUB(taskIdListGet, 0xFFEAF698) NSTUB(taskLock, 0xFFEAFD54) NSTUB(taskName, 0xFFEAF590) NSTUB(taskResume, 0xFFEAF974) NSTUB(taskSuspend, 0xFFEAF7A0) NSTUB(taskUnlock, 0xFFEAFDFC) NSTUB(time, 0xFFE9C3F8) NSTUB(utime, 0xFFE9D014) NSTUB(vsprintf, 0xFFE9E7D8) NSTUB(write, 0xFFE9FB00)
boot.c[]
I ain't got no idea, where should i have to get the proper '+ 0x30000' value from, so i left it untouched. The others are fixed, i hope.
#include "lolevel.h" #include "platform.h" #include "core.h" /* Ours stuff */ extern void createHook (void *pNewTcb); extern void deleteHook (void *pTcb); void boot(); /* "relocated" functions */ void __attribute__((naked,noinline)) h_usrInit(); void __attribute__((naked,noinline)) h_usrKernelInit(); void __attribute__((naked,noinline)) h_usrRoot(); void boot() { long *canon_data_src = (void*)0xFFEB60C0; long *canon_data_dst = (void*)0x1900; long canon_data_len = 0xCEB0; long *canon_bss_start = (void*)0xE7B0; // canon_data_dst+canon_data_len long canon_bss_len = 0x9EF70 - 0xCEB0; long i; asm volatile ( "MRC p15, 0, R0,c1,c0\n" "ORR R0, R0, #0x1000\n" "ORR R0, R0, #4\n" "ORR R0, R0, #1\n" "MCR p15, 0, R0,c1,c0\n" :::"r0"); for(i=0;i<canon_data_len/4;i++) canon_data_dst[i]=canon_data_src[i]; for(i=0;i<canon_bss_len/4;i++) canon_bss_start[i]=0; asm volatile ( "MRC p15, 0, R0,c1,c0\n" "ORR R0, R0, #0x1000\n" "BIC R0, R0, #4\n" "ORR R0, R0, #1\n" "MCR p15, 0, R0,c1,c0\n" :::"r0"); h_usrInit(); } void h_usrInit() {//FFC0198C asm volatile ( "STR LR, [SP,#-4]!\n" "BL sub_FFC01968\n" "MOV R0, #2\n" "MOV R1, R0\n" "BL sub_FFE9C438\n"// unknown_libname_765 ; "Canon A-Series Firmware" "BL sub_FFE8DAA8\n"// excVecInit "BL sub_FFC011C4\n" "BL sub_FFC01728\n" "LDR LR, [SP],#4\n" "B h_usrKernelInit\n" ); } void h_usrKernelInit() {//FFC01744 asm volatile ( "STMFD SP!, {R4,LR}\n" "SUB SP, SP, #8\n" "BL sub_FFE9C938\n" //classLibInit "BL sub_FFEAF720\n" //taskLibInit "LDR R3, =0xD7C0\n" "LDR R2, =0x9BC00\n" "LDR R1, [R3]\n" "LDR R0, =0x9E930\n" "MOV R3, #0x100\n" "BL sub_FFEA8830\n" //qInit "LDR R3, =0xD780\n" "LDR R0, =0xDFC8\n" "LDR R1, [R3]\n" "BL sub_FFEA8830\n" //qInit "LDR R3, =0xD83C\n" "LDR R0, =0x9E904\n" "LDR R1, [R3]\n" "BL sub_FFEA8830\n" //qInit "BL sub_FFEB42A0\n" //workQInit "BL sub_FFC012B0\n" "MOV R4, #0\n" "MOV R3, R0\n" "MOV R12, #0x800\n" "LDR R0, =h_usrRoot\n" //sub_FFC01A64 "MOV R1, #0x4000\n" "LDR R2, =0xCEF70\n" //0x9EF70 + 0x30000 "STR R12, [SP]\n" "STR R4, [SP,#4]\n" "BL sub_FFEAC960\n" //kernelInit "ADD SP, SP, #8\n" "LDMFD SP!, {R4,PC}\n" ); } static long drv_struct[16]; static long dh_err() { return -1; } static void drv_self_hide() { long drvnum; drvnum = _iosDrvInstall(dh_err,dh_err,dh_err,dh_err,dh_err,dh_err,dh_err); if (drvnum >= 0) _iosDevAdd(drv_struct, "A/DISKBOOT.BIN", drvnum); } 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_FFEA15CC\n" "MOV R1, R4\n" "MOV R0, R5\n" "BL sub_FFEA2044\n" "BL sub_FFC017E8\n" "BL sub_FFC01704\n" "BL sub_FFC01A10\n" "BL sub_FFC019F4\n" "BL sub_FFC01A3C\n" "BL sub_FFC019C4\n" ); _taskCreateHookAdd(createHook); _taskDeleteHookAdd(deleteHook); drv_self_hide(); asm volatile ( "LDMFD SP!, {R4,R5,LR}\n" "B sub_FFC0136C\n" ); }