UART / console redirection

  • 37 Replies
  • 10429 Views
*

Offline srsa_4c

  • ******
  • 3695
UART / console redirection
« on: 12 / December / 2013, 12:11:05 »
Advertisements
I decided to do some research on this topic.

On VxWorks, there was already some work done:
A messy proof-of-concept patch for the a610 (RW): https://trac.assembla.com/chdk/browser/trunk/tools/devel-patch
A write only solution (original work is probably this): https://trac.assembla.com/chdk/browser/trunk/platform/generic/main.c?rev=3271#L188

I have extended the latter by replacing the read handler routine of the /tyCo/0 device. Modified part of platform/generic/main.c below. This proof-of-concept code only executes the '?' command. To try it, CAM_CONSOLE_LOG_ENABLED needs to be defined in platform_camera.h. The patched finsig_vxworks finds all needed functions. WIP patch attached.
Code: [Select]
#if CAM_CONSOLE_LOG_ENABLED

#define DEV_HDR_WRITE_OFFSET (0x14C/4)
#define DEV_HDR_READ_OFFSET (0x148/4)
#define DEV_HDR_READ_SEM_1 (0x14)
#define DEV_HDR_READ_SEM_2 (0x3c)
#define DEV_HDR_READ_RNGBUF (0x10/4)

typedef int DEV_HDR;

int (*_tyWriteOrig)(DEV_HDR *hdr, char *buf, int len);


int hook_tyWriteOrig(DEV_HDR *hdr, char *buf, int len)
{
// Slow, but stable writes
FILE *fd = fopen("A/stdout.txt", "a");
if (fd) {
    fwrite(buf, 1, len, fd);
    fclose(fd);
}

    return _tyWriteOrig(hdr, buf, len);

}

int replaced_tyRead(int pTyDev, char *buf, int buflen)
{
    // this can't just be replaced when the system's already up, because
    // the original tyRead is already called by then (and it will wait indefinitely)
    // unless ... semGive is called on the 2 semaphores inside the original routine
    // note: buflen is 1 !!
    static int firsttime = 1;
    if (firsttime==1) {
        firsttime = 2;
        FILE *fd = fopen("A/chdklog.txt", "a");
        if (fd) {
            char buff[64];
            int bufflen = sprintf(buff, "pTyDev: %x, buf: %x, len: %x\n", pTyDev, (int)buf, buflen);
            fwrite(buff, 1, bufflen, fd);
            fclose(fd);
        }
        if (buflen>0) {
            msleep(2000);
            buf[0]='?';
            return 1;
        }
    }
    else if (firsttime==2) {
        firsttime = 0;
        if (buflen>0) {
            buf[0]='\n';
            return 1;
        }
    }
    while(1) {
        msleep(1000);
    }
    return 0;
}

void cam_console_init()
{
    DEV_HDR *DRV_struct;
    int tmp;

    extern DEV_HDR* _iosDevFind(char*, void*);
    DRV_struct = _iosDevFind("/tyCo/0", &tmp);

    _tyWriteOrig = (void*)DRV_struct[DEV_HDR_WRITE_OFFSET];

FILE *fd = fopen("A/chdklog.txt", "a");
if (fd) {
    // can't be used with "Fut" API
    //fprintf(fd, "DRV_struct: %x, _tyWriteOrig: %x\n", DRV_struct, _tyWriteOrig);
    char buf[256];
    int buflen = sprintf(buf, "DRV_struct: %x, _tyWriteOrig: %x\n", DRV_struct, _tyWriteOrig);
    fwrite(buf, 1, buflen, fd);
}

FILE *fdout = fopen("A/stdout.txt", "r");
if (fdout)
{
        // replace device write handler
        DRV_struct[DEV_HDR_WRITE_OFFSET] = (int)hook_tyWriteOrig;
        // replace device read handler
        DRV_struct[DEV_HDR_READ_OFFSET] = (int)replaced_tyRead;
        extern int _semGive(int semID); // low level Vx function
        extern int _rngBufPut(int id, char *buf, int len); // Vx ringbuffer related function
        // put some data into the read ringbuffer (in order to allow the read handler to return)
        int r1 = _rngBufPut(DRV_struct[DEV_HDR_READ_RNGBUF], "\n\n\n\n", 4);
        // unblock the 2 possible read semaphores (only the first appears to be needed, they are actually the same semaphore)
        int r2 = _semGive((int)DRV_struct + DEV_HDR_READ_SEM_1);
        int r3 = _semGive((int)DRV_struct + DEV_HDR_READ_SEM_2);
        // the original read handler will now return, the replaced one will be called from now on
        // get some debug info
        char buf[64];
        int buflen = sprintf(buf, "rngbp: %x, sg1: %x, sg2: %x\n", r1,r2,r3);
        fwrite(buf, 1, buflen, fd);
        fclose(fdout);
    fwrite("tyWrite replaced, camera log enabled\n", 1, sizeof("tyWrite replaced, camera log enabled\n")-1, fd);
    }

if (fd)
{
    fclose(fd);
}

}

