The issue can be reproduced with theBilalFakhouri's ROM in QEMU.
First step: what Canon code writes to this address range? (0x40452044 on the "good" firmware).
# this goes into 700D/debugmsg.gdb
# note: 0x40000000 is the uncacheable memory flag, so both addresses refer to the same physical memory location
watch *0x40452044
watch *0x452044
# run with:
./run_canon_fw.sh 700D,firmware="boot=1" -s -S & arm-none-eabi-gdb -x 700D/debugmsg.gdb
No results that way.
Second try: use our own logging framework (-d ram). The logs obtained that way would be huge, so add this into logging.c, eos_log_mem, right after the call to should_log_memory_region_verbosely:
if ((addr & 0x0FFFFFF0) != 0x00452040)
{
return;
}
./run_canon_fw.sh 700D,firmware="boot=1" -d ram |& grep -a -C 5 ram
...
[EEPROM-DMA]! [0x340000] -> [0x40450E00] (0xBB860 bytes)
[ram] at Startup2:FF139C24:FF139C24 [0x40452040] <- 0xFF : was 0x0; 8-bit
...
A-ha! This data is copied from the serial flash.
On the bad firmware:
[EEPROM-DMA]! [0x340000] -> [0x40451200] (0xBB860 bytes)
Alright, so next step would be to find out where 0x40450E00 or 0x40451200 is allocated, and how to find a pointer to it. Grep is usually good for finding needles in the haystack, so...
./run_canon_fw.sh 700D,firmware="boot=1" -d ram,io,calls,tail,sflash,debugmsg |& grep -a -C 5 -i 40450E00
...
call 0xFF13AB98(340000, 40450e00, bb6dc, 100000) at [Startup2:ff12087c:ff123344]
call 0xFF139FFC(340000, 40450e00, bb6dc, c0820404) at [Startup2:ff13abfc:ff120880]
[ Startup2:ff13a028 ] (00:01) [SF] readSerialFlashWithQuad Dest 0x40450e00 Src 0x340000 Size 767708
call 0xFF139AE8(bd000, 40450e00, bc, ffffff3e) at [Startup2:ff13a3f4:ff13ac00]
[SFDMA] at Start:FF139BE8:FF139BE8 [0xC0530060] <- 0x40450E00: Transfer memory address
[EEPROM-DMA]! [0x340000] -> [0x40450E00] (0xBB860 bytes)
All of the above addresses are good candidates to be looked up in the disassembly.
Stack trace for the call to readSerialFlashWithQuad:
./run_canon_fw.sh 700D,firmware="boot=1" -d callstack -s -S & arm-none-eabi-gdb -x 700D/debugmsg.gdb
...
(gdb) b *0xff13a028
...
Breakpoint 4, 0xff13a028 in ?? ()
(gdb) print_current_location_with_callstack
Current stack: [14bf60-14bb60] sp=14be88 at [Startup2:ff13a028:ff13ac00]
0xFF0C35B0(0, ff0c35b0, 19980218, 19980218) at [Startup2:bba0:14bf58] (pc:sp)
0xFF1232FC(14bf44, 1, 340000, 1000) at [Startup2:ff0c3634:14bf28] (pc:sp)
0xFF1206E8(450d3c, 450d64, 23b24, 0) at [Startup2:ff123340:14bf10] (pc:sp)
0xFF13AB98(340000, 40450e00, bb6dc, 100000) at [Startup2:ff12087c:14bed0] (pc:sp)
0xFF139FFC(340000, 40450e00, bb6dc, c0820404) at [Startup2:ff13abfc:14beb0] (pc:sp)
In particular, 0xFF1232FC is... PROPAD_CreateFROMPropertyHandle : FIX.
Wait, what?! All these years, we've been writing in the middle of Canon's property data structures without even knowing about it?! Guess we were lucky, as I believe the FIX settings block is probably not written back to the permanent memory at shutdown... (one small piece added to
this puzzle).
Back to our quest: who allocates memory for this? There are some calls to alloc_dma_memory around, so let's trace them with gdb:
b *0x16e8c
commands
silent
print_current_location
KRED
printf "alloc_dma_memory(0x%x)\n", $r0
log_result
KRESET
c
end
b *0xFF1232FC
commands
silent
print_current_location
KRED
printf "PROPAD_CreateFROMPropertyHandle(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", $r0, $r1, $r2, $r3, MEM($sp), MEM($sp+4), MEM($sp+8)
KRESET
c
end
(./run_canon_fw.sh 700D,firmware="boot=1" -d debugmsg -s -S & arm-none-eabi-gdb -x 700D/debugmsg.gdb) |& grep -a -C 50 -i 40450E00
...
[ Startup2:ff0c3634 ] PROPAD_CreateFROMPropertyHandle(0x14bf44, 0x1, 0x340000, 0x1000, 0x100, 0x100000, 0x1000000)
[ Startup2:ff1230a8 ] alloc_dma_memory(0x1000ff)
[ Startup2:ff1230ac ] => 0x40450dc4
...
[ Startup2:ff13a028 ] (00:01) [SF] readSerialFlashWithQuad Dest 0x40450e00 Src 0x340000 Size 767708
...
Found where it's allocated, now to figure out where the result is stored. Or, maybe better, as I prefer to avoid messing with the property data structures - refactor with the crop_rec method for overriding these registers. That would require finding the cmos_write stub for all camera models.
Reference for the above commands:
README.rst - Debugging with GDB.