Display (bitmap overlay) - page 18 - General Discussion and Assistance - CHDK Forum

Display (bitmap overlay)

  • 175 Replies
Re: Display (bitmap overlay)
« Reply #170 on: 11 / April / 2021, 10:15:18 »
I just imported M10 111a into Ghidra, so I'll have some details coming soon  ;)

Perhaps worth to mention that most or all framebuffers are fixed in PowerShot firmware, whereas (AFAIK) they are allocated at run-time in EOS firmware.

They are kind of allocated (addresses are passed up from gui_init_event), but they somehow seem to always end up in exactly the same address, on multiple firmware versions and even between cameras (R and RP)
« Last Edit: 11 / April / 2021, 10:17:40 by kitor »
Magic Lantern / EOS R / 200D


Offline reyalp

  • ******
  • 13054
Re: Display (bitmap overlay)
« Reply #171 on: 11 / April / 2021, 14:06:36 »
I just imported M10 111a into Ghidra, so I'll have some details coming soon  ;)
In case you haven't found them, there are some scripts to help with that https://chdk.fandom.com/wiki/Firmware_analysis_with_Ghidra
Don't forget what the H stands for.

Re: Display (bitmap overlay)
« Reply #172 on: 11 / April / 2021, 14:41:57 »
Thank you.
I have some problems with Ghidra auto-analysis, at some moment it stops progressing and then 30 minutes later it will crash (same issue I had with 200D ROM).

Before it crashed I managed to locate XimrExe (size of payload is 0x300, like on 200D), CreateMARV, and what I thought might be the code that is responsible for context setup. But with missing xrefs and crash later... I have to retry tomorrow, this time starting with those scripts. Saving a project may be a good idea too  :-X

One thing I noticed, MARV "flags" field is a little bit different than on later models, it seems to hold just color type ID and bytes per pixel. Not that surprising for early implementation.
Magic Lantern / EOS R / 200D


Offline srsa_4c

  • ******
  • 4382
Re: Display (bitmap overlay)
« Reply #173 on: 11 / April / 2021, 14:48:49 »
I just imported M10 111a into Ghidra, so I'll have some details coming soon
I forgot to mention that PowerShot-based firmwares provide very few Zico hints on the ARM side. A list of mzrm handlers is useful for identifying the ARM side functions. Attached is a list of the m10 handlers, starting with handler #0 (first valid handler is #2). Look up calls to mzrm_createmsg to use the IDs.


Offline reyalp

  • ******
  • 13054
Re: Display (bitmap overlay)
« Reply #174 on: 11 / April / 2021, 18:59:20 »
Look up calls to mzrm_createmsg to use the IDs.
Added scripts to use lists like this to comment / find calls in ghidra https://app.assembla.com/spaces/chdk/subversion/commits/5827
Don't forget what the H stands for.

Re: Display (bitmap overlay)
« Reply #175 on: 12 / April / 2021, 14:34:52 »
Function at fc23d2b8 is responsible for redraw and for XimrContext structure population.
XimrContext is the structure passed as the first argument to most functions and then to XimrExe.

Disambiguation - we call VRAM structure "MARV" in Magic Lantern (little endian signature).
"Output Chunk" as well as "Ximr Context" are names directly taken from XCM on EOS R+. (XCMStatus EvShell command)

"Flags" field of MARV is a bit different to what I'm used to - possible values are  0x04000002, 0x05000004 and 0x07000002.
On the left "color type", on the right probably bytes per pixel.

Max 8 layers like on 200D. Layer definition inside Ximr Context has identical offsets to 200D.

Ximr functions are easy to find as they always take Ximr Context as first param.
All layer manipulation functions are easy distinguishable for that as 2nd param is checked to be below MAX_LAYER_COUNT (8 in case od Digic 6/7, 6 for Digic 8,X)

Bad news: The very first call is XimrInitializeContext, which means it is recreated on every redraw. This is different to 200D/M50 which does it once on init.
It is however a bit similar to R+ where this is handled by XCM on every redraw.

