Sign up here and you can log into the forum!

Unresponsive stock remote when eiri enabled with EIRI='ON'

Have a question about devices internals, memory layout, reverse engineering, etc---This is the place for anything so technical that it would cause a n00b's head to 'splode

Unresponsive stock remote when eiri enabled with EIRI='ON'   

Postby serpens » Mon Oct 26, 2015 6:26 am

I installed 1.05.04_B_WDLXTV.COM_WDLXTV_PLUS-0.5.2.2 and with EIRI='ON' discovered that some of the stock remote buttons do not work. A search of the forums shows that this is already known: http://forum.wdlxtv.com/viewtopic.php?f=38&t=5374

Some detective work shows that the last working kernel is 1.03.49 and the first kernel with this issue is 1.05.04, and the key difference between the two kernels for this issue lies in the implementation of irkernel.c:
Code: Select all
diff -ur 1.03.49/bungalow_1.03.49_B/src/libs/3_8_0/linux-2.6.22.19/drivers/char/irkernel.c 1.05.04/bungalow_1.05.04_B_G/src/libs/3_8_0/linux-2.6.22.19/drivers/char/irkernel.c
--- 1.03.49/bungalow_1.03.49_B/src/libs/3_8_0/linux-2.6.22.19/drivers/char/irkernel.c   2010-10-28 20:20:16.000000000 -0700
+++ 1.05.04/bungalow_1.05.04_B_G/src/libs/3_8_0/linux-2.6.22.19/drivers/char/irkernel.c 2011-04-27 03:37:24.000000000 -0700
@@ -1,3 +1,8 @@
+#define        CONFIG_IR_REPORT_RELEASE_KEY
+#ifdef CONFIG_IR_REPORT_RELEASE_KEY
+#define        CONFIG_IR_ALT_KEY
+#endif // CONFIG_IR_REPORT_RELEASE_KEY
+
...
@@ -738,6 +882,9 @@
                return(-ENOMEM);
#endif //CONFIG_IR_HOLD_KEY
        }
+#ifdef CONFIG_IR_ALT_KEY
+       ir_priv.alt_key_table = kmalloc(max_keys * sizeof(unsigned long), GFP_KERNEL);
+#endif // CONFIG_IR_ALT_KEY

        /* Register device, and may be allocating major# */
        status = register_chrdev(major_num, ir_devname, &ir_fops);

As shown above, the root cause of the problem is that the implementation of CONFIG_IR_ALT_KEY allocates memory for the alt_key_table but fails to initialise it. The resulting uninitialised alt_key_table contains non-zero entries that can confuse the subsequent key processing code.

The obvious fix is to initialise the alt_key_table, but this will require either a kernel rebuild, or at the very least a rebuild of the kernel module irkernel.ko.

As a proof of concept, I took a different approach, which is to use the new IR_IOCSETALTKEYS ioctl to initialise the alt_key_table.

Code: Select all
Index: eirid.c
===================================================================
--- eirid.c   (revision 253)
+++ eirid.c   (working copy)
@@ -43,18 +43,21 @@
#include <stdbool.h>

// WDTV IR sensor
-#define CONFIG_TANGO2 1
+#include <linux/autoconf.h>

#ifdef CONFIG_TANGO2
-#include <asm/tango2/tango2_gbus.h>
-#include <asm/tango2/hardware.h>
#include <asm/tango2/ir.h>
#elif defined(CONFIG_TANGO3)
-#include <asm/tango3/tango3_gbus.h>
-#include <asm/tango3/hardware.h>
#include <asm/tango3/ir.h>
#endif

+#ifndef IR_IOCSETRELEASEKEY
+#define IR_IOCSETRELEASEKEY     _IO(IR_IOC_MAGIC, 6)
+#endif
+#ifndef IR_IOCSETALTKEYS
+#define IR_IOCSETALTKEYS        _IO(IR_IOC_MAGIC, 7)
+#endif
+
#include "wdtv_codes.h"
#include "eiri_net.h"
#include "ir_io.h"
@@ -305,6 +308,17 @@
     }
     free(keys);

