DIGIC 7 development (200D/SL2, 800D/T7i, 77D, 6D2)

Started by feedrail, June 12, 2017, 07:05:50 AM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

DieHertz

So I don't need my STM32 Discovery and phototransistors anymore? :-( :-D

a1ex

Hehe... the other testers were quicker :D

Still need that hardware setup for M50. Or maybe for initial debugging, as all these recent cameras are dual-core.

Decoding LED blinks may also be possible with a camera that has automatic LCD brightness (5D3, 5D2, 7D) and already runs ML (I can look into it if needed).

deathline

Quote from: DieHertz on April 24, 2018, 10:39:33 AM
So I don't need my STM32 Discovery and phototransistors anymore? :-( :-D


Is there any working project file code?

DieHertz

I have found a 2GiB SD card, formatted it via my 6D2 (low-level format), then dd-ed 256 MB filesystem .img over it, and copied 6D2_DUMP.FIR into SD root.
Then put the SD card into camera, turned it on, screen lit up as usual, I let it sit for a minute and then turned camera off, opened SD card bay and after 10 seconds ejected it.
There are no new files on the SD card following this procedure, did I miss something?

Walter Schulz

You have to "load" FIR file using Firmware Update in Canon menu!

DieHertz



Oh indeed, I forgot this is the firmware update file format.
Thank you!

Battery taken out, can I put it back now? :)

alpha232

I'm getting all antsy for something else to test :D

Much thanks to poor a1ex for his tolerating my odd schedule.

DieHertz

LED number on 6d2 appears to be 0x5b.
Speaker/beeper is a bit weird, the second least significant bit seems to have some echo which makes it hard to distinguish whether it's 1 or 0, there seem to be 3 clicks per just two edges. It's either 0x40, 0x42, or both.
Maybe that explains why there are 3 clicks, rising edges coincide, while falling edges are spread apart as one of them is longer than the other.
https://youtu.be/MFp3pxfomGM

Result:
SD LED: 0xD208016C
Speaker 1: 0xD2080100
Speaker 2: 0xD2080108

P.S. 77D looks similar :)

a1ex


DieHertz

a1ex, here's the CPU info from 6D2.
Maybe it could be easier if it wrote output to SD card, taking these photos was far from easy :-)










I wonder what is the level8 cache it mentions

a1ex

Emulation ready 8)



Please refer to README.rst, HACKING.rst, the sticky tweet and the 80D/750D threads to get started.


./run_canon_fw.sh 77D -d debugmsg -s -S & arm-none-eabi-gdb -x 77D/debugmsg.gdb

<<<<< Musa(PU0) Boot Ver 0.21 >>>>>
BootLoader
K408 READY
K408 ICU Firmware Version 1.0.2 ( 7.3.6 )
ICU Release DateTime 2017.02.23 14:49:29
...
[SD] Name: QEMU! Size: 247(7bc00)
...
[STARTUP] ERROR WaitPU1 TimeOut
...


Next steps:
- attempt to jump to main firmware (will it work? we've got two CPUs)
- enable the boot flag (might be risky, we will reflash a small part of the ROM)
- port ML startup process (likely similar to 80D)
- run the proof of concept code from 80D thread (logging, photo capture etc)
- figure out how to print things on the screen
- start porting ML!

More about the bootflag:
- recovery branch with CONFIG_BOOT_BOOTFLAG=y
- doesn't work yet; stub autodetection routines have to be updated for Thumb (they were written for DIGIC 6)
- the risk is more about bugs or other unexpected behavior in Canon bootloader (unlikely)
- this will let you compile ML (in these early stages) and run test code on your camera.

Have fun!

P.S. just got a cool feature request - audio output to Bluetooth headphones. Not tempting enough for me to get another camera, but if any of you is willing to look into it, I'll be here to help (at least with the reverse engineering side).

deathline

Quote from: a1ex on April 30, 2018, 09:51:12 AM
P.S. just got a cool feature request - audio output to Bluetooth headphones. Not tempting enough for me to get another camera, but if any of you is willing to look into it, I'll be here to help (at least with the reverse engineering side).

Are you sure digic7 cameras have  hardware support for Bluetooth 4.0 BR/EDR? 200d canon firmware support only bluetooth low energy and there is no profile for audio headsets.But i've found a low energy supported hid profile gamepad for playing mario :D 

DieHertz

Great job Alex, I guess now is the case for us, owners of 6d2 and other DIGIC 7 cameras, to continue the effort :-)

