Here's what happens when the camera loads diskboot.bin:- The content of diskboot.bin is unscrambled and is copied to MEMBASEADDR (that's 0x1900 on DIGIC II...5).- Cam is restarted, the bootloader jumps to the loaded code at 0x1900.- The diskboot file starts with code found in loader/- The CHDK loader copies the CHDK core to its final location. That is usually the original starting address of the camera's malloc heap. The Canon heap is then adjusted in the boot process so Canon code doesn't overwrite the CHDK core.- A compatibility check is new in CHDK 1.5 (that's the check_compat call you quoted).- When the CHDK core is relocated, the CHDK loader starts executing it (platform/camera/main.c).- After this, a modified copy of Canon boot code is executed (platform/camera/sub/.../boot.c), to start the camera normally, with CHDK running alongside the firmware.diskboot.bin files are scrambled, the scrambling method is known as "dancing bits".
The content of diskboot.bin is unscrambled and is copied to MEMBASEADDR (that's 0x1900 on DIGIC II...5).
Cam is restarted, the bootloader jumps to the loaded code at 0x1900
The diskboot file starts with code found in loader/
.section .entry LDR SP, =MEMBASEADDR BL check_compat// ordinary startup... MOV SP, #0x1900 MOV R11, #0 B my_restart
.section .entry LDR SP, =MEMBASEADDR BL check_compat
MOV SP, #0x1900 MOV R11, #0
B my_restart
#include "../generic/check_compat.c"extern long *blob_chdk_core;extern long blob_chdk_core_size;void __attribute__((noreturn)) my_restart(){ { long *dst = (long*)MEMISOSTART; const long *src = blob_chdk_core; long length = (blob_chdk_core_size + 3) >> 2; core_copy(src, dst, length);} // restart function // from sub_FF83846C via 0x12345678 asm volatile ( " MOV R0, #0x78 \n" " MCR p15, 0, R0, c1, c0 \n" " MOV R0, #0 \n" " MCR p15, 0, R0, c7, c10, 4 \n" " MCR p15, 0, R0, c7, c5 \n" " MCR p15, 0, R0, c7, c6 \n" " MOV R0, #0x80000006 \n" " MCR p15, 0, R0, c9, c1 \n" " MCR p15, 0, R0, c9, c1, 1 \n" " MRC p15, 0, R0, c1, c0 \n" " ORR R0, R0, #0x50000 \n" " MCR p15, 0, R0, c1, c0 \n" " LDR R0, =0x12345678 \n" " MOV R1, #0x80000000 \n" " STR R0, [R1, #0xFFC] \n" //" BL sub_FF896A8C \n" // nullsub //" LDR R0, =0xFF820000 \n" "MOV R0, %0\n" // new jump-vector //" LDMFD SP!, {R4,LR} \n" " BX R0 \n" : : "r"(MEMISOSTART) : "memory","r0","r1","r2","r3","r4" ); while(1);}
: : "r"(MEMISOSTART) : "memory","r0","r1","r2","r3","r4"
while(1);
diskboot.bin files are scrambled
I need some deeper file-by-file, line-by-line execution flow understanding.
1. PLATFORMID
2. MAXRAMADDR
3. MEMISOSTART
4. KEYSYS
5. MEMBASEADDR
6. ROMBASEADDR
7. NEED_ENCODED_DISKBOOT
and why some of them are missing from my stubs_entry.S:
QuoteThe content of diskboot.bin is unscrambled and is copied to MEMBASEADDR (that's 0x1900 on DIGIC II...5).What's the code performing that? Built-in program? Then how does this code is aware that "if a file named exactly 'diskboot.bin' is present on the card, it must be loaded to some memory address"? Why to MEMBASEADDR - what so special about this address - why not to the very first byte address?
Which code exactly? What function exactly in this code? How about line-by-line analysis in this function (at least generally)?
But I don't understand what these line do:Code: [Select] MOV SP, #0x1900 MOV R11, #0MOV SP, #0x1900 means that the stack top is set to 0x1900 address, but why?
I don't understand what core_copy does and why, but I suppose that after comes the camera restart code (which I probably have to substitute from ixus160 to ixus190?)
This line seems interesting:Code: [Select]: : "r"(MEMISOSTART) : "memory","r0","r1","r2","r3","r4"but I also don't understand what does it do and why.
"mov R0, %0\n" "BX R0\n"
Code: [Select]while(1);why infinite loop here? So this function is a some kind of "master thread"?
I suppose that the next step - some code (which one?) calls startup() function in platform/<camera>/main.c, which then calls boot() function from platform/<camera>/sub/<version>/boot.c (?) And what next?
Am I understanding right that the diskboot.bin utilizes 2 independent memory regions on the camera RAM:a. some memory region where diskboot.bin (ISO actually) is loaded from the card. Is MEMBASEADDR the value that points to its start?
b. some completely another memory region used as a malloc heap for (a) region (loaded ISO). Is MEMISOSTART the value that points to its start?
which probably means that we have to scramble the compiled CHDK sources in order to comply with the camera craziness?
PS I can't proceed to whatever disassembling until I have a clear understanding of the whole boot-up process in enough details.
QuotePS I can't proceed to whatever disassembling until I have a clear understanding of the whole boot-up process in enough details.I would suggest familiarizing yourself with the firmware disassembly. Understanding the Canon firmware can help you understand why CHDK does the things it does.
When the camera is turned on without the CHDK, it executes the very first bytes of the firmware and thus booting the camera.
// ordinary startup... MOV SP, #0x1900 MOV R11, #0 B my_restart
void __attribute__((noreturn)) my_restart(){ { long *dst = (long*)MEMISOSTART; const long *src = blob_chdk_core; long length = (blob_chdk_core_size + 3) >> 2; core_copy(src, dst, length);}
asm volatile (....)
"MOV R0, %0\n" // new jump-vector
When the CHDK core is relocated, the CHDK loader starts executing it (platform/camera/main.c).
Here we implement the function copy_and_restart() (outdated: actually it is my_restart() inside loader/<camera>/main.c). As arguments it takes the destination, source and size of the CHDK core. It first copies the core to the destination and then executes the slightly adapted reset code. You can typically locate this reset code in the firmware by using your reference port. Once you have found it, you must copy it (or make sure it is the same as the reference) and make sure you change the jump at the end to jump to the start of the core you just copied).Note that this last jump is to the start of the core which means it will execute the code in core/entry.S next. This code will call the startup() function in platform/<camera>/main.c, which in turn will call the adapted boot code.
.section .entry#ifndef THUMB_FW MOV R0, #2 TEQ R0, #2 LDR SP, =MEMBASEADDR MOV R11, #0#else .code 16 .syntax unified#endif B startup
Note that this last jump is to the start of the core which means it will execute the code in core/entry.S next. This code will call the startup() function in platform/<camera>/main.c, which in turn will call the adapted boot code.
Porting a camera consists of two main phases. The first phase is concerned about making the camera bootable under the control of CHDK code. When this phase is completed, the camera should be able to successfully boot a CHDK where all features are turned off. After that begins the second phase, where important constants and addresses must be determined from the firmware in order to make all features work. It is possible to activate one feature after the other, such as finding key codes to make the keyboard work or finding addresses of the framebuffers to enable graphical output.
For testing purposes you probably want to make sure that you have the standard startup() in platform/<camera>/main.c; this function basically just calls the boot() function of boot.c.
Another new attempt to collect the puzzle.First of all - I don't understand whether the camera RAM is energy-dependent or not?
Step 1. The camera (normally) starts the code execution at the zero address (?).
Then the Canon firmware does:QuoteThe content of diskboot.bin is unscrambled and is copied to MEMBASEADDR (that's 0x1900 on DIGIC II...5).
Step 2. Then the Canon firmware does:Loads the folder "CHDK" (so called "CHDK core") from the card to the blob_chdk_core address (?). It's probably somewhere near MEMBASEADDR (unclear where exactly, probably right after it).
Step 3. Then loader/<camera>/entry.S is invoked (who calls it?) and calls my_restart() in loader/<camera>/main.c:
Which means: copy the (RAM-loaded to blob_chdk_core on step 2) CHDK folder to MEMISOSTART (e.g. final CHDK folder location).
restarts the camera in such a way so that when it reboots, it starts to execute the code not from zero address but from MEMBASEADDR (?):
Code: [Select]: : "r"(MEMISOSTART) : "memory","r0","r1","r2","r3","r4"
is still unclear and why is MEMISOSTART is involved there.
When steps 1 and 2 are done, part of the original Canon firmware gets erased by the CHDK folder content copied from the card. That's why we relocate the CHDK folder loaded content (on step 2) to MEMISOSTART (in the next steps after step 2) and reload the camera. But the diskboot.bin content does not erase anything useful in the RAM (during step 1) and hence does not have to be relocated.
I checked it - there's another file named "entry.S" - but inside the core folder! Who could believe it! Oh yeah, if I wanted to make things trickier, I also would name 2 different files with the same name and extension...
QuoteNote that this last jump is to the start of the core which means it will execute the code in core/entry.S next. This code will call the startup() function in platform/<camera>/main.c, which in turn will call the adapted boot code.Interesting - how exactly does this happen? Why actually "jump is to the start of the core" executes the code in core/entry.S? This is totally unclear to me yet.
Step 6. Then platform/camera/main.c startup() calls boot() in the end. And boot() involves somehow the CHDK core.... (?)
2. About *.S-files. Why so strange file extension - "*.S"? Does it mean anything? Does Canon firmware directly read it or some user code does so? Why do some *.S-files contain Assembler code while others contain the C code? Wouldn't it be better to set some 2 different file extensions to different content?
I currently found the code that reads and writes some *.S-files with the C-content. But where is the code writing-reading the *.S-files with the Assembler-content?
3. Is the camera really rebooted or it's just some special memory-reset - while keeping the power on (and thus preserving in the energy-dependent memory our previously loaded code)?
.globl blob_chdk_core, blob_chdk_core_size .section .blob_chdk_coreblob_chdk_core_start: .incbin CORE_FILEblob_chdk_core_end: .textblob_chdk_core_size: .long blob_chdk_core_end - blob_chdk_core_startblob_chdk_core: .long blob_chdk_core_start
.section .blob_chdk_core
.globl blob_chdk_core, blob_chdk_core_size
When the Canon firmware is done loading and decoding DISKBOOT.BIN, it jumps to the address where it just loaded. This is the loader entry.S
.......# Define empty recipes for source files (including the makefiles)# to prevent make from trying implicit rules to create them. Speeds up build process../makefile_loader.inc: ;entry.S: ;
I was learning Assembler a long time ago - and surely have trouble understanding some things - especially when it comes to ARM specifics.
This is probably the main question I don't understand. Why? Why when the Canon firmware is done loading and decoding DISKBOOT.BIN, it jumps to loader/<camera>/entry.S ?
Because loader/makefile_loader.inc contains its label at the very end?Code: [Select].......# Define empty recipes for source files (including the makefiles)# to prevent make from trying implicit rules to create them. Speeds up build process../makefile_loader.inc: ;entry.S: ;
I have a hypothesis: maybe DISKBOOT.BIN is an executable file, and Canon firmware executes it after loading-decoding?
CHDK is built in such a way that the start of the file contains the code from entry.S
.FORCE: ;entry.o: $(core)/entry.S .FORCE @echo $< \-\> $@ $(CC) $(CFLAGS) -nostdinc -c -o $@ $<
You can just copy the tree and adjust the things that are actually platform specific, which is mostly the .c and .s files and makefile.inc files in the platform directory.
The only thing remains unclear to me by that time:Code: [Select]CHDK is built in such a way that the start of the file contains the code from entry.SCan you please provide more details on it? How exactly does it happen? I mean how exactly (in the chdk code) does it happen that loader/<camera>/entry.S eventually gets compiled into the very beginning of DISKBOOT.BIN?
Impossible. How do I know what files exactly to correct and how, if I don't understand the general boot-up workflow?
Started by akira « 1 2 ... 12 13 » DryOS Development
Started by adong « 1 2 ... 49 50 » DryOS Development
Started by makomk « 1 2 » DryOS Development
Started by alvm Firmware Dumping