supplierdeeply

rebooting/loading CHDK binaries from lua or canon basic

  • 60 Replies
  • 8300 Views
*

Offline reyalp

  • ******
  • 10069
rebooting/loading CHDK binaries from lua or canon basic
« on: 12 / September / 2010, 03:44:45 »
Advertisements
This is only tested on D10, should be similar on other cams.
Background:
romstarter code puts a pointer to a canon function like copy_at_restart in the first word of data TCM (0x80000000 or 0x40000000 depending on camera)
This is the function both firmware update and diskboot loading use to start the loaded binaries, after decoding. It doesn't do much (if any) hardware initialization.

Idea:
load unencoded CHDK image (loader/<camera>/main.bin) into regular malloc RAM.
Call canon function to copy it it to 0x1900 and run.
Problem: Most of the time it crashes or the display is black or corrupted.
Solution: (?) Call DispCon_TurnOffDisplay before calling canon reboot function.
This seems to work for me. Even in record mode. I'm a little surprised that other hardware doesn't get confused, YMMV.

Since only eventprocs and predictable addresses are used, this should be possible in canon basic too. This means an alternate manual loading method instead of firm update. No encoding required.

If you are using this to reboot CHDK, you need a full CHDK binary size of free memory.
Code: (lua) [Select]
--[[
@description test loader
--]]
imgname = "A/MAIN.BIN"
st=os.stat(imgname)
if not st then
error("failed to stat" .. imgname)
end
if call_event_proc("SystemEventInit") == -1 then
error("SystemEventInit failed")
end
imgbuf=call_event_proc("AllocateMemory",st.size)
if imgbuf == 0 then
error("failed to allocate" .. st.size)
end

imgfile=call_event_proc("Fopen_Fut",imgname,"rb")
if (f==0 or f==-1) then
error("Fopen_Fut" .. imgname .. " failed " .. imgfile)
end
if call_event_proc("Fread_Fut",imgbuf,st.size,1,imgfile) ~= 1 then
error("Fread_Fut failed")
end
print("loaded " .. st.size .. " at  " .. imgbuf)
sleep(2000)
call_event_proc("DispDev_EnableEventProc")
call_event_proc("DispCon_TurnOffDisplay")
sleep(1000)
canon_copy_and_restart = peek(0x80000000)
call_func_ptr(canon_copy_and_restart,0x1900,imgbuf,st.size,0x1900)
Don't forget what the H stands for.

*

Offline fudgey

  • *****
  • 1705
  • a570is
Re: rebooting/loading CHDK binaries from lua or canon basic
« Reply #1 on: 12 / September / 2010, 06:48:24 »
Awesome ;)

I attempted to use the script to load DISKBOOT.BIN on a570 100e (it's unencoded i.e. it's just a copy of loader/a570/main.bin from after building that sub) using 0x40000000 in the peek.

It does not work, causes a crash. No romlog is written. A bare blinking diskboot.bin does not blink.

The script gets 0xffff05a0 from peek(0x40000000) which at first glance looks good: it's an entry point to a function that uses the strings "..Start Program on RAM" and "..< Verify Error >". The latter makes me think it could require a checksum or something, but wouldn't that be the same for normal reboot (I've never ported a camera so I've never studied CHDK loading stuff either, really...). Or maybe it just requires a different syntax?


On the other hand I did manage to reboot my camera by simply calling 0xffc0b748 from lua, which is something I've never been able to do before. This address of course only works on the a570 100e, similar commands have already been proven on DryOS cameras.

*

Offline reyalp

  • ******
  • 10069
Re: rebooting/loading CHDK binaries from lua or canon basic
« Reply #2 on: 12 / September / 2010, 19:41:24 »
Interesting. I haven't yet been able to make it work from canon basic, which was actually my main goal in this project. I can load the file, register an event proc to and call it but the camera hangs (not crash or assert,) before reaching CHDK loader/<camera>/entry.s

The canon code (for diskboot and fi2 update) does disable interrupts before calling this function, but I don't do it in the lua version so I'm not sure why it would be required here. There could also be cache/write buffer issues, although I'd expect the verify step to cause pretty much everything to get flushed out.

I know I have event proc registration working, because I can register sprintf under a different name and it works fine.

It's important to remember that this does NOT do the normal camera shutdown sequence. This means
- hardware may not be in the state expected on restart. This could cause abnormal behavior or maybe even damage.
- recently changed camera settings might not be saved to flash (taskBye does some write to rom stuff)
- filesystem stuff may not synced to SD. However, you generally don't lose much in abnormal shutdowns (assert, exception etc) that aren't in the middle of actually writing something, so this should be OK, especially if you switch to play mode before doing the reboot. Switching to play recommended anyway, since I'd expect more of the hardware to be in an off or idle state.

For CHDK, it might be better to copy taskBye and replace the last bit with the load and restart code. Or hook it, and check a global to decide if a reboot or actual shutdown is requested.

I believe the verify stuff just checks the the copied data matches. This could fail if interrupts aren't disabled (because some ram could get modified) or the source and destination overlap. From CHDK, the memory should not overlap, since almost the entire CHDK image has to fit before the start of heap. Loading from canon basic without CHDK, overlapping might be a problem, but can probably be worked around. If verify fails, it does go into a tight loop, which would match the symptoms I'm seeing.
Don't forget what the H stands for.

Re: rebooting/loading CHDK binaries from lua or canon basic
« Reply #3 on: 12 / September / 2010, 20:06:23 »
I did manage to reboot my camera by simply calling 0xffc0b748 from lua


Did you have to pass any parameters to that function ?

Does it work with DISKBOOT.BIN or the FIR file ?



David


*

Offline reyalp

  • ******
  • 10069
