Emulating 1100d using trix

Started by elenhinan, February 14, 2014, 03:39:11 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

elenhinan

Sorry in advance for the long post.

I recently had a mainboard die on me while doing som hw-modifications to my 1100D, and ended up buying a replacement mainboard. This, however, is in FactoryMode, so USB connection isn't working normally. This is needed for my use (astrophotography).

Using IDA and a rom-dump from ML, I set on my way to fix this.

As the api call "ClearFactoryMode" present in some cameras isn't (or at least isn't registered) in the 1100D (1.05) firmware, I've been looking through the firmware after a memory/rom address that stores the factorymode setting. I figured that by finding a function which clearly branches depending on this setting, would set me on track to find the address.

The debuglog has these two entries:

    766:  1324.648 [PTP] ptpConnectModeChanged:ffffffff -> deadbeef
    767:  1324.661 [PTP] ConnectFactoryMode

Which is caused by the factorymode setting. I believe without it it would be ffffffff -> ffffffff and not deadbeef.
The entries to the log file is found in the function at xFF1262E4, where the deadbeef value is read through the address at R1 +x4. Sadly, I cannot find where this function is called from (and thus the value of R1), as the only xref (xFF59AA00) points to a long lists of DCD's followed by function addresses, and I don't know where these are used. I should also note that I understand that this setting alone might not be enough to get my camera out of factorymode, but it should restore normal function of the USB-port (I think/hope).

I should mention that I don't really have any experience with arm, I've done some assembly programming for AVR, and other more high-level languages as well as VHDL, so I'm really on new territory here.

In a hope to shed some light on this, I was hoping to emulate the startup using trix and ida, and this boots until the init fucntion (displaying K288 and so forth in the log), and then reaches an infinite loop in what I expect is the PowerMgr task (xFF1EA7D4). Thus it never reaches the breakpoint I've set in ptpConnectModeChanged.

Is this due to some interrupt driven by a timer used by the task scheduler not being implemeted, or is there something else in wrong? I don't expect the emulator to do wonders, but I was hoping it would get this far.

My alternative is to either compare my rom-dump with one from a healtyh 1100d, or try to get the old settings out of my more-or-less broken mainboard using led blinking or something. It can run the simple blink-tests, but doesn't boot up  anything else. Writing these settings into rom shouldn't be hard, at least I found some functions used by enablebootdisk etc that writes a value to a rom address.

If anyone has some hints/tips that would be great. A simple c-file for creating a autoexec.bin for blinking etc also would be nice. I might try using the GDB-fucntion for creating a breakpoint in the camera, and read out the register that way.

And a big thank you to everyone involved in this project, the amount of work you've done is astounding :) I'm almost happy my PCB died, so that I could dive into ML  ;)

a1ex

Well... if it only runs the simple blink tests, but doesn't boot, how did you reach the conclusion that USB is not working normally?

nanomad

Can you dump the value of *(0x38B0+0x3C) ? I guess not.

Anyway, I would tackle this by finally finding the damn debug port (should be an UART port like on CHDK, the connector is on the unused pins of the battery slot) and using the bootloader to figure out what's wrong (I think the camera is stuck there)
EOS 1100D | EOS 650 (No, I didn't forget the D) | Ye Olde Canon EF Lenses ('87): 50 f/1.8 - 28 f/2.8 - 70-210 f/4 | EF-S 18-55 f/3.5-5.6 | Metz 36 AF-5

a1ex

There are file I/O routines in bootloader (I can try to map them and get a ROM dump from there).

I also remember having some success with blinking DebugMsg strings on 60D.

elenhinan

Quote from: a1ex on February 14, 2014, 03:59:23 PM
Well... if it only runs the simple blink tests, but doesn't boot, how did you reach the conclusion that USB is not working normally?

Maybe I expressed myself badly.

The orignal mainboard does not do anything without an SD-card. If I insert an ML sd-card, it blinks if I use the blink test. Thats it. Apart from this, it's dead. Does not connect to usb either. I had a post about it a week ago.

The replacement mainboard, which is a new unused one from ebay, came preloaded with firmware 1.05 in factory mode. This works fine, except that it's recognized as "Canon EOS factory connect" when connecting via USB, and thus doesn't work with software like Backyard EOS. So this is the mainboard I'm working on, the old one is only interesting if any of the calibration data it might contain are needed, but I doubt it. This camera will be used with dark frames etc to correct for sensor bias, and shutter speed  of 10s -> 600s, so shutter calibration isn't really a concern.