+    int numaltkeys = 128;
+    unsigned long *altkeys = malloc((numaltkeys + 1) * sizeof(*altkeys));
+    altkeys[0] = numaltkeys;
+    for (i = 0; i < numaltkeys; ++i)
+        altkeys[1+i] = 0;
+    if ((ret = ioctl(native_fd, IR_IOCSETALTKEYS, altkeys)) < 0) {
+        printf("IR_IOCSETALTKEYS error: %s\n", strerror(errno));
+        return 1;
+    }
+    free(altkeys);
+
     int wait = atoi(argv[1]);
     if ((ret = ioctl(native_fd, IR_IOCSETWAITPERIOD, wait)) < 0) {
   printf("2 ioctl error: %s\n", strerror(errno));

This approach is somewhat fragile since the size of the alt_key_table cannot be easily determined by the userspace code. The number 128 is not known outside the kernel module source. A slightly more robust approach would be to repeatedly probe the IR_IOCSETALTKEYS ioctl to initialise an ever increasing number of keys until failure, then use a binary search to narrow in on the exact number of keys.

The dmaosd application must use the same IR_IOCSETALTKEYS ioctl to either program or initialise the alt_key_table, so it might be regarded as a reasonable approach to solve the problem.

I think it would be good to deploy one of these fixes into the next version.
serpens
n00b
 
Posts: 6
Joined: Mon Oct 26, 2015 5:59 am

Re: Unresponsive stock remote when eiri enabled with EIRI='O   

Postby mad_ady » Tue Oct 27, 2015 1:45 am

You know, most first time poster either complain that their moviesheets don't work, or try to sell us fake watches. You, sir, are a breath of fresh air!

Excellent analysis, and I'm glad you have a proposed workaround. I can help you implement it and push a newer firmware.

However, despite my large post counter, I don't have experience with eiri or other remotes and I'll need your help to do most of the work.

Can you try to flash the 1.05 - 0.5.2.2 firmware with 1.03's kernel (for Live?) I wonder if it works out of the box without losing any features (maybe large disks?).

Plan b is to replace irkernel. Which for my is compiled as a module. You can build modules for the WDTV and they should load just fine, the problem is you need an old Linux distro (something like Ubuntu 8.04?) to be able to do the cross-compilation. I will ask recliq for help with this cross-compilation (he had an old environment lying around). Can you prepare a diff that would go into the irkernel.c file so that we can try it?

Also, here's a plan C. Can you try to get irkernel (/lib/modules/2.6.22.19-19-4-orig/irkernel.ko) from 1.02 base and load it into 1.05 kernel? You should be able to use an Ext3 version of the firmware and just overwrite the file. You can get it from here: http://svn.wdlxtv.com/filedetails.php?repname=wdlxtv-live&path=%2Ftrunk%2Flib%2Fmodules%2Firkernel.ko. See if that works without EIRI and with EIRI.

What do you think? I'd try Plan C first - it has high chances of working if the difference is only in there.
User avatar
mad_ady
Developer
 
Posts: 4552
Joined: Fri Nov 05, 2010 9:08 am
Location: Bucharest, Romania

Re: Unresponsive stock remote when eiri enabled with EIRI='O   

Postby serpens » Wed Oct 28, 2015 6:33 am

mad_ady wrote:Can you try to flash the 1.05 - 0.5.2.2 firmware with 1.03's kernel (for Live?) I wonder if it works out of the box without losing any features (maybe large disks?).


This approach might be somewhat fragile since at the very least, it seems fairly certain that dmaosd has some expectation that irkernel has the new functionality. I do note however, that when eiri is enabled, the startup script replaces /dev/ir with a fairly simple proxy, and the system seems to work, but to be honest I doubt I could be 100% sure that nothing is unintentionally crippled.

mad_ady wrote:Plan b is to replace irkernel. Which for my is compiled as a module. You can build modules for the WDTV and they should load just fine, the problem is you need an old Linux distro (something like Ubuntu 8.04?) to be able to do the cross-compilation. I will ask recliq for help with this cross-compilation (he had an old environment lying around). Can you prepare a diff that would go into the irkernel.c file so that we can try it?


I have worked my way along most of this path, but didn't cross the last bridge. What I mean is that I added various amounts of debugging to irkernel.c in order to figure out what was going on, and when I discovered the root cause, I stopped. It would be relatively straightforward to complete the last step and create and apply a patch to irkernel.c.

I did this work on a Fedora 12 system that I have, but only fiddled with the kernel module itself. I didn't try building the entire kernel.

I ran tests with the newly compiled kernel module by shutting down dmaosd and/or eirid, reloading the kernel module, and restarting the programs.

mad_ady wrote:Also, here's a plan C. Can you try to get irkernel (/lib/modules/2.6.22.19-19-4-orig/irkernel.ko) from 1.02 base and load it into 1.05 kernel? You should be able to use an Ext3 version of the firmware and just overwrite the file. You can get it from here: http://svn.wdlxtv.com/filedetails.php?repname=wdlxtv-live&path=%2Ftrunk%2Flib%2Fmodules%2Firkernel.ko. See if that works without EIRI and with EIRI.

What do you think? I'd try Plan C first - it has high chances of working if the difference is only in there.


In my original post, I basically suggested two approaches:
  • Fix irkernel.c
  • Work around the problem in eirid.c

In the options you enumerated, all seem to suggest leaving eirid.c alone, and focusing the effort on the kernel or kernel module.

Given that, I would prefer to just fix the underlying problem in irkernel.c since this approach:
  • Addresses the root cause
  • Leaves everything else alone and reduces the chance of introducing unintentional problems

I'll prepare a patch for the kernel module, compile it and verify that the module works ok on my setup.
serpens
n00b
 
Posts: 6
Joined: Mon Oct 26, 2015 5:59 am

Re: Unresponsive stock remote when eiri enabled with EIRI='O   

Postby serpens » Wed Oct 28, 2015 8:07 pm

serpens wrote:I'll prepare a patch for the kernel module, compile it and verify that the module works ok on my setup.

Here is a patch to the irkernel.c module that corrects the problem. I've verified that it works on my WDTV Live Plus:

Code: Select all
--- irkernel.c.orig   2015-10-28 20:31:50.000000000 -0700
+++ irkernel.c   2015-10-28 20:39:45.000000000 -0700
@@ -883,7 +883,16 @@
#endif //CONFIG_IR_HOLD_KEY
   }