#endif
To make something useful out of this, some kind of remote console support over PTP would be desirable. I will need some help with that...

edit: new patch, all functions are automatically found
« Last Edit: 13 / December / 2013, 14:22:31 by srsa_4c »

*

Offline ahull

  • *****
  • 634
Re: UART redirection
« Reply #1 on: 13 / December / 2013, 00:57:38 »
I have extended the latter by replacing the read handler routine of the /tyCo/0 device.

I am a little unclear on this, do we need to modify the /tyCo/0 device, or the default stdin,stdout and stderr handlers?

If we modify the /tyCo/0 handler, does this not then render the UART unusable for anything else?

If I understand how this works (and I am still reading through the VxWorks manuals, so in all probability I don't), then these are two separate things.

If you redirect the default stdin,stdout and std err handlers, that then frees up the UART for other purposes.

If on the other hand,  you patch the UART handler, then anything which subsequently attempts to use the UART will instead read and write to your patched handler.

I know that very few people will actually want to access the UART for other purposes, but we have already seen one pretty impressive hack from Chris Stubbs based on this.

I suspect it would be desirable to be able to patch both the UART and stdin/out/err handlers.
« Last Edit: 13 / December / 2013, 01:01:49 by ahull »

*

Offline srsa_4c

  • ******
  • 3695
Re: UART redirection
« Reply #2 on: 13 / December / 2013, 15:08:17 »
I am a little unclear on this, do we need to modify the /tyCo/0 device, or the default stdin,stdout and stderr handlers?
Since the earlier hacks modified the read/write handlers, I followed that route. It's possible to modify the global std* file descriptors too (on VxWorks at least), you can give that a try: ioGlobalStdSet, you can find the address in the above patch. You most likely won't get usable results with 'disk' files. BTW, the pipe library is available on the ixusW, I checked it.

Quote
If we modify the /tyCo/0 handler, does this not then render the UART unusable for anything else?
Quote
If you redirect the default stdin,stdout and std err handlers, that then frees up the UART for other purposes.
If on the other hand,  you patch the UART handler, then anything which subsequently attempts to use the UART will instead read and write to your patched handler.
My intention was to "talk" to the camera console, in a quick and dirty way. If that goal can be achieved differently (for example by creating a custom device for the standard file descriptors), then it's probably possible to talk to the console and use the uart at the same time.

I'm now trying to research the same in DryOS. Only succeeded to replace the write handler, the trick I used on the read handler in the above example doesn't seem to work yet...

I changed the topic title.

*

Offline ahull

  • *****
  • 634
Re: UART redirection
« Reply #3 on: 14 / December / 2013, 00:41:26 »
I am a little unclear on this, do we need to modify the /tyCo/0 device, or the default stdin,stdout and stderr handlers?
Since the earlier hacks modified the read/write handlers, I followed that route. It's possible to modify the global std* file descriptors too (on VxWorks at least), you can give that a try: ioGlobalStdSet, you can find the address in the above patch. You most likely won't get usable results with 'disk' files. BTW, the pipe library is available on the ixusW, I checked it.

Perfect, ioGlobalStdSet is exactly what I was trying to track down, you have done (most of) the hard work for me.
 
I think it should be possible to use the lua tricks I posted about before to set up a (disk?) file handles for std*, I'll have a go at that when I have some spare time. It would also be useful to have access to  ioGlobalStdGet( ) so we can check to see the values they are currently assigned, and restore them when we have finished using them.
Quote
Quote
If we modify the /tyCo/0 handler, does this not then render the UART unusable for anything else?
Quote
If you redirect the default stdin,stdout and std err handlers, that then frees up the UART for other purposes.
If on the other hand,  you patch the UART handler, then anything which subsequently attempts to use the UART will instead read and write to your patched handler.
My intention was to "talk" to the camera console, in a quick and dirty way. If that goal can be achieved differently (for example by creating a custom device for the standard file descriptors), then it's probably possible to talk to the console and use the uart at the same time.

I'm now trying to research the same in DryOS. Only succeeded to replace the write handler, the trick I used on the read handler in the above example doesn't seem to work yet...

I changed the topic title.


An interesting development, if you have anything you want me to test, let me know. I have an Ixus 115 HS with me as well as the SD430, so I should be able to test on both VxWorks and DryOS
« Last Edit: 14 / December / 2013, 01:42:00 by ahull »


*

Offline ahull

  • *****
  • 634
Re: UART / console redirection
« Reply #4 on: 14 / December / 2013, 00:51:22 »
BTW, the pipe library is available on the ixusW, I checked it.

That is also useful to know. From my digging the other day, I suspect that conversation with the wireless subsystem may rely on pipes. This is based on pure conjecture, so take this remark with a pinch of salt, until I produce hard evidence  ;) . There are a number of pipe device strings in the SD430 firmware....
Code: [Select]
/pipe/id%03d%c
pipe0
pipe1
wpipe0
wpipe1
cat: write error: Broken pipe
... FWIW, the wpipe device mentioned is probably related to the serial port.
« Last Edit: 14 / December / 2013, 00:53:11 by ahull »