As mentioned, I've modified the 1100d quite a lot. AF, AE, prism and mirror are gone, and display with keys are only connected for debugging. Shutter, flash, flash microswitch and so forth is cut of as well. Camera worked fine in this state earlier before the first mainboard went dead. With new mainboard it works fine now with e.g. live mode when I connect the display.

I could check for an UART, I don't have a scope at home but I could hook it up at work (monday the earliest), as long as it sends some bytes during startup I should be able to find the pin(s), baud rate etc.

Photo of the camera below. Goes in a IP44 box, with peltier cooling coupled with copper to the sensor, humidity sensor (to avoid condensation) and some temp sensors, with an arduino PID controlling the peltier voltage for constant temperature.


nanomad:
I had 0x38b0 pegged as "interesting", saw it in a couple of suspect places relating to factorymode. I have the ram-dump generated from the debug-menu of ML from the new mainboard, I'll open it in a hexeditor and see what the values are.



elenhinan

Extract from ram4.bin
This starts at 0x00000000 right?


I also compiled ML from the repository with an added menu including menu items for
SaveRasenToFile
SaveRingToFile
SaveLensToFile
SaveTuneToFile
SaveCamSetProp

The camera hangs when calling savetunetofile  (maybe since there is no tuning?), the rest of the outputs I have. Distributing the 1100D rom I guess isn't ok, but I can upload the rest of the dumps if you're interested. Shutter count is 16.7m as well, I guess it will start at 0 if I take an image.

a1ex

QuoteThe orignal mainboard does not do anything without an SD-card. If I insert an ML sd-card, it blinks if I use the blink test. Thats it. Apart from this, it's dead. Does not connect to usb either. I had a post about it a week ago.

Understood. I'm confident we can get a ROM dump from the dead one, and we can even attempt to reflash it if you want (it would be our first try, but we can't do any more damage than there already is, right?)

For the good mainboard, I'm tempted to try to call("FA_SetDefaultSetting"); this one will reset more settings than you can do from Canon menu (language will be set to Japanese, among other things). But I have no idea if this will touch the factory flag.

I assume you have already tried to update Canon firmware.

Here you can find my experiments about factory menus: https://groups.google.com/d/msg/ml-devel/ab7QERQye0M/qSqZ28qP20cJ (but I don't remember entering a persistent mode).

I do remember entering some mode where I could set a password to the camera, but I don't think it was called factory mode.

elenhinan

The "dead" mainboard we can try whatever on, only takes 4 screws and some ribbon cables to switch it with the working one.

I already did the FA_SetDefaultSetting, didn't change anything. Didn't even switch back to Japanese, as the board was configured for (luckily I do speak/read some) out-of-the-antistatic-bag. Did savecamsetprop, fa_setdefaultsetting, savecamsetprop. Haven't compared the files yet, and I called them using correct lower/uppercase (I think). But as the pcb was directly from factory, I guess it would already be at the "fa_setdefaultsetting"-settings.

Tried updating firmware, finishes saying completed, and nothing changes. I guess the factorymode is just a setting, not firmware-related per-se.

Only difference obvious to me in the normal menu, is that the internal fw version is listed after "3.7.3 55(21)" is listed after 1.05. There's no factory menu like some other cameras have.

edit: as a side-note, I think (in retrospect) what might have killed the mainboard might have been either the ebay ac-eos power-supply, or the fact that I removed the flash pop-up detector switch _and_ the flash hv capacitor, leaving the HV-power supply running without load. I do remember a faint high pitched noise from the camera some time before it died. I've since soldered the ribbon-cable where the flash-switch were, making the camera believe the flash is closed (this is the idea, anyway). Or it could have been electrostatic discharge, but this would be a first.

a1ex

This might give some hints: http://a1ex.bitbucket.io/ML/states/550D-alt/index.html

I can make a diagram like this for 1100D => done http://a1ex.bitbucket.io/ML/states/1100D-alt/sm29.htm

Also, I'd like to ask you to call prop_dump from debug.c after clearing Canon settings, ask another 1100D owner to do the same (nanomad? dmilligan? other volunteer?) and compare the logs.

elenhinan

Did this in the following ordeR:

1) started camera
2) prop_dump()
3) call(FA_SetDefaultSettings)
4) call(dumpf)
5) prop_dump()
6) powered camera on and off
7) prop_dump()

all three dumps are in separate directories in the zip-file, as well as the ML I used to run these (in my own menu called "factory" to the far right, see screenshot)

https://dl.dropboxusercontent.com/u/4977015/1100d_FactoryMode_PropDump.zip

So if anyone else want to dump their props, I could compare.

elenhinan

