Running X86 binaries on armv7

armqemux86

I am trying to run a SNBC USB printer on Raspberry Pi2.

For that I need to copy the filter binary of the SNBC USB printer to /usr/lib/cups/filter. But the filter binary is compiled using a x86 processor (Manufacturer does not have interest to support arm) where as I use armv7. I know it will not work but for a curiosity I tried and cups says /usr/lib/cups/filter/rasterorp3150 failed.

I looked for solutions on the internet and people suggest to use Qemu. But it is for a complete x86 to arm platform. Is there a way to convert the x86 binary to arm binary in a easy uncomplicated way?

By the way, is converting the x86 binary using a hexedit tool to an equivalent armv7 binary a good idea? (opcode conversion)

If so, can anyone give some idea on how to do it?

Best Answer

You can't easily convert an x86 binary to ARM. If you can't get the source code, or an ARM binary from the manufacturer, and you really do want to use the printer with your Pi2, then the Qemu approach is the correct one in this case, although it will likely be very slow. Qemu does full system emulation but it also works very well for single process emulation.

I'm assuming you have some sort of Debian derivative on your Pi2 (I'm not sure this will work with Raspbian though), and that the binary you have is for i386 (if it's 64-bit, use amd64 instead). Start by adding i386 as a foreign architecture:

sudo dpkg --add-architecture i386
sudo apt-get update

Then run ldd on the binary and add any required libraries; typically

sudo apt-get install libc6:i386

and anything else with the :i386 suffix added. Make sure this doesn't remove any installed package; hopefully everything you need is multiarch-enabled. (Otherwise the rest won't work.)

Once you've done that, install qemu-user-static if it isn't already installed (along with its binfmt-support recommendation); then you can use qemu-i386-static to run your program:

qemu-i386-static /usr/lib/cups/filter/rasterorp3150

In fact thanks to binfmt-support it should run directly (as pointed out by Toby Speight):

/usr/lib/cups/filter/rasterorp3150

(binfmt-support will use Qemu to make this work transparently.)

If you don't want to use binfmt-support, move rasterorp3150 away:

sudo mv /usr/lib/cups/filter/rasterorp3150 /usr/lib/cups/filter/rasterorp3150.x86

and install a script containing

#!/bin/sh
exec qemu-i386-static /usr/lib/cups/filter/rasterorp3150.x86 "$@"

as /usr/lib/cups/filter/rasterorp3150.

If you'd rather you can set up a chroot for all this; see debootstrap and its --foreign option (the chroot can be set up to use Qemu automatically).

Related Question