Android Emulator Development, Anbox, & Waydroid

Beyond TCP/IP: ADB Debugging Virtual Android via Direct USB Passthrough (QEMU/KVM)

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction: The Limitations of Network ADB and the Power of Direct Passthrough

Debugging Android devices running in virtualized environments, such as QEMU/KVM, Anbox, or Waydroid, often defaults to network-based Android Debug Bridge (ADB) connections. While functional, TCP/IP ADB connections can introduce latency, instability, and a lack of direct low-level access crucial for intricate debugging tasks. This guide delves into an advanced technique: directly passing through a physical USB Android device to your virtualized Android instance using QEMU/KVM. This method offers superior performance, enhanced reliability, and opens the door to debugging scenarios typically reserved for physical hardware, such as USB accessory mode and more robust debugging of kernel-level interactions.

Prerequisites for Direct USB Passthrough

Before we begin, ensure your host system and virtual machine environment are correctly configured. This tutorial assumes a Linux host with QEMU/KVM and libvirt installed.

Software Requirements:

  • Host OS: A Linux distribution (e.g., Ubuntu, Fedora, Arch Linux).
  • Virtualization: QEMU/KVM with libvirt for VM management.
  • ADB: Android Debug Bridge installed on your host system (android-tools-adb package).
  • USB Utilities: usbutils (for lsusb) and udev (for permissions).

Hardware Requirements:

  • A physical Android device (phone, tablet, development board) to be passed through.
  • Your host PC running the QEMU/KVM virtual machine.
  • The virtualized Android environment (e.g., a custom Android x86 VM, Anbox, Waydroid).

Understanding USB Passthrough in QEMU/KVM

QEMU/KVM offers robust USB device passthrough capabilities. Unlike simply forwarding USB traffic over the network, direct passthrough essentially detaches the physical USB device from the host and attaches it directly to the virtual machine. The guest OS then interacts with the device as if it were natively connected to its own USB controller. This requires identifying the device by its Vendor ID (VID) and Product ID (PID).

Step 1: Identify Your Android Device’s USB IDs

First, connect your Android device to your host machine via USB. Ensure it’s in USB debugging mode if prompted. Then, open a terminal on your host and use the lsusb command to list all connected USB devices. Look for an entry corresponding to your Android device.

$ lsusb

The output will resemble something like this:

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching HubBus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hubBus 002 Device 002: ID 04e8:6860 Samsung Electronics Co., Ltd Galaxy (MTP)

In this example, 04e8:6860 represents the Vendor ID (VID) and Product ID (PID) of the Samsung Galaxy device. Make a note of these IDs for your device.

Step 2: Configure QEMU/KVM for USB Passthrough via Libvirt

The recommended and most manageable way to configure USB passthrough for QEMU/KVM guests is through libvirt. We’ll modify the virtual machine’s XML configuration.

  1. List your VMs:

    $ virsh list --all

    Identify the name of your virtualized Android VM (e.g., android_x86_vm).

  2. Edit the VM’s XML configuration:

    $ virsh edit android_x86_vm

    This will open the XML configuration in your default editor. Scroll down to the <devices> section. We need to add a <hostdev> entry.

  3. Add the USB device configuration:
    Inside the <devices> tag, add the following, replacing vendor='0x04e8' and product='0x6860' with your device’s actual VID and PID:

    <hostdev mode='subsystem' type='usb'>  <source>    <vendor id='0x04e8'/>    <product id='0x6860'/>  </source>  <address type='usb' bus='0' port='1'/></hostdev>

    The <address> tag is important. If you have multiple USB devices, adjust the port attribute (e.g., port='2') or simply omit the <address> tag, and libvirt will assign one. Save and exit the editor.

  4. Restart your VM:

    $ virsh shutdown android_x86_vm$ virsh start android_x86_vm

    The device should now be available inside your VM.

Alternative: Raw QEMU Command Line (Less Recommended for Permanent Setups)

If you’re launching QEMU directly without libvirt, you can add the USB device with a command-line argument:

$ qemu-system-x86_64 ... -usb -device usb-host,vendorid=0x04e8,productid=0x6860 ...

Step 3: Handle USB Device Permissions (udev Rules)

Often, non-root users lack direct access to USB devices. To avoid running QEMU or libvirt commands as root, which is a security risk, we’ll create a udev rule to grant proper permissions.

  1. Create a new udev rule file:

    $ sudo nano /etc/udev/rules.d/51-android.rules
  2. Add the rule:
    Insert the following line, again replacing idVendor and idProduct with your device’s IDs. Replace <your_username> with your actual Linux username, or use MODE=

    Android Mobile Specs & Compare Directory

    Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!

    Compare Devices Specs →
Google AdSense Inline Placement - Content Footer banner