#ifdef   CONFIG_IR_ALT_KEY
-   ir_priv.alt_key_table = kmalloc(max_keys * sizeof(unsigned long), GFP_KERNEL);
+   ir_priv.alt_key_table = kzalloc(max_keys * sizeof(unsigned long), GFP_KERNEL);
+   if (ir_priv.alt_key_table == NULL) {
+      printk(KERN_ERR "%s: out of memory for alt key table\n", ir_devname);
+#ifdef CONFIG_IR_HOLD_KEY
+      kfree(ir_priv.hold_key_table);
+#endif //CONFIG_IR_HOLD_KEY
+      kfree(ir_priv.buffer);
+      kfree(ir_priv.key_table);
+      return(-ENOMEM);
+   }
#endif   // CONFIG_IR_ALT_KEY

   /* Register device, and may be allocating major# */


I put a compiled version of it here: irkernel.ko

md5sum 8c820bc0fefc301ba36a220be1d957f9
sha1sum 6e9f053a29987b8042ac82ac4792461c71b1a95
serpens
n00b
 
Posts: 6
Joined: Mon Oct 26, 2015 5:59 am

Re: Unresponsive stock remote when eiri enabled with EIRI='O   

Postby mad_ady » Thu Oct 29, 2015 12:03 am

Sweet! I will replace the ko in the firmware tree and see if others can try it out. So now, you have EIRI support with other remotes and the original remote as well, right?

