“Fixing” a buggy Windows driver with a Virtual Machine

Recently, a friend of mine built me a debug cable for the Nexus 4. It turns out that the headphone jack can be turned into a UART cable by applying the right resistance, but that’s a story for another day.

My troubles started as soon as I plugged it in.1-error

So, why is the USB adapter having an existential crisis? The answer seems to be that Prolific really wants you to buy a newer device.

Rebooting into a Linux distro would be an option, but what if you want to work in Windows for whatever reason? There is a “fixed” driver available, but this seems to cause quite a lot of instability for me with BSODs at random intervals.

I knew there was nothing wrong with the device itself, so I turned to virtualization for a solution. VirtualBox has the ability to intercept a USB device on a Windows host and provide it to the guest – but that comes at the cost of the RAM needed to run a whole distro like Debian.

What if I could run just enough to load a USB driver and something like netcat? (which can be used to get data to and from a serial port)

Enter Buildroot. It’s a set of scripts which can build all kinds of embedded system images – it’s most commonly used to build modem filesystems for MIPS and ARM based devices but it can also be used to create images that will work on x86.

I was able to hack a quick version of this together but after talking with people in #buildroot on Freenode, I spent some time learning how to use the build system properly. There’s a way to store all of your configuration changes separately from the buildroot code itself, described in Building Out of Tree in the manual. With a lot of tinkering, I now have a git repo that can be checked out and rebuilt very easily.

I worked on this for about a week and a half and now have an image that can be booted in VirtualBox with the PL2302 drivers loaded automagically. This means I can let VirtualBox take over the serial device and it won’t crash Windows.

I also wrote a script to take an empty image created with dd, partition and format it, then make it bootable with extlinux and add my working kernel/initramfs to it.

When I tested my first versions of this it would boot with about 28mb of RAM allocated to the VM, but let’s say the minimum is 32mb to be safe, which is small enough to be run on my laptop without impacting performance.

Building this system went from a couple of hours work to a week of troubleshooting and asking questions in IRC. It’s probably bigger than my goal now and in retrospect maybe I should have just dual booted to work with the serial converter instead. Although, if I’d done that I wouldn’t know buildroot nearly as well as I know it now.

Linux booting and detecting a USB to serial converter

Picocom and microcom are installed in this tiny system, so before networking it up I tested it out with

microcom -s 115200 /dev/ttyUSB0

and… nothing. Panic – had the soldering on the cable held up to being packed in a suitcase? What had I done wrong? I installed the Windows driver mentioned above and connected via PuTTY – also nothing. Not even line noise at 9600 baud. Just before I was going to give up for the day, I noticed that the Nexus 4 bumper case was stopping the cable going all the way in. With the case gone, the cable and serial adapter worked fine and my job was done.

I haven’t tested multidirectional communication yet, I don’t think the Nexus 4 is accepting input on the UART but the following commands let me connect to 192.168.56.101 on port 1234 and read the console output

stty -F /dev/ttyUSB0 raw
stty -F /dev/ttyUSB0 115200
udhcpc
nc -l -p 1234 < /dev/ttyUSB0

putty

When I’m not writing code or causing trouble, I can be found eating food from The Cinnamon Scrolls

5 thoughts on ““Fixing” a buggy Windows driver with a Virtual Machine

  1. […] [Voltagex] was fed up with BSODs on his Windows machine due to a buggy PL2303 USB/serial device driver. The Linux PL2303 driver worked just fine, though. A weakling would simply reboot into Linux. Instead, [Voltagex] went for the obvious workaround: create a tiny Linux distro in a virtual machine, route the USB device over to the VM where the drive…. […]

    1. No, it’s probably better if Windows doesn’t recognise it. Just add a USB filter in VirtualBox rather than attaching it on the fly.

      You can take my GitHub project and change the kernel config to add your serial driver, then rebuild it.

      Also, if you’re stuck, you can send me the USB VID/PID and I’ll tell you which config option to enable in Linux

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s