Re: rebooting/loading CHDK binaries from lua or canon basic
« Reply #4 on: 12 / September / 2010, 20:30:01 »
Did you have to pass any parameters to that function ?
It looks like the only possible parameter is 7, which would make it not actually restart. This is used by firmware update code.

It will use diskboot, since the diskboot won't be hidden when it restarts.

This means that if you want to load an arbitrary image, you should be able to call this function with 7, and then use the canon copy and restart mentioned earlier. It also skips some parts that do CP15 manipulation, so that may need to be done elsewhere.

If this function works on most cameras (or most vxworks at least) it's probably worth adding to sig_ref. The code from this function is also used as a basis for loader/<platform>/resetcode/main.c

I've got the canon basic loader working BTW, it did need IRQ disabled. This means I'll have to load and run a tiny bit of ARM code, but it should be completely camera independent.
Don't forget what the H stands for.

*

Offline reyalp

  • ******
  • 10069
Re: rebooting/loading CHDK binaries from lua or canon basic
« Reply #5 on: 13 / September / 2010, 01:44:21 »
http://drop.io/reyalp_chdk/asset/cbloader-1-zip

canon basic loader. Only tested on d10 right now, I'll try to get it working on a540 later. It uses LCDMessage for diagnostics, so cameras without that may not work out of the box.

extend.m is the script
cbloader.bin is a small piece of ARM code that is loaded and run by extend.m
cbloader.S is the source to cbloader.bin The version included has code to disable and flush the caches, but this doesn't appear to be needed on D10.
makefile.diff is a patch to the loader/<camera>/makefile to build cbloader. Doesn't matter which camera you apply it to.

cbloader.bin gets the address of data TCM from CP15, so it doesn't need to be adjusted for different cameras.

The code for cbloader.bin could be hard coded into the script as a bunch of numeric constants, but it would be awkward without arrays, and it's more likely to work if it is in uncached memory.

Note that if you want to run simple ARM code from cbasic, without rebooting the camera, you can just run it like cbloader. "simple" is anything that doesn't rely on being loaded at a fixed address, which probably means hand written asm, but a small amount of C might be OK.

If you use this to manually load CHDK, you'll probably want to make it inoperative once CHDK is loaded. This could be done by registering an eventproc from CHDK, and checking with ExecuteEventProcedure in the script.
Don't forget what the H stands for.

Re: rebooting/loading CHDK binaries from lua or canon basic
« Reply #6 on: 13 / September / 2010, 07:59:31 »

It looks like the only possible parameter is 7, which would make it not actually restart.


Well, I do not know how fudgey got it to work.

I had previously tried passing values '0' and '7'.

'0' caused camera to retract lens, immediately extend it, show Canon splash screen and then hang.

Restart was called from a uBasic function.

*

Offline whoever

  • ****
  • 280
  • IXUS950
Re: rebooting/loading CHDK binaries from lua or canon basic
« Reply #7 on: 13 / September / 2010, 10:46:11 »
http://drop.io/reyalp_chdk/asset/cbloader-1-zip

canon basic loader. Only tested on d10 right now, I'll try to get it working on a540 later. It uses LCDMessage for diagnostics, so cameras without that may not work out of the box.
It actually works as is  on Ixus950 (late VxWorks), even though ExMem() is missing here (what is it supposed to do anyway?). Loaded the full CHDK binary, which then ran normally, without visible side effects.

I did manage to reboot my camera by simply calling 0xffc0b748 from lua
Did you have to pass any parameters to that function ?
I used to call the corresponding function in Ixus950 (thru PTP) like that:
Code: [Select]
((void(*)(int)) 0xFF81B74C)(0); // usu reboots Ixus950 (interesting "screen fade" effect)
which "usually" worked, with funny LCD fading while rebooting (as I didn't call DispCon_TurnOffDisplay).


Re: rebooting/loading CHDK binaries from lua or canon basic
« Reply #8 on: 13 / September / 2010, 12:07:44 »
Well, I see the funny LCD fading but on reboot, after displaying splash screen, the camera hangs.

Let us see if I have done this correctly  ....

In A620 stubs_entry_2.s :-

NHSTUB(reboot_fw_update, 0xFFC127E0)

In A620 lib.c  :-

void reboot(int fw_update)
{
  _reboot_fw_update(fw_update);
}

In lolevel.h :-

#if !CAM_DRYOS
extern void _reboot_fw_update(int);
#else
extern void _reboot_fw_update(char *);
#endif

In platform.h :-

#if !CAM_DRYOS
void reboot(int); 
#else
void reboot(char *fw_update); // fw_update == NULL implies normal reboot
#endif

In the uBasic function :-

  #if defined(CAMERA_a620)
      reboot(0);                      // **** TESTING ****
  #else
   char *fn = "A/PS.FI2";
   reboot(fn);
  #endif

*

Offline reyalp

  • ******
  • 10069
Re: rebooting/loading CHDK binaries from lua or canon basic
« Reply #9 on: 13 / September / 2010, 12:21:07 »
It actually works as is  on Ixus950 (late VxWorks), even though ExMem() is missing here (what is it supposed to do anyway?).
On D10, it looks like ExMem() registers the ExMem* functions, and then unregisters itself. ExMem.AllocUncacheable() is needed, so those functions must be registered already on your camera.

Quote
I used to call the corresponding function in Ixus950 (thru PTP) like that:
Code: [Select]
((void(*)(int)) 0xFF81B74C)(0); // usu reboots Ixus950 (interesting "screen fade" effect)
which "usually" worked, with funny LCD fading while rebooting (as I didn't call DispCon_TurnOffDisplay).
Before I discovered turning off the display, it rebooting was quite intermittent, wither several different possible behaviors.

It looks like 3 is another possible parameter to this function, in on some cameras.
Don't forget what the H stands for.

 

Related Topics