a1ex

You still need my help to enable the boot flag, but at least you can now debug your binaries in QEMU.

Good news - we were able to jump to main firmware without any special tricks! (confirmed by both DieHertz and deathline). In reboot-dumper.c from the digic6-dumper branch, run this:


void(*firmware_start)(void) = (void*) 0xE0040001;
firmware_start();

while(1);


That means, one can already start to port the 80D boot process (minimal.c) and debug it in QEMU. Same for the DIGIC 6 boot flag enabling code (recovery branch).

DIGIC 6 cameras require a special trick to jump to main firmware (poking register 0xD20C0084 on single-core D6). This was not needed for DIGIC 7.

Feel free to play around with the virtual machine and report your findings.

DieHertz

I'm sure we'll need your help for much more than that :-)

DieHertz

I think it fails earlier, unless "irregular TotalSheets 0" is a known and insignificant error message.
6D2 seems to wait for startup config to finish, last flag `0x40000` isn't cleared for a couple of minutes

DieHertz

Is it safe to assume that most of these messages are errors?


a1ex

The TotalSheets and EstimatedSize errors are likely caused by wrong / incomplete MPU messages (these will have to be logged from a real camera); the WaitPU1 error is probably what's blocking right now. It appears to wait at a semaphore.

200D:

startupPrepareCapture -> take_semaphore(PU1Wait_sem, 2000) -> DebugMsg("WaitPU1 TimeOut") if failed.
This semaphore (PU1Wait) is created right after launching TaskMain (E00413E6).
The function that gives this semaphore is E0040220 -> E004053C, referenced at:

  call 0xE0426000(e0040221, 0, 0, 1000)                                          at [init:e00402dd:e004029d]

That's something named init1 / init_task1. It does a bunch of initialization, then calls give_semaphore(PU1Wait_send) at the end.
It also appears to initialize Omar (a small secondary core likely used to offload some image processing tasks).

So, one puzzle is to debug this init_task1 to see where it locks up / why it doesn't finish / whether it's starting at all.

BHybes

I ran the FIR file as an update on my 800D and only got this from it:


a1ex

One of the ROMs is very slow, so it takes a while. Updated the binaries to skip that step.

@ 200D/6D2/77D owners: please check whether the new dumpers are still working (same link, top of the page).

DieHertz

I'm still figuring my way through radare2, ARM console, and probably something else. Having no IDA complicates it a bit, reading raw undecorated ASM in GDB is too hardcore for now :)
Will try the new dumper tonight

a1ex

Radare2 should be the most promising one; I doubt you'll get anything useful from ARM-console on Thumb.

