Dario Scarpa, TOo BUsy TO Mantain A BLOg

Binary Patching the Razer Atrox Linux Driver

…or “how I got Retropie to handle all the 10 buttons of the Razer Atrox changing a bit in xpad.ko”.

What does a videogame programmer on vacation? Well, many things, actually, but to somehow stick to stereotypes, he surely must *play* some videogames, too.

the Razer Atrox connected to Raspberry Pi running RetroPie

So, recipe:

a Raspberry PI sitting in a drawer since months

the Razer Atrox fight stick, bought on sale and sitting in another drawer since then

the amazing RetroPIE SD image and some childhood game ROMs

Result:

all working in a very straightforward way, EXCEPT for the fact that during the input configuration, only six of the main eight buttons worked (the top ones, because the Atrox also features two side buttons, “start” and “select”, that were working).
The buttons that didn’t work were the ones labeled LT and RT (Left Top and Right Top).

After excluding the chance of a hardware problem (trying the joystick under Windows), I decided that it was a driver issue… probably a simple one: 8 buttons out of 10 were working already, after all.

So, listing the loaded kernel modules and through quick Googling I found out that the code handling the joystick was
in xpad.c, and in a few minutes of code analysis I noticed that the two buttons not working were handled by this code block, only if the xpad->mapping field was set to MAP_TRIGGERS_TO_BUTTONS:

So, the fix looked to be setting the proper flag (MAP_TRIGGERS_TO_BUTTONS) into the mapping field of the Razer Atrox definition in the xpad_device array of structs, that is a series of definitions used to tune the driver behaviour according to the detected hardware.

Another hint of that was that some similar fight sticks had the mapping field set to MAP_TRIGGERS_TO_BUTTONS, while the Razer Atrox didn’t:

I didn’t want to recompile the whole kernel, but only the xpad module. The process didn’t look totally straightforward, because Retropie was using a custom kernel image, and not the one distributed through APT (that would have made things easier).
The process was made harder by the lack of a proper Internet connection (due to my vacation setting: I only had available an unrealiable 3G connection accessed through wi-fi tethering).

So, after considering that if I was right I only had to change a byte in that struct array, I opted for the binary patching approach.
The C structs are usually compiled to the binaries in very simple and predictable way, and this wasn’t an exception: after a couple of two-bytes fields (idVendor and idProduct), we have a pointer to the name string constant describing the model (4 bytes on 32 bit ARM), and after that two one-byte fields, mapping and xtype, the first of which contains the value we need to change.

...meaning that we're looking for a byte with value 0x00 in the original definition, and we need to change it to 0x02 (that is, 1 << 1).

The two bytes fields used for identification, 0x24c6 and 0x24c6, are a perfect candidate to search into the binary, after remembering to fix the byte ordering field by field: 0x24c6 gets compiled to C6 04 and 0x5000 to 00 50.

After firing and hex-editor on my version of xpad.ko, and searching for the hex string C6 24 00 50, I found out the binary translation of the Razer Atrox definition at offset 1CA8:

I did the simple modification with an hex-editor, replaced the original xpad.ko file with the patched one (in /lib/modules/3.18.11+/kernel/drivers/input/jostick/), rebooted, and the Razer Atrox buttons were all working nicely.