IXUS190 porting attempt - DryOS Development - CHDK Forum

IXUS190 porting attempt

  • 97 Replies
  • 31142 Views
IXUS190 porting attempt
« on: 22 / May / 2017, 10:49:23 »
Advertisements
I'm trying to port Canon IXUS190

Dump: https://chdk.setepontos.com/index.php?topic=13142.0

Firmware: 100d

I follow the instruction http://chdk.wikia.com/wiki/Adding_support_for_a_new_camera

I took as a basis the Canon IXUS160 port.

Currently, I succeeded doing this:

Code: [Select]
make rebuild-stubs
But I failed yet to do this:

Code: [Select]
make fir
Here is the content of the files generated after make rebuild-stubs:

stubs_entry.S

https://pastebin.com/uhLUuNZa

stubs_entry_2.S

https://pastebin.com/W8LU8r0P

stubs_min.S

https://pastebin.com/KfGkfZkF

I am trying to do make fir, but I am getting errors:

Code: [Select]
../../../../platform/ixus190_elph200/libplatform.a(main.o): In function `get_focal_length':
main.c:(.text+0x70): undefined reference to `focus_len_table'
../../../../platform/ixus190_elph200/libplatform.a(main.o): In function `get_zoom_x':
main.c:(.text+0xb8): undefined reference to `focus_len_table'
../../../../platform/ixus190_elph200/sub/100d/libplatformsub.a(boot.o): In function `init_required_fw_features':
boot.c:(.text+0x5b0): undefined reference to `hook_CreateTask_low'
boot.c:(.text+0x5b4): undefined reference to `task_CaptSeq'
boot.c:(.text+0x5bc): undefined reference to `task_ExpDrv'
boot.c:(.text+0x5c4): undefined reference to `task_FileWrite'
boot.c:(.text+0x5cc): undefined reference to `task_MovieRecord'
../../../../platform/ixus190_elph200/sub/100d/libplatformsub.a(kbd_common.thm.o): In function `kbd_update_key_state':
kbd_common.c:(.text+0x60): undefined reference to `physw_status'
../../../../platform/ixus190_elph200/sub/100d/libplatformsub.a(kbd_common.thm.o): In function `kbd_update_physw_bits':
kbd_common.c:(.text+0xa8): undefined reference to `physw_status'
../../../../platform/ixus190_elph200/sub/100d/libplatformsub.a(shooting.thm.o): In function `rec_mode_active':
shooting.c:(.text+0x1694): undefined reference to `playrec_mode'
../../../../platform/ixus190_elph200/libplatform.a(wrappers.o): In function `takeFileIOSemaphore':
wrappers.c:(.text+0x3f8): undefined reference to `fileio_semaphore'
../../../../platform/ixus190_elph200/libplatform.a(wrappers.o): In function `open':
wrappers.c:(.text+0x468): undefined reference to `fileio_semaphore'
../../../../platform/ixus190_elph200/libplatform.a(wrappers.o): In function `close':
wrappers.c:(.text+0x4b8): undefined reference to `fileio_semaphore'
../../../../platform/ixus190_elph200/libplatform.a(wrappers.o): In function `write':
wrappers.c:(.text+0x518): undefined reference to `fileio_semaphore'
../../../../platform/ixus190_elph200/libplatform.a(wrappers.o): In function `fw_closedir':
wrappers.c:(.text+0x594): undefined reference to `fileio_semaphore'
../../../../platform/ixus190_elph200/libplatform.a(wrappers.o):wrappers.c:(.text+0x5e4): more undefined references to `fileio_semaphore' follow
collect2: error: ld returned 1 exit status
../../../makefile_sub.inc:59: recipe for target 'main.elf' failed
make[1]: *** [main.elf] Error 1

I don't know how to fix these errors yet. I defined the dummy values for problem functions - inside stubs_entry_2.S, but the rest of the code doesn't see them.

focus_len_table is not a function - but an array in main.c:

Code: [Select]
extern int focus_len_table[NUM_FL*NUM_DATA];
So I guess that NHSTUB is not suitable to define it?
« Last Edit: 22 / May / 2017, 10:57:29 by dorelly2 »

*

Offline srsa_4c

  • ******
  • 4451
Re: IXUS190 porting attempt
« Reply #1 on: 22 / May / 2017, 11:22:48 »
I am trying to do make fir, but I am getting errors
Looks like you're using outdated code (probably the 1.4 branch). Recent developments only go to trunk, you should switch to that.
The sigfinder will find the focus length table _after_ you specify the lens parameters (CAM_DNG_LENS_INFO) in platform_camera.h correctly.

Re: IXUS190 porting attempt
« Reply #2 on: 23 / May / 2017, 02:34:39 »
That's right, I use the 1.4 branch. It's said to be stable, and should I use unstable releases like trunk? Is it a good idea to use unstable branches? You want to say that it is impossible to use 1.4 branch?
« Last Edit: 23 / May / 2017, 02:41:26 by dorelly2 »

Re: IXUS190 porting attempt
« Reply #3 on: 23 / May / 2017, 10:19:22 »
Recompiled with trunk sources. Have set in platform_camera.h:

Code: [Select]
    #undef CAM_DNG_LENS_INFO               { 50,10, 400,10, 32,10, 69,10 } // See comments in camera.h
    #define CAM_DNG_LENS_INFO               { 43,10, 430,10, 30,10, 69,10 } // See comments in camera.h

Proof: http://www.canon-europe.com/cameras/ixus-190/specifications/

Compiled with make fir, but in order to compile I had to put this into stubs_entry_2.S:

Code: [Select]
#include "stubs_asm.h"

NHSTUB(TurnOffBackLight, 0x12345678)
NHSTUB(TurnOnBackLight, 0x12345678)
NHSTUB(close, 0x12345678)
NHSTUB(exmem_alloc, 0x12345678)
NHSTUB(open, 0x12345678)

NHSTUB(MakeDirectory_Fut, 0x12345678)
NHSTUB(RefreshPhysicalScreen, 0x12345678)

// make fir errors

NHSTUB(TurnOffE1, 0x12345678)
NHSTUB(init_focus_eventflag, 0x12345678)
NHSTUB(init_nd_eventflag, 0x12345678)
NHSTUB(init_nd_semaphore, 0x12345678)
DEF(hook_CreateTask_low, 0x12345678)
DEF(playrec_mode, 0x12345678)
NHSTUB(SetZoomActuatorSpeedPercent, 0x12345678)
NHSTUB(UnsetZoomForMovie, 0x12345678)

I am compiling straight inside ixus160_elph160 folder - in other words I did NOT create some new ixus190_elph200 folder - to avoid any set up problems like adding the new folder name into the camera_list.csv (or maybe more?). I'll create a new folder at the very last moment.

I have now some compiled DISKBOOT.BIN. Should I test in in my camera? It is really small, just 130 KB.

What's next step?
« Last Edit: 23 / May / 2017, 11:04:48 by dorelly2 »


*

Offline reyalp

  • ******
  • 14082
Re: IXUS190 porting attempt
« Reply #4 on: 23 / May / 2017, 13:34:22 »
I would suggest working from the trunk sources at this point, but the differences aren't too large. There are some ports of more recent cameras in the trunk.

I am compiling straight inside ixus160_elph160 folder - in other words I did NOT create some new ixus190_elph200 folder - to avoid any set up problems like adding the new folder name into the camera_list.csv (or maybe more?). I'll create a new folder at the very last moment.
FWIW, I'd suggest starting a new folder and dealing with those problems now. There shouldn't be too much that you have to do, camera_list.csv is only used for batch builds.

Don't forget to create the loader directory as well.

Quote
I have now some compiled DISKBOOT.BIN. Should I test in in my camera? It is really small, just 130 KB.
There's not really any point until you've gone a bit further.
Quote
What's next step?
You need to correct every platform specific item in the platform directory. That means all the inline assembly (normally generated using code-gen), every address, reference to a firmware function, makefile.inc settings etc. It's OK to dummy some things out to get it boot, but you really need to keep track of what's copied from the other port and what is verified.

If you just want to try to make something boot, I would put in infinite loop that just blinks an LED somewhere very early in the process (e.g. at the top of loader my_restart). If you don't know an LED address, it's a fair guess it will be the same as ixus160.

At a minimum, you will need to figure out the correct diskboot or FI2 encoding (for the bootable SD card and "firmware update" boot methods, respectively). You also need the right PID for FI2 encoding. You also need it for diskboot unless you disable the compatibility check.

Once you've got an LED blinking in loader, you move the blinking loop into platform boot.c.

In your stubs_entry_2.s, using 0x12345678 will cause an immediate crash if any of those functions are called. Typically, we define NULL_SUB to point to a return instruction when we need a dummy address. Some functions require a return value, for those you could point at a function that returns 0 or 1 instead.

Don't forget what the H stands for.

Re: IXUS190 porting attempt
« Reply #5 on: 24 / May / 2017, 03:59:46 »
Quote
You need to correct every platform specific item...
Yes, I understand this basic idea.

But I am reading the article http://chdk.wikia.com/wiki/Adding_support_for_a_new_camera and I understand nothing. This article seems to be too outdated. I simply don't find paths, folders, files, functions, values mentioned therein. As a result, I just don't understand what should I do and how.

I don't understand the CHDK boot-up flow, which file boots first, how exactly does it do it, what functions are called and in what order, and where are the platform-dependent values that need to be substituted. What is it - "task creation" (what is "task"), what are these files with "*.S" extensions, how do they work in terms of C language usage. Is this some sort of precompile (I mean these NHSTUB and DEF macros)? What it "kbd.c" - my camera doesn't have any keyboard.

Maybe there is some more up-to-date porting instruction? Show it it to me, please.

If there is not - perhaps some experienced developer here would write one?

Quote
Typically, we define NULL_SUB to point to a return instruction when we need a dummy address
OK. But how would I get the value for NULL_SUB?
« Last Edit: 24 / May / 2017, 04:16:40 by dorelly2 »

Re: IXUS190 porting attempt
« Reply #6 on: 24 / May / 2017, 08:52:24 »
Quote
you will need to figure out the correct diskboot
I don't understand you.
Quote
"firmware update" boot method
It doesn't interest me.
Quote
You also need the right PID
If you mean PLATFORMID from stubs_entry.S, it is available (but it is also already known from http://chdk.wikia.com/wiki/P-ID_(Table) ):

stubs_entry.S
Quote
// Camera info:
//   DRYOS R59 (DRYOS version 2.3, release #0059+p3)
//   Firmware Ver GM1.00D   // Found @ 0xff0ac3bc, "GM1.00D" @ 0xff0ac3c9
//   Firmware build timestamp: Nov 14 2016 10:10:59
//   Canon IXUS 190

// Values for makefile.inc
//   PLATFORMOSVER = 59
//   PLATFORMID = 13011 (0x32d3) // Found @ 0xfffe0270
//   MAXRAMADDR = 0x07ffffff
//   MEMISOSTART = 0x0028e804
//   KEYSYS = ? Not found, possible new firmware encryption key.              // Found @ 0xff014590

Quote
If you don't know an LED address
Of course, I don't. And how would I?
Quote
it's a fair guess it will be the same as ixus160
I found some code in ixus160 lib.c:
Code: [Select]
#define LED_PR 0xc022f1fc
#define LED_AF 0xc022d200

void debug_led(int state)
{
*(int*)LED_PR=state ? 0x93d800 : 0x83dc00;
}
I don't quite understand what is does. Guess swithes light on/off? Besides what if the LED address is not the same? How do I search it? Where is the instruction?

https://chdk.setepontos.com/index.php?topic=13105.msg132548#msg132548
Quote
bootloader start is 0xff010000, firmware start is 0xff020000
The first value is ROMBASEADDR as defined in makefile.inc:

Code: [Select]
ROMBASEADDR=0xff010000
MAXRAMADDR=0x07ffffff
MEMISOSTART=0x0028e804

But what is the second value (0xff020000)? Is it MEMBASEADDR ?
« Last Edit: 24 / May / 2017, 09:52:15 by dorelly2 »

Re: IXUS190 porting attempt
« Reply #7 on: 24 / May / 2017, 10:02:37 »
loader/entry.S from ixus160:

Quote
.section .entry

    LDR     SP, =MEMBASEADDR
    BL      check_compat


// ordinary startup...

    MOV     SP, #0x1900
    MOV     R11, #0
    B       my_restart

I wonder - what is the "#0x1900" value? The documentation says:

Code: [Select]
mov sp, #<MEMBASEADDR>   
mov r11, #0   
b   my_restart

loader/main.c from ixus160:

I need to understand what does this code do and should I replace it from ixus160 to ixus190:
Code: [Select]
#include "../generic/check_compat.c"

extern long *blob_chdk_core;
extern long blob_chdk_core_size;

void __attribute__((noreturn)) my_restart()
{
    {
        long *dst = (long*)MEMISOSTART;
        const long *src = blob_chdk_core;
        long length = (blob_chdk_core_size + 3) >> 2;

  core_copy(src, dst, length);

}

    // restart function
    // from sub_FF83846C via 0x12345678
    asm volatile (
"    MOV     R0, #0x78 \n"
"    MCR     p15, 0, R0, c1, c0 \n"
"    MOV     R0, #0 \n"
"    MCR     p15, 0, R0, c7, c10, 4 \n"
"    MCR     p15, 0, R0, c7, c5 \n"
"    MCR     p15, 0, R0, c7, c6 \n"
"    MOV     R0, #0x80000006 \n"
"    MCR     p15, 0, R0, c9, c1 \n"
"    MCR     p15, 0, R0, c9, c1, 1 \n"
"    MRC     p15, 0, R0, c1, c0 \n"
"    ORR     R0, R0, #0x50000 \n"
"    MCR     p15, 0, R0, c1, c0 \n"
"    LDR     R0, =0x12345678 \n"
"    MOV     R1, #0x80000000 \n"
"    STR     R0, [R1, #0xFFC] \n"
//"    BL      sub_FF896A8C \n"  // nullsub
//"    LDR     R0, =0xFF820000 \n"
"MOV     R0, %0\n"              // new jump-vector
//"    LDMFD   SP!, {R4,LR} \n"
"    BX      R0 \n"
         : : "r"(MEMISOSTART) : "memory","r0","r1","r2","r3","r4"
        );

        while(1);
}

and whether the startup() function in platform/<camera>/main.c is called and where.

platform/<camera>/sub/<version>/boot.c - should it be manually corrected? It states:
Code: [Select]
/*
 * boot.c - auto-generated by CHDK code_gen.
 */
« Last Edit: 24 / May / 2017, 10:48:57 by dorelly2 »


*

Offline srsa_4c

  • ******
  • 4451
Re: IXUS190 porting attempt
« Reply #8 on: 24 / May / 2017, 11:31:22 »
Before I attempt to answer some of the questions, one advice: You need to disassemble your camera's firmware and at least one more (the ixus160, for example). Use this script first (after editing it, so it finds the utilities): http://chdk.wikia.com/wiki/GPL:disassemble.pl
After that, use the resulting PRIMARY.BIN.dis plus the file named funcs_by_address.csv (finsig_dryos outputs this for you) with the following script: http://chdk.wikia.com/wiki/User:Srsa_4c/GPL:stubs2disv7.pl . You'll get disassembly files that have a lot of functions identified and string references will become visible.
The missing stubs and variables can mostly be located using one or more known camera's disassembly as reference.
I don't understand the CHDK boot-up flow
Here's what happens when the camera loads diskboot.bin:
- The content of diskboot.bin is unscrambled and is copied to MEMBASEADDR (that's 0x1900 on DIGIC II...5).
- Cam is restarted, the bootloader jumps to the loaded code at 0x1900.
- The diskboot file starts with code found in loader/
- The CHDK loader copies the CHDK core to its final location. That is usually the original starting address of the camera's malloc heap. The Canon heap is then adjusted in the boot process so Canon code doesn't overwrite the CHDK core.
- A compatibility check is new in CHDK 1.5 (that's the check_compat call you quoted).
- When the CHDK core is relocated, the CHDK loader starts executing it (platform/camera/main.c).
- After this, a modified copy of Canon boot code is executed (platform/camera/sub/.../boot.c), to start the camera normally, with CHDK running alongside the firmware.

diskboot.bin files are scrambled, the scrambling method is known as "dancing bits".
Quote
- "task creation"
the firmware's CreateTask function (or one of its variants) is used to start tasks.
Quote
(what is "task")
Something like this: https://en.wikipedia.org/wiki/Thread_(computing)
Quote
, what are these files with "*.S" extensions, how do they work in terms of C language usage
They contain ARM assembly and/or preprocessor macros. They are there to interface CHDK with the Canon firmware.
Quote
What it "kbd.c" - my camera doesn't have any keyboard.
Cameras have buttons, that's what we call keyboard.

Quote
But how would I get the value for NULL_SUB?
Find a BX LR instruction in your cam's disassembly and use its address.
« Last Edit: 24 / May / 2017, 11:51:57 by srsa_4c »

*

Offline reyalp

  • ******
  • 14082
Re: IXUS190 porting attempt
« Reply #9 on: 24 / May / 2017, 13:43:18 »
Quote
you will need to figure out the correct diskboot
I don't understand you.
"correct diskboot or FI2 encoding"

This means the NEED_ENCODED_DISKBOOT value in makefile.inc, which is used by dancingbits.c in tools. If your camera uses a previously unknown value, then you have to add it to dancingbits. If stubs_entry.S doesn't identify the value or address, you can find it by finding the value of in an already-supported firmware, finding the code that references it (will have references to diskboot related strings) and then finding the corresponding code in your firmware.

This general approach of "find thing in working port, find a way to identify thing in disassembly, find corresponding thing in your firmware" is the main technique used to make a port.

Quote
Quote
If you don't know an LED address
Of course, I don't. And how would I?
From the firmware disassembly, or testing using canon basic.
Quote
I found some code in ixus160 lib.c:
Code: [Select]
#define LED_PR 0xc022f1fc
#define LED_AF 0xc022d200

void debug_led(int state)
{
*(int*)LED_PR=state ? 0x93d800 : 0x83dc00;
}
I don't quite understand what is does. Guess swithes light on/off?
Yes,  0xc022f1fc is the MMIO address, and the two values switch it on and off, respectively.
Quote
Besides what if the LED address is not the same? How do I search it? Where is the instruction?
Either by trial and error (Canon tends to use a relatively limited range of addresses, so trying values used by other recent cameras is a good bet) or by reverse engineering LED related functions. Unfortunately, the exact address isn't usually referenced directly for LEDs, so they can be a tricky to find.

Quote
But I am reading the article http://chdk.wikia.com/wiki/Adding_support_for_a_new_camera and I understand nothing. This article seems to be too outdated. I simply don't find paths, folders, files, functions, values mentioned therein. As a result, I just don't understand what should I do and how.
It's a bit out of date, but most of it still applies.

Unfortunately, there is no newer/better documentation. It would be nice to have something better, but writing a comprehensive porting guide is a huge amount of work.
Don't forget what the H stands for.

 

Related Topics