I find GDB useful not for step-by-step debugging (I find that too slow, and IDA crashes very often, so it doesn't help that much), but with:
- watch *0x1234 (to tell what code writes to that memory address)
- custom logging hooks (to tell when a particular sequence of code executes, and with what arguments / return values / etc)

Most of the time, I use various logging options from qemu -d (many of them are custom logging code, not found in vanilla QEMU), possibly coupled with small GDB scripts (see e.g. generic_log) and grep. The most useful ones: I/O trace with interrupts (-d debugmsg,io,int), call trace (-d calls,tail), RAM trace (-d ram, with variations, or temporary edits to source code to define filters if grep is too slow).

Back to our issue. From what I could tell, the second core (CPU1) gets stuck waiting for interrupt 0xA, early in the boot process; see the EOS M5 notes about GIC.


; 77D
ROM:E0007752  BL      gicc_setup   ; writes to 0xC1000100 and 104
ROM:E0007756  MOV     R0, #0xA
ROM:E000775E  BL      wait_some_interrupt   ; calls WFI in a loop until it gets the expected interrupt


I believe these are meant to generate a software interrupt for CPU1 (77D):

[CPU0] [GICD]   at Startup:E0152F04:E0092855 [0xC1001F00] <- 0x2000A   : ???
[CPU0] [GICD]    at RscMgr:E0152F04:E0092855 [0xC1001F00] <- 0x2000A   : ???
[CPU0] [GICD]    at RscMgr:E0152F04:000350BF [0xC1001F00] <- 0x2000C   : ???


See arm_gic_architecture_specification.pdf, 4.3.15 Software Generated Interrupt Register GICD_SGIR: lowest hex digit is the interrupt ID, and the 0x2 is CPUTargetList (second CPU).

We've got some generic GIC emulation code in QEMU (intc/arm_gic.c); would be great if that can be reused.

t3r4n

Quote from: DieHertz on May 04, 2018, 03:17:21 PM
I'm still figuring my way through radare2,

well maybe I've got something
try adapting the following to your specific camera layout

# Show comments at right of disassembly if they fit in screen
e asm.cmtright=true

# Shows pseudocode in disassembly. Eg mov eax, str.ok = > eax = str.ok
e asm.pseudo = true
# (Show ESIL instead of mnemonic)
# e asm.esil = true

# Selected: asm.describe (Show opcode description)
e asm.describe = false

#asm.emu (Run ESIL emulation analysis on disasm)
e asm.emu = true

# Solarized theme
eco solarized

# Use UTF-8 to show cool arrows
e scr.utf8 = true
e scr.utf8.curvy=true

# set arch and cpu type
e io.va = true
e asm.arch = arm
e asm.bits = 16
e asm.cpu=cortex
# anal.armthumb (aae computes arm/thumb changes (lot of false positives ahead))
e anal.armthumb=true

# initialize esil vm
#e esil.stack.addr = 0x20000000
#e esil.stack.size = 0x000f0000

e asm.section.sub = true
e io.va=true

#S ${esil.stack.addr} ${esil.stack.addr} ${esil.stack.size} ${esil.stack.size} ram mrwx

#00000000 - 00003FFF: eos.tcm_code
S 0x0000000 0x00000000 0x3fff 0x3fff tcmcode mrwx

#00004000 - 1FFFFFFF: eos.ram
S 0x00004000 0x00004000 0x1FFFBFFF 0x1FFFBFFF  eosram mrw-

#40000000 - 40003FFF: eos.ram_uncached0
S 0x40000000 0x40000000 0x3fff 0x3FFF  eosramuncached0 mrw-

#40004000 - 5FFFFFFF: eos.ram_uncached
S 0x40004000 0x40004000 0x1FFFBFFF 0x1FFFBFFF  eosramuncached mrw-

#80000000 - 8000FFFF: eos.tcm_data
S 0x80000000 0x80000000 0xffff 0xffff tcmram mrw-

#BFE00000 - BFFFFFFF: eos.ram_extra
S 0xBFE00000 0xBFE00000 0x1fffff 0x1fffff  eosramextra mrw-

#C0000000 - DFFFFFFF: eos.iomem
S 0xc0000000 0xc0000000 0x1fffffff 0x1fffffff  eosiomem mrw-


#FC000000 - FDFFFFFF: eos.rom1
#FE000000 - FFFFFFFF: eos.rom1_mirror
S 0xfc000000 0xfc000000 0x1fffffff 0x1fffffff  eosrom1 mr-x
S 0xfe000000 0xfe000000 0x1fffffff 0x1fffffff  eosrom1m mr-x

aa
aaa
aae
e anal.hasnext = true
# e io.sectonly = true
e search.in = io.sections.exec
#aac
dbe 0xFE020000


(taken from https://vimeo.com/211371081 and adapted to 750D)
then leave this open in a text editor
start qemu .... -S -s  and  radare with :

r2 -aarm -b16 -d gdb://localhost:1234

paste the commands above into radare (loading as a startup script does not seem to work with gdb option)
hit vv and start debugging.



DieHertz

New ROM dumper on 6D2 works as intended, got different hashes, but I suppose it's because of change of settings since last dump?
@t3r4n you should consider moving these into ~/.radare2rc and not fiddle with text files and open editors :-)

BHybes