Now, some stubs. Declarations fit those from 200D.
Names of those stubs are made up by their function, no strings exists for those in EOS roms too.
I left numbered params where I'm not sure of their meaning, but they are saved into XimrContext structure.
Code: [Select]
fc3ed850 XimrInitializeContext(pXC)

fc3edac0 XimrSetLayerVisibility(*pXC, layer_id, state)
fc3edcae XimrSetLayerColorParams(*pXC, layer, *pMARV, color_id, p5)
fc3edae0 XimrSetLayerMARV(*pXC, layer_id, *pMARV, p4)
fc3edb26 XimrSetLayerDimensions(*pXC, layer, src_x, src_y, src_w, src_h, dst_x, dst_y)

fc3edc30 XimrSetLayer_related_fc3edc30(pXC, layer_id, p3, p4, p5)
fc3edc68 XimrSetLayer_related_fc3edc68(pXC, layer_id, p3, p4, p5)

fc3ed9ec XimrSetOutputChunkMARV(*pXC, *pMARV)
fc3edaa2 XimrSetOputChunkResolution(*pXC, w, h)

Decomp of those functions is weird to understand, as it has the same caveat as 200D, R and R6:
Code: [Select]
pLayer = (XimrLayerData_withOffset *)((int)pContext + layerId * 0x3c);There's some compiler optimization going on there, you need to offset actual context inside structure definition.

Undefined fields were not referenced (at least on 200D). Fields with _<offset> name - referenced, but unknown meaning, may have wrong data size.
Code: [Select]
struct XimrLayerData_withOffset {
    //add fake paddng
    uint8_t _0x48;
    uint8_t _0x49;
    undefined field_0x4a;
    uint8_t _0x4b;
    uint8_t _0x4c;
    uint8_t _0x4d;
    undefined field_0x4e;
    undefined field_0x4f;
    undefined field_0x50;
    undefined field_0x51;
    uint8_t _0x52;
    uint8_t _0x53;
    uint8_t _0x54;
    uint8_t color_type;
    uint8_t visibility;
    uint8_t _0x57;
    undefined field_0x58;
    undefined field_0x59;
    uint16_t src_y;
    uint16_t src_x;
    uint16_t src_h;
    uint16_t src_w;
    uint16_t dst_y;
    uint16_t dst_x;
    uint16_t enabled;
    struct MARV MARV;

First "true" field is at offset 0x48 while looking at decomp. Layer definition inside XimrContext start at the same offsets and seems to have the same structure.
Layers data is located at the same Ximr Context offsets as 200D/Digic 7.

Output Chunk is defined at different offset in Ximr Context (start at 0x28 on M10, 0xC on 200D).

Interesting part - there's a condition on which 3rd layer is referenced:
Code: [Select]

If you are able to patch this function and inject some instructions, you should be able to add own layer like this:
Code: [Select]
XimrSetLayerColorParams(XimrContext,0,pNewLayerMARV,colorId,0); //colorId is probably just 1
XimrSetLayerDimensions(XimrContext,0,0,0,src_x, src_y, src_w, src_h, dst_x, dst_y);

Please remember than on 200D (Digic 7) I had to align display buffer to 0x100, otherwise it was shifted by offset/4. This wasn't the case on R/Digic 8.
Other potential candidates to hook: very end of XimrInitializeContext, very beginning of XimrExe (before mzrm_createmessage).

I would just copy all parameters from layer 0/1, except pNewLayerMARV which you need to create yourself. In my experiments I created the structure myself, but there's a CreateMARV function you may try to use at fc586110:
Code: [Select]
MARV * CreateMARV (void * p1, uint32_t flags, uint width, uint height, uint p5, uint p6)
I never dug into functions that are not responsible for layers, except naming some of those. Goal was to add own layers, and those XimrSetLayer_* were enough to achieve that on 200D.
« Last Edit: 13 / April / 2021, 02:42:20 by kitor »
Magic Lantern / EOS R / 200D


Related Topics