Update: Ok, I commited the patched file. I still have something to try and fix before I release a new firmware, but a new firmware should be released by the end of November containing your patch.
User avatar
mad_ady
Developer
 
Posts: 4552
Joined: Fri Nov 05, 2010 9:08 am
Location: Bucharest, Romania

Re: Unresponsive stock remote when eiri enabled with EIRI='O   

Postby serpens » Thu Oct 29, 2015 4:34 am

mad_ady wrote:Sweet! I will replace the ko in the firmware tree and see if others can try it out. So now, you have EIRI support with other remotes and the original remote as well, right?

Update: Ok, I commited the patched file. I still have something to try and fix before I release a new firmware, but a new firmware should be released by the end of November containing your patch.


I have EIRI support, but I'm using the stock remote.

Where do I find the committed wdlxtv kernel sources? I looked on http://svn.wdlxtv.com/, and looked in kernels/ but only found binaries.
serpens
n00b
 
Posts: 6
Joined: Mon Oct 26, 2015 5:59 am

Re: Unresponsive stock remote when eiri enabled with EIRI='O   

Postby mad_ady » Thu Oct 29, 2015 5:27 am

I only commited the compiled kernel module. There is no official repository of kernel sources and mods, mostly because we can't compile a full kernel (no way to sign it).
User avatar
mad_ady
Developer
 
Posts: 4552
Joined: Fri Nov 05, 2010 9:08 am
Location: Bucharest, Romania

Re: Unresponsive stock remote when eiri enabled with EIRI='O   

Postby serpens » Mon Nov 02, 2015 7:11 am

mad_ady wrote:I only commited the compiled kernel module. There is no official repository of kernel sources and mods, mostly because we can't compile a full kernel (no way to sign it).

I looked around for progress on kexec and the most relevant posts I could find were:
The last refers to kexec "not being stable". Do you happen to know which post speaks to the nature of the instability with kexec ?
serpens
n00b
 
Posts: 6
Joined: Mon Oct 26, 2015 5:59 am

Re: Unresponsive stock remote when eiri enabled with EIRI='O   

Postby mad_ady » Mon Nov 02, 2015 11:48 pm

I'm not sure about an actual post, but I remember hearing b-rad on IRC that his last attempts at kexec had everything working except console - when the new kernel booted it would hang when trying to output text via console, or something like this. I never tried it, but you can ask b-rad if you log on to IRC and camp around (he's on a business trip currently but should return next week).
User avatar
mad_ady
Developer
 
Posts: 4552
Joined: Fri Nov 05, 2010 9:08 am
Location: Bucharest, Romania

Re: Unresponsive stock remote when eiri enabled with EIRI='O   

Postby allidea » Fri Jan 08, 2016 1:42 pm

serpens wrote:I put a compiled version of it here: irkernel.ko

md5sum 8c820bc0fefc301ba36a220be1d957f9
sha1sum 6e9f053a29987b8042ac82ac4792461c71b1a95


Any way for *nix n00bs to try this driver without new firmware flash?
Can I do it with rmmod command? Don't want to mess up things too much.
Have a problem? Visit Tweak Master's House Of Useful Tricks.
Ad 1) I tend to find a solution by myself just after I submit a new post asking others to do it for me.
Ad 2) Proud to be *nix n00b - not because I prefer m$, rather I'm trying to get better at it!
allidea
WDTVer
 
Posts: 48
Joined: Wed Dec 22, 2010 4:12 am

Next

Return to WDTV Live

Who is online

Users browsing this forum: No registered users and 2 guests