Thanks a1ex.
Worked myself through the state machine using the names you found, and the log file from dumpf.
Looks like my "PropTuningFlag" is xDEADBEEF, which is both printed in the log and in the prop_dump files at address 0x10000000, and this might be why it goes into factory mode.

I found an api call, "SetTuningFlag", which might do the trick. Now I just have to do some more research so I don't screw this up.
The next property, 0x10000000+4 is "0xBADCAFFE" which doesn't sound to good either :)

And thanks for all your quick replies! If I get this up and running I hope I can in turn help you all with something, like testing the uart.

edit: 0xFF05D3C8 is the function (I guess) for setting the tuning data. Question is, if this is a self-calibrating thing og needs input.. It's a huge function, so I'll have to try to understand it before calling it.

a1ex

From 550D:

PROP  1000000:     4:ffffffff
PROP  1000001:     4:badcaffe

So, it looks like a call("SetTuningFlag", -1) might do the trick?

Also, my decompiler says:

DebugMsg(51, 3, msg='ptpConnectModeChanged:%x -> %x', fact_struct.off_0x4 /*0x5270*/, arg1->off_0x4)
if NE(-arg1->off_0x4 + fact_struct.off_0x4 /*0x5270*/):
    if NE(1 + arg1->off_0x4):
        DebugMsg(51, 22, msg='ConnectFactoryMode', fact_struct.off_0x4 /*0x5270*/, arg1->off_0x4)


About that state machine: these functions (state transitions) are triggered when somebody sends an input message. Here, it happens from SyncSendPipeEvent or SendPipeEvent; you can match the first argument with the numbers from the state machine. For example, PD_SetZoom -> SyncSendPipeEvent(0x1c) -> ptpSetZoom. I've found the functions for 46 and 48, but not for 47.

It's also worth trying to setup a state object hook (look in state-object.c) and try to mangle the arguments of these functions. Not very easy though; here are some rough notes: http://magiclantern.wikia.com/wiki/StateObjects

You can also hook into DebugMsg (see dm-spy and gui-common.c) and mangle the RAM from there, or set a GDB watchpoint (examples in adtg_gui).

