Skip to content

Instantly share code, notes, and snippets.

@Alabate
Last active June 20, 2023 10:48
Show Gist options
  • Save Alabate/200f021e644baed84993dd6109811ba2 to your computer and use it in GitHub Desktop.
Save Alabate/200f021e644baed84993dd6109811ba2 to your computer and use it in GitHub Desktop.
Use custom USB device with Android emulator by using custom built kernel on Ubuntu 18.04

Use custom USB device with Android emulator by using custom built kernel on Ubuntu 18.04

The android emulator doesn't support all usb devices because they are disabled in the kernel. So we need to build it with another configuration. My goal was to build the same version as it was before, but with just configuration modifications.

Find current android version

Start the emulator without modifications, go into

Configuration > System > About emulated device > Android version

Then note the following informations:

  • Android version: 9
  • Kernel version: 4.4.124+
  • Build date: Mon Jun 18

We will use those informations later

Get sources and move to the right commit

# First we need to get prebuilt of gcc toolchain for x86_64 arch
# I've took the most recent version of x86_64-linux-android gcc prebuilt
# You can go here to see the list of versions: https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/x86/
git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9
cd x86_64-linux-android-4.9
# Show list of available tags
git tag
# I choose the most recent that matched my android version
git checkout android-9.0.0_r49
cd ..

# Then we need to clone the kernel sources
# Goldfish is the name of the kernel for android emulator
# We have to choose the branch in the list found here https://android.googlesource.com/kernel/goldfish
# I choosed `android-goldfish-4.4-dev` because we are on linux 4.4
git clone https://android.googlesource.com/kernel/goldfish/ -b android-goldfish-4.4-dev
cd goldfish
# To show the list of commits in this branch
git log --pretty=format:"%H %ad: %s"
# I choosed the one that was just before the build date (commit named 4.4.124 didn't work)
git checkout f41f5aa46e3076e17e5f1eea5b0a879e3a383ac4

Configure it

# Generate default configuration
make x86_64_ranchu_defconfig
# Open the menu to edit the configuration
make menuconfig
# In our case we wanted to enable USB ACM devices, so I enabled
# Device Drivers > USB Support > USB Modem (CDC ACM) support
# Note: Press space to enable it until you have a star
# Then save and exit

Build it

# Ensure you are at the root of the goldfish directory
cd goldfish
# We need to add some variables to our env
# Please edit the line of the path if you cloned x86_64-linux-android-4.9 somewhere else
export CROSS_COMPILE=x86_64-linux-android-
export ARCH=x86_64
export PATH=$PATH:$(pwd)/../x86_64-linux-android-4.9/bin
# Then start the build with 8 cpu
make -j8
Hopefully this will succeed

Permission to access the device

# First you need to add an udev rule to allow your user to access the usb device
# As you use android emulator, I suppose your user is in the `kvm` group. You can check if it is by doing
groups
# If you are not in the kvm group you can add yourself in it by doing
sudo usermod -aG kvm ${USER}
# Find the VendorId and ProductId of your usb device
lsusb
# Bus 001 Device 004: ID 1546:000b U-Blox AG
# We know our VendorId is 1546 and productId 000b
# We add an udev rule to configure group for our device
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="1546", ATTRS{idProduct}=="000b", GROUP="kvm"' | sudo tee /etc/udev/rules.d/99-usb-android.rules
sudo udevadm control --reload-rules
# Unplug and replug your device before continuing

Start the emulator with the custom kernel and the custom device

emulator @MappingDevice -writable-system -no-snapshot -show-kernel -verbose -kernel arch/x86/boot/bzImage -qemu -usb -device usb-host,vendorid=0x1546
# -writable-system: Needed for next section, to enable usb api.
# -no-snapshot: Disable fast boot to ensure a full reboot. You can remove this once everything works
# -show-kernel -verbose: Enable debugging log, can be remove once everything works
# -kernel arch/x86/boot/bzImage: Select built kernel
# -qemu -usb -device usb-host,vendorid=0x1546,productid=0x000b: Qemu parameters to forward usb device

# Hopefuly it will boot :)

# Check if your device is loaded by linux in the emulator
adb root
adb shell
# Once you're inside the shell you can check various places for your device
ls /dev
lsusb
dmesg

Enabling the USB API

By default the usb API is disabled on android emulator. We need to enabled it by writing a file in /system/etc/permissions.

# Start the emulator with the -writable-system option
adb root
adb remount # Remount filesystem in write mode
adb shell
echo '<permissions><feature name="android.hardware.usb.host"/></permissions>' > /system/etc/permissions/android.hardware.usb.host.xml

Then restart your device and you should now see your device in the usb API

@zangtian2
Copy link

zangtian2 commented Mar 15, 2020

Thank you very much.Follow your steps,Succeed。
Another question,in this way ,could i connect success with AOA?
i connect a android phone as a accessory..but it failed,

qemu-system-x86_64: libusb_set_configuration: -6 [BUSY]
[  208.677717] usb 1-1: can't set config #1, error -32

@pablo-souza
Copy link

pablo-souza commented May 10, 2021

@zangtian2 any answer?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment