599pages on
this wiki
Add New Page
Talk0 Share

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 informationEdit

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 dataEdit

  • 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 Edit


Firmware dumps Edit

  • firmware version 1.00B

Download location for firmware dumps:
P&S firmware dumps mirror

Porting Edit

Stubs.s first try Edit

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.


#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 Edit

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"



   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"


void h_usrInit()
   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()
   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"



   asm volatile (
	"LDMFD   SP!, {R4,R5,LR}\n"
	"B       sub_FFC0136C\n"

Ad blocker interference detected!

Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Also on Fandom

Random Wiki