This one is also interesting: SetUSBToDCPMode (but can't find its code).

elenhinan

SetTuningFlag worked, took a split second to execute, and set dthe x1000000 deadbeef to ffffffff. Rebooted the camera, and it now connects as normal to both backyardeos and eos utilities.
I've attached the log from running the command, as well as the prop_dump

Camera won't take pictures though, it just timeouts when trying to take an image with either eos utility or byeos. It might be because it still thinks the flash is up, and wont take a picture before it has charged (?), or that the shutter count is 0xffffffff. Firmware version in the original menu shows as 1.05ME, and it says there's no firmware on the sd card if I try to update.

At this stage I hope there isn't anything wrong with the camera apart from software settings, but I really can't be sure so I'll play around a bit and see. If it's something HW it will de difficult to figure out.

https://dl.dropboxusercontent.com/u/4977015/prop_dump-settuningflag.zip

a1ex

Looks like it did something.

Did the camera take pictures before? Does it take pictures with ML intervalometer?

Can you do a call("Release") and post a log?

Tip: to get really detailed logs, enable dm-spy (might be a bit tricky). They will get saved into dm.log, but they will contain every single debug message (by default, Canon skips or trims a bunch of them, didn't figure out the exact behavior).

http://www.magiclantern.fm/forum/index.php?topic=2388

elenhinan

I haven't had much time to play with the camera the last days. Anyway:

I hadn't tried taking images with the camera before doing the "settuningflag" call, since I didn't have a shutter button. Didn't think of the intervallometer. Just in case, I ordered a new top with complete set up buttons, so I can check if tha flash/whatever has anything to do with it. It did take images fine after all my HW alterations though, up until the mainboard went bye-bye.

Second, I did try liveview before doing the settuningflag, and I looked like it worked ok. Now after, the image is mostly black, and I can only see something if I aim it directly at the downlights in the ceiling. Having no real data from this, this is just how I remember the events (so I might be wrong). My guess is that the canon service software writes some calibration data to the memory, which the "settuningflag" call then copies into rom. It does at least state in the log that it first cleares a sector of rom, then copies data.

   1604: 18128.332 [PROPAD] PROPAD_WriteFROMMultiPropertyPartly 0x15B050 1
   1605: 18128.432 [PROPAD] MultiPartly Check 0x1000000 4
   1606: 18160.670 [PROPAD] EraseSectorOfRom 0xF8B10000(0)
   1607: 18160.795 [PROPAD] Write Addr:0x403D3500->0xF8B10000(0) Size:0x10000
   1608: 18177.946 [PROPAD] Write VALID COMBO Addr:0xF8B10000(0)

So just copying a zeroed (or maybe random) array of data as calibration might not be the best way to success. I did see somewhere (can't find the link) an image from an uncalibrated sensor, where banding was visible. Makes sense to calibrate for this. For astrophotography, where one do dark frames anyway, being able to do this afterwards might actually be a good thing.ยจ

Anyway, my progress since last time was getting dm-spy up and running. Not knowing what functions/addresses "HIJACK_CACHE_HACK_*" was referring to, I found the addresses used for 600D and saw that they at least aligned with some functions on my 1100D, and tried it. And i worked :)

After enabling dm-log in the debug menu, I called "Release", generating the following log:
https://dl.dropboxusercontent.com/u/4977015/release-dmlog.zip

I'll see if I can bring my camera to work this week, and try too look for the uart. Does anyone know if data is sent on this by default, or does it have to be enabled? I guess I'll solder some wires to the battery-bay connector, making it easier to access. I think I have a ft232 somewhere I can hook it up to if I see a signal. No promises though, not much free time for this :(

a1ex

Okay, so... when you called Release, did it take a picture or at least try to?

Copying the tuning data from a good camera is a good idea IMO. Do you still have the ROM files from the old board from ML/LOGS? If so, zip them up along with the ROMs from the new one and send them to me (by PM please). If not, I'll ask nanomad to send me a dump from his 1100D.

I'd also fire up ADTG GUI (use these stubs for 1100D) and check the configuration of the LiveView sensor registers. I smell that tune data contains ADTG gains (among other things), and the gains are easy to override. It may even provide some insights about what these registers do what.

There is a log function in the modified ADTG GUI from the linked thread (it dumps all registers), but it only triggers after taking a picture (which it seems you can't do yet). You can try to make a modified version and upload the .mo file, so another 1100D owner can try and get the same log.

elenhinan

Found link regarding ccd calibration.

This company apparently makes software for calibrating EOS cameras (not the 1100D according to the list though, but all other cameras seems to be supported)

Image from sensor before and after calibration data.
http://www.spt.info/index.php/service-adjustment-software?id=21

Also, shutter speed is calibrated, as well as AE and AF. I guess being able to do this without paying $$$ would be nice.

elenhinan

Quote from: a1ex on February 16, 2014, 05:51:49 PM
Okay, so... when you called Release, did it take a picture or at least try to?

Copying the tuning data from a good camera is a good idea IMO. Do you still have the ROM files from the old board from ML/LOGS?

No, it didn't try. No sound from shutter. Camera hangs as well. At least the GUI does, commands like "beep" and the logging seems to run in the background.

Being stupid, I formatted the card when the old mainboard didn't boot up, hoping that would help. Low level format :( So no rom from old pcb. But it does run autoexec.bin at least, so I guess I could get them somehow with some work. Everything I need should be in 0xFF000000 -> 0xFFFFFFFF right?

a1ex

Yep, I'll prepare a bin to dump that area (already have one for 60D).

elenhinan

Thanks :)
I could probably manage myself if you have the source, if that's less of a hassle for you.

elenhinan

I managed to dump the rom (0xFF000000 -> 0xFFFFFFFF) from the old camera using the LED, checking every 4096 bytes with crc32 to be sure there where no transmission errors.

Comparing the rom on the new board with that of the old, this is how many bytes differ at which addresses:

0xff000000 - 00020
0xffa10000 - 00648
0xffa20000 - 10286
0xffa30000 - 01694
0xffa50000 - 00472
0xffa90000 - 00306
0xffb10000 - 43062
0xffb20000 - 64175
0xffb30000 - 64128
0xffb40000 - 64353
0xffb50000 - 36824
0xffb60000 - 33834
0xffb70000 - 16917
0xffbf0000 - 24136
0xffc00000 - 35853
0xffc10000 - 35824
0xffc20000 - 35656
0xffc30000 - 35684
0xffc40000 - 20717
0xffc50000 - 00010
0xffc60000 - 25037
0xffc70000 - 40493
0xffc80000 - 64618
0xffc90000 - 64606
0xffca0000 - 56450
0xffcf0000 - 48082
0xffea0000 - 59049
0xffeb0000 - 65416


Is there a function for copying data from memory to rom? I know of the one used by setbootdisk which only writes one byte of a time, which I guess should work.

Edit: Found erase_rom_section(adr) at 0xff1e94d4 and write_to_rom(to_adr, from_adr, length) at 0xff1e93c0. I guess I'll test them at an empty area of the nvram first and see.