*

Offline srsa_4c

  • ******
  • 3695
Re: UART redirection
« Reply #5 on: 14 / December / 2013, 11:42:47 »
It would also be useful to have access to  ioGlobalStdGet( ) so we can check to see the values they are currently assigned, and restore them when we have finished using them.
It's right after the other routine, @ 0xffc1b154.
Quote
if you have anything you want me to test, let me know
No progress yet. I simply don't have an idea what's happening. I have replaced both the read and write handlers during the boot process, and the read handler is simply not called at all (the other one is working). No such problem on VxWorks...

*

Offline ahull

  • *****
  • 634
Re: UART redirection
« Reply #6 on: 15 / December / 2013, 00:48:17 »
It would also be useful to have access to  ioGlobalStdGet( ) so we can check to see the values they are currently assigned, and restore them when we have finished using them.
It's right after the other routine, @ 0xffc1b154.
Thanks, I'll have a play with that when I have a spare moment.
Quote
Quote
if you have anything you want me to test, let me know
No progress yet. I simply don't have an idea what's happening. I have replaced both the read and write handlers during the boot process, and the read handler is simply not called at all (the other one is working). No such problem on VxWorks...
Very odd, for DryOs, sounds like either you have misidentified it (unlikely, but perhaps a typo somewhere in your code), or it is somehow already redirected. :blink:

*

Offline srsa_4c

  • ******
  • 3695
Re: UART redirection
« Reply #7 on: 15 / December / 2013, 07:42:18 »
Very odd, for DryOs, sounds like either you have misidentified it (unlikely, but perhaps a typo somewhere in your code), or it is somehow already redirected.
I think I got it. The DryOS camera console doesn't rely on stdin/out/err, it communicates directly with the uart driver. My replaced read handler was not called simply because there is (most likely) no part of the firmware that reads stdin.
The console code consists of (at least) two tasks: ConsoleSvr (the one that executes the commands) and LowConsole (which communicates with the uart).
In order to use the uart for other purposes, LowConsole has to be eliminated (which isn't too easy when the system's already up as it's coded to run forever).

Above notes are for DryOS, Vx cameras (except ixus30/40) also have those two tasks.


*

Offline srsa_4c

  • ******
  • 3695
Re: UART / console redirection
« Reply #8 on: 20 / December / 2013, 12:29:28 »
DryOS, continued.

As written previously, the "event shell" communicates directly with the UART driver. However, the various event procedures seem to use stdin/stdout. I have verified this by starting "drysh" via a script: I was able to talk to it and get its output. Next step: remote console over PTP.
Small excerpt from the output:
Code: [Select]
Dry> dminfo
[Driver Entry]
  total :   5 (DRV_ENTRY_MAX)
  used  :   3
[Created Devices]
  drvNo  name
     2   A
     0   /_term
[Default Device]
  device name :
[File Descriptor]
  total :  31 (DM_FILE_MAX)
  used  :   6
  open  :   3
Dry> exit

*

Offline ahull

  • *****
  • 634
Re: UART / console redirection
« Reply #9 on: 21 / December / 2013, 02:20:08 »
 :D (loud applause)... If I had a hat, I'd be throwing it in the air.

 

Related Topics