The original article was copied from here.
This manual assumes that
- firmware dump
- basic ARM assembler knowledge
- decent ARM reversengineering tool
- C knowledge
- chdk building environment
are already available/known/setup correctly. Making above things to work/etc. is not part of this document.
It is recommended that you use the sources from the trunk, as they contain fewer bells and whistles, and thus there are fewer things that can go wrong.
|/bin||- results ready for usage|
|/core||- glue that makes it all work together|
|/CHDK||- Files intended for CHDK directory on the SD card|
|/doc||- some docs...|
|camera.h||- Camera-dependent settings|
|/lib||- various libraries. BASIC handling, some math and standard C functions, font, other "separate" stuff goes here|
|- initial code ran by camera. Setups various things.|
|- camera-/firmware- dependent code|
|+ generic||- generic code #included by platform code|
|/script||- BASIC scripts|
|/tools||- tools to make life easier :)|
|/buildconf.inc||- build optional components settings|
Source is build in the following order: tools, lib, platform, core, loader. The result of 'core' is main.bin. It contains injected code and code to startup camera in special way.
'loader is a, well, loader for the 'core'. It handles camera's software reset, loading 'core' to specific address and finally running it.
Files that are not included into source tree are
- /tools/sig_ref_<X>.bin (see description below)
- /platform/<NAME>/sub/<VER>/PRIMARY.BIN - fw dump for camera NAME version VER
Take a look at Makefiles, some of them must be modified.
- pakwif - utility to build FIR - fw update files
- hexdmplt - utility to dump files
- gensig.sh - Signature finder to simplify search of known functions in fw dumps. File signatures.h is generated from data from the set of
- sig_ref_#.txt and sig_ref_#.bin. Txt contains function names and virtual offsets and bin is a corresponding fw dump.
So, the goal is to add things that are missing in /loader and /platform directories. The good starting point is copying of loader and platform stuff from another camera that may be very alike to the one your are trying to port to.
makefile.inc in platform/sub dir should be edited, it contains these parameters:
|PLATFORMID=12345||- decimal ModelID so valid FIRs were built, refer to P-ID (Table).|
|MEMBASEADDR=0x1900||- address where wif or diskboot code will be loaded by camera. As code is mostly position dependent it's important to know. Used by loader.|
|RESTARTSTART=0x50000||- address of a free region. memmove() to setup core in memory and reset code lives here. Obviously it must not intersect with whats already loaded in RAM.|
MEMBASEADDR - (MEMBASEADDR+FIRSIZE) and
MEMISOSTART - (MEMISOSTART+MEMISOSIZE)
|ROMBASEADDR=0xffc00000||- base address of fw. Used by function signature finder. For A-series it is 0xFFC00000, for S-, SD-, and G- series - 0xFF810000.|
|MEMISOSTART=0xABCDE||- these will be adjusted later. Depends on particular firmware.|
Corresponding fw dump must be placed into PRIMARY.BIN in platform/sub/<VER> directory.
Edit Makefile and disable generation of Thumb code.
Optional: edit platform\generic\main.c and disable function call link capt_seq_task(), mykbd_task() and movie_record_task() as long as platform\sub is not fully modified for your platform.
Many recent cameras require the DISKBOOT.BIN to be encoded. On these cameras, you need to define NEED_ENCODED_DISKBOOT in the platformsub makefile.inc
Example memory layout while CHDK is running:
|0x00000000-0x00001000||- interrupt related stuff.|
|0x00001000-0x00001900||- kernel stack.|
|0x000ABCD0-0x000CBCD0||- 'core' lives here. <- thing we change|
|0x000CBCD0-0x00200000||- VxWorks Primary memory pool.|
|0x00200000-0x02000000||- "Extended" RAM. Various buffers, etc.|
|0x10000000-0x1fffffff||- same as 0x0-0x0fffffff but with no caching|
|0xffc00000-0xffffffff||- Firmware flash|
|stubs_min.S||- usually data pointers to make keyboard driver work. 'physw_status is where kbd state is kept. Address is inside PhySw task depending on kbd architecture.|
|stubs_entry.S||- entry points found by finsig. I.e. generated.|
|stubs_entry_2.S||- functions addresses 'fixups'. Here go functions that were mistakenly identified by finsig or completely missed.|
|stubs_auto.S||- file generated from boot.c. Entry points for original fw functions referenced by boot.c assembler inlines.|
|lib.c||- various fw-dependent stuff. Pointers, sizes, etc.|
|boot.c||- FW startup and basic hook installation code.|
Most functions are copied and have straight equivalent inside of FW at early initialization stages but ours are with minor modifications. :)
void boot() - setup .data and .bss
void h_usrInit() - Nothing interesting here. Just don't forget to fix the call to h_usrKernelInit().
void h_usrKernelInit() - fix R0 (h_usrRoot) and (IMPORTANT!) R2 (pMemPoolStart) parameters of kernelInit() call like that:
"LDR R0, =h_usrRoot\n" "MOV R1, #0x4000\n" // "LDR R2, 0xA0000\n" // old "LDR R2, =new_sa\n" // new "LDR R2, [R2]\n" // new "STR R12, [SP]\n" "STR R4, [SP,#4]\n" "BL sub_FFEC9DA8\n" kernelInit()
Now return to makefile.inc and modify MEMISOSTART so it pointed to *original* pMemPoolStart, i.e. 0xA0000 in this example.
h_usrRoot() - two modifications: add calls to taskCreateHookAdd and taskDeleteHookAdd to install hooks on task creation (further CHDK startup/initialization depends on these) and drv_self_hide() to "hide" A/DISKBOOT.BIN file. Later is required to diskboot successfully - without it camera will stuck in permanent diskboot :)
Yes, this is a generated file but it must be reviewed and every questionable entry point must be checked and fixed if needed by corresponding line in stubs_entry_2.S.
Some functions are not required by CHDK to function properly but are used to get some valuable information by hand or are left there for historical reasons.