• Introducing XDA Computing: Discussion zones for Hardware, Software, and more!    Check it out!

[GUIDE] Build / Mod AVD Kernel Android [10] [11] [12] rootAVD [Magisk] [USB passthrough] [Linux] [Windows] [Google Play Store API]

Search This thread

newbit

Senior Member
Nov 16, 2008
178
69
Hello Fellows,

with this Guide I would like to show what is necessary to do,
to get the new USB passthrough Feature,
from the Android Studio since Emulator 30.0.26 (August 16, 2020),
to work with a USB-Serial Device. Unfortunately the announcement "USB passthrough is now available"
needs to be taken literally. It means, just the passing from the host system to the gates of Android are possible.
There is no "taking it from there" implemented in Android nor the Kernel. And this is what this Guide is all about.
Inspired by Alabate and his Guide Use custom USB device with Android emulator by using custom built kernel on Ubuntu 18.04
Three basic steps needed to be done.

[Update 04.05.2021]
A much more easier and reliable way on how to build, mod and update your AVDs Kernel with its modules,
can be found in my [GUIDE] by using the official AOSP Build ENV.
  1. Build the AVD Kernel with the right check at the right place
  2. Convince Linux to actually let go of the USB-Serial Device
  3. Grant Permissions in Android to acknowledge the new plugged in Device
The Development Environment:
1. Build the AVD Kernel with the right check at the right place

### From the shell with the AVD running we can get some Kernel Infos:
uname -r && uname -v 4.14.175-g6f3fc9538452 #1 SMP PREEMPT Wed Apr 8 17:38:09 UTC 2020

### Install the following tools to work with and to build the kernel:
sudo apt-get install -y build-essential libssl-dev kernel-package libncurses5-dev bzip2 lib32z1 bison flex sudo apt-get install -y libelf-dev libelf-devel or elfutils-libelf-dev sudo apt-get install -y qt5-default qttools5-dev-tools qttools5-dev sudo apt-get install -y geany git

### Create a working directory and download the kernel source and its prebuilt gcc:
I choose the latest android-10.0.0_r47 branch and its prebuilt gcc 4.9
Code:
cd ~/ && mkdir avdkernelcompile && cd avdkernelcompile
git clone \
    -b android-10.0.0_r47 \
    --single-branch https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9

I also choose the mainline android-goldfish-4.14-dev branch from the goldfish kernel source
Code:
git clone -b android-goldfish-4.14-dev --single-branch https://android.googlesource.com/kernel/goldfish

### Pull the config.gz from the AVD to generate and merge the kernel defconfigs file:
These steps lower the risk of getting build errors. And before you mod the kernel, it could
make sense to start with a build kernel that actually boots your AVD first, and then apply changes to it.
Code:
adb pull /proc/config.gz
gunzip -k config.gz
cd goldfish
cp ../config .config
make savedefconfig
mv defconfig arch/x86/configs/avd_pulled_defconfig
rm .config
./scripts/kconfig/merge_config.sh -m \
    ./arch/x86/configs/avd_pulled_defconfig \
    ./arch/x86/configs/x86_64_ranchu_defconfig
make savedefconfig
mv defconfig arch/x86/configs/merged_avd_pulled_defconfig
rm .config

### prepare the kernel with the gcc to be build:
we are now in the goldfish directory
exports must be done every time you open a new terminal
export CROSS_COMPILE=x86_64-linux-android- export ARCH=x86_64 export PATH=$PATH:$(pwd)/../x86_64-linux-android-4.9/bin

make the just created defconfig file
make merged_avd_pulled_defconfig

If you come back here later, this is the right place to mod your kernel.
I like the GUI Interface because you have a better overview and a search function.
make xconfig

In order to get the USB-Serial recognized by the kernel, make sure the UHCI HCD is checked.
You can find it under: Device Drivers -> USB support -> UHCI HCD (most Intel and VIA) support
UHCI_HCD.png

Close and save it.

### build the actually kernel, with the all CPU cores you have, and see afterwards how long it took:
time make -j$(nproc)

The new kernel is placed in:
~/avdkernelcompile/goldfish/arch/x86/boot/bzImage
We leave it there for now. If you are planing to make changes when all is working so far, just jump
to make xconfig . The build time now is much smaller now. If you have to start over,
you can run make mrproper

### Start the AVD with the new kernel from via terminal
To be able to start the emulator and adb from everywhere, add those path in your ~/.bashrc
echo export PATH=~/Android/Sdk/platform-tools:$PATH >> ~/.bashrc echo export PATH=~/Android/Sdk/emulator:$PATH >> ~/.bashrc source ~/.bashrc

run the new kernel with:
Code:
emulator \
    -netdelay none -netspeed full -avd Pixel_4_XL_API_29 \
    -writable-system -no-snapshot-load \
    -show-kernel \
    -verbose \
    -ranchu \
    -kernel ~/avdkernelcompile/goldfish/arch/x86/boot/bzImage
If the kernel works proper, you can run the AVD with this even after a Wipe Data from the AVD Manager
Later on, you can get rid of the show-kernel, verbose and ranchu option. If the kernel boots and you
can work with the AVD for your satisfaction, it is time for the mod and the next step.

2. Convince Linux to actually let go of the USB-Serial Device
According to the Emulator Release Notes, one would just need the vendorID and productID from the desired USB Device to pass it through. These are easily obtained by:
lsusb Bus 002 Device 009: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

To start the AVD with it, and you leave out the verbose stuff, the command changes to:
Code:
emulator \
    -netdelay none -netspeed full -avd Pixel_4_XL_API_29 \
    -writable-system \
    -no-snapshot-load \
    -kernel ~/avdkernelcompile/goldfish/arch/x86/boot/bzImage \
    -qemu -usb \
    -device usb-host,vendorid=0x067b,productid=0x2303

If you keep watching the terminal, you can see the error message:
libusb: error [get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/043, errno=13 libusb: error [get_usbfs_fd] libusb requires write access to USB device nodes
Now to convince Linux to let go of the USB-Serial Device, one must create an UDEV Rule.
You can do this even while the AVD is running an the USB-Serial Device is connected:
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", OWNER="libvirt-qemu", GROUP="kvm"' | sudo tee /etc/udev/rules.d/99-usb-android.rules
After this echo command, watch while you unplug and plug it, you will only see the Info Message:
libusb_release_interface: -4 [NO_DEVICE]
And if you also watching the AVD with:
adb root adb shell dmesg | grep usb
You will see that the kernel is already recognizing it.
[ 619.670306] usb 1-1: new full-speed USB device number 6 using uhci_hcd [ 620.071451] usb 1-1: New USB device found, idVendor=067b, idProduct=2303 [ 620.073050] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 620.074698] usb 1-1: Product: USB-Serial Controller [ 620.075872] usb 1-1: Manufacturer: Prolific Technology Inc.

Btw: If you also want to use this USB-Serial Device without access issues in other tools, for example CoolTerm,
just copy the line from the udev rule and change the SUBSYSTEM to tty.
SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", OWNER="libvirt-qemu", GROUP="kvm"

Side Note: Under Mac OS you will get a similar libusb: error, but unlike Linux, there is no UDEV System, so you
cannot change this situation at all. Also not by unloading a kext. I tried, even with EL Capitan where you actually
still could unload kexts very easily. So this just "prooves" that the Google Developers, never tried to pass an USB
through - even if they hinted it: (This should also have been workng on Linux and macOS already) And it is even
worst, there is actually a very convenient feature built in QEMU, with the -serial keyword, you can attach such devices
in no time. But for some reason, EXACTLY this feature is taken out from the Google Developers - what a bummer.

3. Grant Permissions in Android to acknowledge the new plugged in Device
With the kernel recognizing the USB-Serial Device and Linux let us acces it, the AVD just doesn't know what
to do with it. Or rather, it doesn't have permissions to proceed. To grant these permissions, one must simply
place a file, with this permissions, called android.hardware.usb.host.xml in /system/etc/permissions or
in /vendor/etc/permissions.

For both places we need not only root but also write access to it. Google Play AVD Images can be rooted, with my
rootAVD script, but these partitions can't remounted as writeable, no matter what. At least, not with my skills.


AVD Images with Google APIs on the other hand are capable of beeing rooted and writeable out of the box.
Actually, just the overlay paritions can be writeable. To achive this, one must start the AVD with the -writable-system
option. What we already doing all the time.

When the AVD is up, go with the ADB commands one by one:
adb root adb shell avbctl disable-verification adb disable-verity adb reboot adb root adb remount adb shell

Every command must show a positive result, if you stuck in a bootloop or so afterwards,
one of the two disable commands didn't work. Start over with a Wipe Data.
Once the remount command shows remount succeeded you are good to go.

In the adb shell:
echo '<permissions><feature name="android.hardware.usb.host"/></permissions>' > /system/etc/permissions/android.hardware.usb.host.xml chmod 644 /system/etc/permissions/android.hardware.usb.host.xml reboot

After the Reboot, plug in your USB-Serial Device, and If you have Serial USB Terminal installed.
it will finally pop up a message.

Screenshot_1609712935.png
If you have USB Device Info installed, It will even show more informations.

Screenshot_1609712974.png Screenshot_1609712976.png Screenshot_1609712981.png

If I disable USB Debugging, the 0000 Device will disappear.

That's it for now. The USB Passthrough for USB-Serial Devices can work.
I am currently working on a way to get a mass storage mounted in the AVD.
But I can't figure out the right fstab.ranchu entry for the AVD to auto mount my USB Storage.
I could get the kernel to recognize it:
[ 28.090063] usb 1-1: new full-speed USB device number 2 using uhci_hcd [ 28.491686] usb 1-1: not running at top speed; connect to a high speed hub [ 28.499738] usb 1-1: config 1 interface 0 altsetting 0 endpoint 0x2 has invalid maxpacket 512, setting to 64 [ 28.501413] usb 1-1: config 1 interface 0 altsetting 0 endpoint 0x81 has invalid maxpacket 512, setting to 64 [ 28.515287] usb 1-1: New USB device found, idVendor=1f75, idProduct=0917 [ 28.516925] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 28.518772] usb 1-1: Product: PenDrive [ 28.519699] usb 1-1: Manufacturer: Innostor [ 28.522417] usb 1-1: SerialNumber: 000000000000000071 [ 28.526804] usb-storage 1-1:1.0: USB Mass Storage device detected [ 28.528787] scsi host0: usb-storage 1-1:1.0 [ 29.962957] usb 1-1: reset full-speed USB device number 2 using uhci_hcd
But it keeps getting repeated with the last line
It also does show up as block device in:
brw------- 1 root root 8, 0 2021-01-03 23:49 sda
But without sda1, just sda. And the USB Stick was formated via SDCARDFS in a real phone.

Update 06.01.2021:
Modding the Kernel with USB Mass Storage and SCSI support

In order to get an USB Stick announced by the kernel as block device node, one must
activate some additional Supports in the Kernel Config.
  • Device Drivers
    • SCSI device support
      • SCSI device support
      • SCSI disk support
    • USB support
      • USB Mass Storage support
        • USB Attached SCSI
ksnip_20210106-211835.png ksnip_20210106-211955.png
With these additional features, the kernel is providing the pluged USB Stick under
/dev/block/sd which is needed to get the fstab.ranchu able to pick it up.

Once the kernel is complete, one must tell Qemu where it is supposed to plug in the USB Stick.
This is done with the -device and USB type options:
Code:
    -device usb-ehci,id=ehci \
    -device usb-host,bus=ehci.0,vendorid=0x8564,productid=0x1000

The EHCI (USB 2.0) driver support is already build in the stock kernel, so if you device can be
"downsqeezed" you can tell it Qemu with these words. Use the device usb.ehci, identify it for me as ehci, and attach my VendorID and ProductID to your usb-host bus ehci.0
(ehci in qemu provides 8 USB ports) With this way, you can also attach multiply USB Devices to the same AVD.
Code:
    -device usb-ehci,id=ehci \
    -device usb-host,bus=ehci.0,vendorid=0x8564,productid=0x1000 \
    -device usb-host,bus=ehci.0,vendorid=0x1f75,productid=0x0917

Screenshot_1609965879.png ksnip_20210102-225748.png

If you have added USB 3.0 support in your kernel already, you can even use the XHCI driver.
Code:
emulator \
    -netdelay none -netspeed full -avd Pixel_4_XL_API_29 \
    -writable-system -no-snapshot-load \
    -kernel ~/avdkernelcompile/goldfish/arch/x86/boot/bzImage \
    -qemu -usb \
    -device usb-ehci,id=ehci \
    -device usb-host,bus=ehci.0,vendorid=0x8564,productid=0x1000 \
    -device qemu-xhci,id=xhci \
    -device usb-host,bus=xhci.0,vendorid=0x1f75,productid=0x0917

And with the fstab.ranchu correctly tuned, both USB Stick will pop up systemwide for every app to use.

Screenshot_1609965998.png Screenshot_1609966012.png Screenshot_1609966074.png

Modding the fstab.ranchu
Without
Magisk on the AVD installed, you can very easly edit the
/vendor/etc/fstab.ranchu just in the adb remounted overlay partitions.
Add this line to it:
/devices/*/block/sd* auto auto defaults voldmanaged=usb:auto

With Magisk on the AVD installed, it gets messy. Due to the fact, that Magisk is mounting a mirror of the orignal read-only partitions, some changes can't be done like before. The only way I could figure out was
to add the fstab.ranchu in my ramdisk.img and let Magisk overlay it during boot time.
Root Directory Overlay System
For this you can use my script rootAVD.sh

Code:
# Set PATCHFSTAB=true if you want the RAMDISK merge your modded fstab.ranchu before Magisk Mirror gets mounted
PATCHFSTAB=false
#PATCHFSTAB=true
# cp the read-only fstab.ranchu from vendor partition and add usb:auto for SD devices
# kernel musst have Mass-Storage + SCSI Support enabled to create /dev/block/sd* nodes
...

How to root the AVD and patch fstab.ranchu:

The script runs in Linux, Darwin MacOS and Windows. It needs the path to the ramdisk.img of the system-image as a parameter.
The AVD needs to be running and accessible via adb shell.
Then just run it and restart, NOT adb reboot, your AVD. It works with
Android 7, Android 10 and Android 11. But not with Android 8 and Android 9.
It also copys every .apk within the Apps Folder to the AVD.
./rootAVD.sh ~/Android/Sdk/system-images/android-30/google_apis_playstore/x86_64/ramdisk.img

To get the fstab.ranchu patched, set PATCHFSTAB=true, make some adjustments, and let the rootAVD script run.

Miscellaneous:
Special Cherrys for Googe Play Store AVD with Stock Kernel:

The EHCI USB Driver is already implemented in the Stock Kernel, even in the Google Play Version AVD.
By adding the android.hardware.usb.host.xml file to its rightful place, a well
written App, like X-plore File Manager, could use its own USB-Driver to access the USB Storage.

Screenshot_1609879051.png

But how to get it there? Once Magisk is installed via the rootAVD script. Which are basicly the
original scripts from Magisk, just a bit tuned. You can install my Magisk Module: usbhostpermissons

Don't forget to start the AVD with usb-ehci command. The USB Stick won't pop up systemwide,
but you can still use them within X-plore and copy & paste files with it.

Replace the emulator with a script to pass arguments and run it from the GUI:

Code:
mv ~/Android/Sdk/emulator/emulator ~/Android/Sdk/emulator/emulator-original
cat <<EOF > ~/Android/Sdk/emulator/emulator
#!/bin/bash
~/Android/Sdk/emulator/emulator-original \[email protected] \
    -writable-system -no-snapshot-load \
    -kernel ~/avdkernelcompile/goldfish/arch/x86/boot/bzImage \
    -qemu -usb \
    -device usb-ehci,id=ehci \
    -device usb-host,bus=ehci.0,vendorid=0x8564,productid=0x1000 \
    -device qemu-xhci,id=xhci \
    -device usb-host,bus=xhci.0,vendorid=0x1f75,productid=0x0917 \
    -device usb-host,bus=usb-bus.0,vendorid=0x067b,productid=0x2303
EOF
chmod +x ~/Android/Sdk/emulator/emulator

If you have your original emulator file renamed, don't forget to change it when you are
calling it manual from the command line.

[Update 15.12.2021]
For Windows Only.

Since Emulator Version 31.1.4, Google re-implemented the USB pass through feature along with
some tools:
and emulator parameters:
The Windows drivers must be installed from an Adminstrator Command Shell
Code:
Install_Drivers.bat
Installing Android USB Assistant...
call Android_USB_Assistant_Install.bat
Microsoft PnP Utility

Processing inf :            Android_USB_Assistant.inf
Successfully installed the driver.
Driver package added successfully.
Published name :            oem89.inf


Total attempted:              1
Number successfully imported: 1

Installing Android Emulator USB Passthrough Assistance Driver

SERVICE_NAME: UsbAssist
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
[SC] DeleteService SUCCESS

SERVICE_NAME: UsbAssist
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 0
        FLAGS              :

Find your connected USB Devices
Code:
emulator -list-usb
VID:PID 058f:6387 (Bus 1, Port 5.1.1)
        Manufacturer:
        Product:
        SerialNumber:   40A0FE0A

VID:PID 067b:2303 (Bus 1, Port 5.1.2)
        Manufacturer:   NA
        Product:        NA
        SerialNumber:   NA

VID:PID 0403:6001 (Bus 1, Port 5.1.2)
        Manufacturer:   FTDI
        Product:        USB-to-Serial
        SerialNumber:   FT9QIQ6Y

VID:PID 1bcf:284c (Bus 1, Port 5.1.2)
        Manufacturer:   SunplusIT Inc
        Product:        5MP USB webcam
        SerialNumber:   N2020040701

Now you can use those VID : PID combination to pass it through your AVD
Code:
emulator -netdelay none -netspeed full -avd Pixel_4_API_3 -usb-passthrough vendorid=0x058f,productid=0x6387

Multible VID : PID combinations are also possible
Code:
emulator -netdelay none -netspeed full -avd Pixel_4_API_32 -usb-passthrough vendorid=0x058f,productid=0x6387 -usb-passthrough vendorid=0x067b,productid=0x2303

Unfortunately the emulator will show this Error:
Code:
qemu-system-x86_64.exe: libusb_kernel_driver_active: -12 [NOT_SUPPORTED]
But the Devices are still passed through.
They will not be shown in the AVD nor recognized as a Device in any way.
In order to accomplish this, you must:
  • root the AVD with Magisk (Canary for 64-Bit only AVDs)
  • patch the FSTAB to get USB Drives automaticly mounted as a drive
  • install my USB Host Permissions Magisk Module
This can be done by:
Code:
rootAVD.bat %LOCALAPPDATA%\Android\Sdk\system-images\android-32\google_apis_playstore\x86_64\ramdisk.img PATCHFSTAB GetUSBHPmodZ

The Magisk Module will be put into the local Download folder of the AVD.

AVDs with a Kernel Version lower then 5.4.65 need either a custom build kernel with the
USB features enabled or an updated prebuild Kernel directly from the AOSP.
Code:
rootAVD.bat %LOCALAPPDATA%\Android\Sdk\system-images\android-30\google_apis_playstore\x86_64\ramdisk.img InstallPrebuiltKernelModules PATCHFSTAB GetUSBHPmodZ

Thanks for reading
Cheers NewBit


Thanks and Credits to @topjohnwu , Alabate, Google, Qemu and Jitendra

QEMU/Devices/USB/Root
USB Quick Start
USB recommendations for qemu
qemu usb storage emulation
 
Last edited:
  • Like
Reactions: adeii

tomek_be

New member
Feb 18, 2021
3
0
I did but with no luck. Emulator correctly creates USB controller and /sys/kernel/debug/usb/devices contains entries corresponding with command line options but passthrough USB device is not discovered by the kernel. Sometimes emulator produces message on stdout that devices has been attached or detached but it is not repeatable. I tried different hardware accelerations ( HAXM and WHPX ) - nothing . BTW - on linux it worked like a charm - only thing I need to do was creating proper /system/etc/permissions/android.hardware.usb.host.xml. After that non modified kernel picked up usb device.
 

newbit

Senior Member
Nov 16, 2008
178
69
I did but with no luck. Emulator correctly creates USB controller and /sys/kernel/debug/usb/devices contains entries corresponding with command line options but passthrough USB device is not discovered by the kernel. Sometimes emulator produces message on stdout that devices has been attached or detached but it is not repeatable. I tried different hardware accelerations ( HAXM and WHPX ) - nothing . BTW - on linux it worked like a charm - only thing I need to do was creating proper /system/etc/permissions/android.hardware.usb.host.xml. After that non modified kernel picked up usb device.
Weird, I still don't get any notice.

So you did try it on Linux with Stock Kernel and permission xml file!? -> it worked
You also tried the same thing on Windows? -> it didn't worked
Is it the same/similar AVD version? Is the syntax on windows different? What commands did you use exactly?
Is your AVD rooted? Did you cross compare the Kernel Configs? Kernel Versions?
What USB Device exactly you are trying to pass through?
 

newbit

Senior Member
Nov 16, 2008
178
69
Hello fellows, Did you find the way to make it work in Windows ?, It's hard to create apps that need interaction with USB / Bluetooth devices under Windows environment !, I wonder why these guys at Google make it so hard ?
It was actually already solved, the same way like on linux. But Google
decided to take out the USB Pass Through Feature on Windows.

Android emulator USB passthrough fails: " 'usb-host' is not a valid device model name"

So the only chance would be to get back to Version 30.5.2 (build_id 7175973) (Feb 27, 2021) to try it out.
 

newbit

Senior Member
Nov 16, 2008
178
69
what's wrong with Google ?
I've stopped wondering since they put this sneaky covid "feature" undetected on my phone.

Hard to develop apks that need to cope with USB or BT in Windows machines
Yes, totally. But Microsoft is to blame as well, according to Erwin Jansen.
I guess you need to remotely debug your apk directly on your phone/device.

Thanks for your information buddy !
No problem, If there is any USB update in the Windows Version, I am happily updating this Guide.
 

Top Liked Posts

  • There are no posts matching your filters.
  • 1
    Hello Fellows,

    with this Guide I would like to show what is necessary to do,
    to get the new USB passthrough Feature,
    from the Android Studio since Emulator 30.0.26 (August 16, 2020),
    to work with a USB-Serial Device. Unfortunately the announcement "USB passthrough is now available"
    needs to be taken literally. It means, just the passing from the host system to the gates of Android are possible.
    There is no "taking it from there" implemented in Android nor the Kernel. And this is what this Guide is all about.
    Inspired by Alabate and his Guide Use custom USB device with Android emulator by using custom built kernel on Ubuntu 18.04
    Three basic steps needed to be done.

    [Update 04.05.2021]
    A much more easier and reliable way on how to build, mod and update your AVDs Kernel with its modules,
    can be found in my [GUIDE] by using the official AOSP Build ENV.
    1. Build the AVD Kernel with the right check at the right place
    2. Convince Linux to actually let go of the USB-Serial Device
    3. Grant Permissions in Android to acknowledge the new plugged in Device
    The Development Environment:
    1. Build the AVD Kernel with the right check at the right place

    ### From the shell with the AVD running we can get some Kernel Infos:
    uname -r && uname -v 4.14.175-g6f3fc9538452 #1 SMP PREEMPT Wed Apr 8 17:38:09 UTC 2020

    ### Install the following tools to work with and to build the kernel:
    sudo apt-get install -y build-essential libssl-dev kernel-package libncurses5-dev bzip2 lib32z1 bison flex sudo apt-get install -y libelf-dev libelf-devel or elfutils-libelf-dev sudo apt-get install -y qt5-default qttools5-dev-tools qttools5-dev sudo apt-get install -y geany git

    ### Create a working directory and download the kernel source and its prebuilt gcc:
    I choose the latest android-10.0.0_r47 branch and its prebuilt gcc 4.9
    Code:
    cd ~/ && mkdir avdkernelcompile && cd avdkernelcompile
    git clone \
        -b android-10.0.0_r47 \
        --single-branch https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9

    I also choose the mainline android-goldfish-4.14-dev branch from the goldfish kernel source
    Code:
    git clone -b android-goldfish-4.14-dev --single-branch https://android.googlesource.com/kernel/goldfish

    ### Pull the config.gz from the AVD to generate and merge the kernel defconfigs file:
    These steps lower the risk of getting build errors. And before you mod the kernel, it could
    make sense to start with a build kernel that actually boots your AVD first, and then apply changes to it.
    Code:
    adb pull /proc/config.gz
    gunzip -k config.gz
    cd goldfish
    cp ../config .config
    make savedefconfig
    mv defconfig arch/x86/configs/avd_pulled_defconfig
    rm .config
    ./scripts/kconfig/merge_config.sh -m \
        ./arch/x86/configs/avd_pulled_defconfig \
        ./arch/x86/configs/x86_64_ranchu_defconfig
    make savedefconfig
    mv defconfig arch/x86/configs/merged_avd_pulled_defconfig
    rm .config

    ### prepare the kernel with the gcc to be build:
    we are now in the goldfish directory
    exports must be done every time you open a new terminal
    export CROSS_COMPILE=x86_64-linux-android- export ARCH=x86_64 export PATH=$PATH:$(pwd)/../x86_64-linux-android-4.9/bin

    make the just created defconfig file
    make merged_avd_pulled_defconfig

    If you come back here later, this is the right place to mod your kernel.
    I like the GUI Interface because you have a better overview and a search function.
    make xconfig

    In order to get the USB-Serial recognized by the kernel, make sure the UHCI HCD is checked.
    You can find it under: Device Drivers -> USB support -> UHCI HCD (most Intel and VIA) support
    UHCI_HCD.png

    Close and save it.

    ### build the actually kernel, with the all CPU cores you have, and see afterwards how long it took:
    time make -j$(nproc)

    The new kernel is placed in:
    ~/avdkernelcompile/goldfish/arch/x86/boot/bzImage
    We leave it there for now. If you are planing to make changes when all is working so far, just jump
    to make xconfig . The build time now is much smaller now. If you have to start over,
    you can run make mrproper

    ### Start the AVD with the new kernel from via terminal
    To be able to start the emulator and adb from everywhere, add those path in your ~/.bashrc
    echo export PATH=~/Android/Sdk/platform-tools:$PATH >> ~/.bashrc echo export PATH=~/Android/Sdk/emulator:$PATH >> ~/.bashrc source ~/.bashrc

    run the new kernel with:
    Code:
    emulator \
        -netdelay none -netspeed full -avd Pixel_4_XL_API_29 \
        -writable-system -no-snapshot-load \
        -show-kernel \
        -verbose \
        -ranchu \
        -kernel ~/avdkernelcompile/goldfish/arch/x86/boot/bzImage
    If the kernel works proper, you can run the AVD with this even after a Wipe Data from the AVD Manager
    Later on, you can get rid of the show-kernel, verbose and ranchu option. If the kernel boots and you
    can work with the AVD for your satisfaction, it is time for the mod and the next step.

    2. Convince Linux to actually let go of the USB-Serial Device
    According to the Emulator Release Notes, one would just need the vendorID and productID from the desired USB Device to pass it through. These are easily obtained by:
    lsusb Bus 002 Device 009: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

    To start the AVD with it, and you leave out the verbose stuff, the command changes to:
    Code:
    emulator \
        -netdelay none -netspeed full -avd Pixel_4_XL_API_29 \
        -writable-system \
        -no-snapshot-load \
        -kernel ~/avdkernelcompile/goldfish/arch/x86/boot/bzImage \
        -qemu -usb \
        -device usb-host,vendorid=0x067b,productid=0x2303

    If you keep watching the terminal, you can see the error message:
    libusb: error [get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/043, errno=13 libusb: error [get_usbfs_fd] libusb requires write access to USB device nodes
    Now to convince Linux to let go of the USB-Serial Device, one must create an UDEV Rule.
    You can do this even while the AVD is running an the USB-Serial Device is connected:
    echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", OWNER="libvirt-qemu", GROUP="kvm"' | sudo tee /etc/udev/rules.d/99-usb-android.rules
    After this echo command, watch while you unplug and plug it, you will only see the Info Message:
    libusb_release_interface: -4 [NO_DEVICE]
    And if you also watching the AVD with:
    adb root adb shell dmesg | grep usb
    You will see that the kernel is already recognizing it.
    [ 619.670306] usb 1-1: new full-speed USB device number 6 using uhci_hcd [ 620.071451] usb 1-1: New USB device found, idVendor=067b, idProduct=2303 [ 620.073050] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 620.074698] usb 1-1: Product: USB-Serial Controller [ 620.075872] usb 1-1: Manufacturer: Prolific Technology Inc.

    Btw: If you also want to use this USB-Serial Device without access issues in other tools, for example CoolTerm,
    just copy the line from the udev rule and change the SUBSYSTEM to tty.
    SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", OWNER="libvirt-qemu", GROUP="kvm"

    Side Note: Under Mac OS you will get a similar libusb: error, but unlike Linux, there is no UDEV System, so you
    cannot change this situation at all. Also not by unloading a kext. I tried, even with EL Capitan where you actually
    still could unload kexts very easily. So this just "prooves" that the Google Developers, never tried to pass an USB
    through - even if they hinted it: (This should also have been workng on Linux and macOS already) And it is even
    worst, there is actually a very convenient feature built in QEMU, with the -serial keyword, you can attach such devices
    in no time. But for some reason, EXACTLY this feature is taken out from the Google Developers - what a bummer.

    3. Grant Permissions in Android to acknowledge the new plugged in Device
    With the kernel recognizing the USB-Serial Device and Linux let us acces it, the AVD just doesn't know what
    to do with it. Or rather, it doesn't have permissions to proceed. To grant these permissions, one must simply
    place a file, with this permissions, called android.hardware.usb.host.xml in /system/etc/permissions or
    in /vendor/etc/permissions.

    For both places we need not only root but also write access to it. Google Play AVD Images can be rooted, with my
    rootAVD script, but these partitions can't remounted as writeable, no matter what. At least, not with my skills.


    AVD Images with Google APIs on the other hand are capable of beeing rooted and writeable out of the box.
    Actually, just the overlay paritions can be writeable. To achive this, one must start the AVD with the -writable-system
    option. What we already doing all the time.

    When the AVD is up, go with the ADB commands one by one:
    adb root adb shell avbctl disable-verification adb disable-verity adb reboot adb root adb remount adb shell

    Every command must show a positive result, if you stuck in a bootloop or so afterwards,
    one of the two disable commands didn't work. Start over with a Wipe Data.
    Once the remount command shows remount succeeded you are good to go.

    In the adb shell:
    echo '<permissions><feature name="android.hardware.usb.host"/></permissions>' > /system/etc/permissions/android.hardware.usb.host.xml chmod 644 /system/etc/permissions/android.hardware.usb.host.xml reboot

    After the Reboot, plug in your USB-Serial Device, and If you have Serial USB Terminal installed.
    it will finally pop up a message.

    Screenshot_1609712935.png
    If you have USB Device Info installed, It will even show more informations.

    Screenshot_1609712974.png Screenshot_1609712976.png Screenshot_1609712981.png

    If I disable USB Debugging, the 0000 Device will disappear.

    That's it for now. The USB Passthrough for USB-Serial Devices can work.
    I am currently working on a way to get a mass storage mounted in the AVD.
    But I can't figure out the right fstab.ranchu entry for the AVD to auto mount my USB Storage.
    I could get the kernel to recognize it:
    [ 28.090063] usb 1-1: new full-speed USB device number 2 using uhci_hcd [ 28.491686] usb 1-1: not running at top speed; connect to a high speed hub [ 28.499738] usb 1-1: config 1 interface 0 altsetting 0 endpoint 0x2 has invalid maxpacket 512, setting to 64 [ 28.501413] usb 1-1: config 1 interface 0 altsetting 0 endpoint 0x81 has invalid maxpacket 512, setting to 64 [ 28.515287] usb 1-1: New USB device found, idVendor=1f75, idProduct=0917 [ 28.516925] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 28.518772] usb 1-1: Product: PenDrive [ 28.519699] usb 1-1: Manufacturer: Innostor [ 28.522417] usb 1-1: SerialNumber: 000000000000000071 [ 28.526804] usb-storage 1-1:1.0: USB Mass Storage device detected [ 28.528787] scsi host0: usb-storage 1-1:1.0 [ 29.962957] usb 1-1: reset full-speed USB device number 2 using uhci_hcd
    But it keeps getting repeated with the last line
    It also does show up as block device in:
    brw------- 1 root root 8, 0 2021-01-03 23:49 sda
    But without sda1, just sda. And the USB Stick was formated via SDCARDFS in a real phone.

    Update 06.01.2021:
    Modding the Kernel with USB Mass Storage and SCSI support

    In order to get an USB Stick announced by the kernel as block device node, one must
    activate some additional Supports in the Kernel Config.
    • Device Drivers
      • SCSI device support
        • SCSI device support
        • SCSI disk support
      • USB support
        • USB Mass Storage support
          • USB Attached SCSI
    ksnip_20210106-211835.png ksnip_20210106-211955.png
    With these additional features, the kernel is providing the pluged USB Stick under
    /dev/block/sd which is needed to get the fstab.ranchu able to pick it up.

    Once the kernel is complete, one must tell Qemu where it is supposed to plug in the USB Stick.
    This is done with the -device and USB type options:
    Code:
        -device usb-ehci,id=ehci \
        -device usb-host,bus=ehci.0,vendorid=0x8564,productid=0x1000

    The EHCI (USB 2.0) driver support is already build in the stock kernel, so if you device can be
    "downsqeezed" you can tell it Qemu with these words. Use the device usb.ehci, identify it for me as ehci, and attach my VendorID and ProductID to your usb-host bus ehci.0
    (ehci in qemu provides 8 USB ports) With this way, you can also attach multiply USB Devices to the same AVD.
    Code:
        -device usb-ehci,id=ehci \
        -device usb-host,bus=ehci.0,vendorid=0x8564,productid=0x1000 \
        -device usb-host,bus=ehci.0,vendorid=0x1f75,productid=0x0917

    Screenshot_1609965879.png ksnip_20210102-225748.png

    If you have added USB 3.0 support in your kernel already, you can even use the XHCI driver.
    Code:
    emulator \
        -netdelay none -netspeed full -avd Pixel_4_XL_API_29 \
        -writable-system -no-snapshot-load \
        -kernel ~/avdkernelcompile/goldfish/arch/x86/boot/bzImage \
        -qemu -usb \
        -device usb-ehci,id=ehci \
        -device usb-host,bus=ehci.0,vendorid=0x8564,productid=0x1000 \
        -device qemu-xhci,id=xhci \
        -device usb-host,bus=xhci.0,vendorid=0x1f75,productid=0x0917

    And with the fstab.ranchu correctly tuned, both USB Stick will pop up systemwide for every app to use.

    Screenshot_1609965998.png Screenshot_1609966012.png Screenshot_1609966074.png

    Modding the fstab.ranchu
    Without
    Magisk on the AVD installed, you can very easly edit the
    /vendor/etc/fstab.ranchu just in the adb remounted overlay partitions.
    Add this line to it:
    /devices/*/block/sd* auto auto defaults voldmanaged=usb:auto

    With Magisk on the AVD installed, it gets messy. Due to the fact, that Magisk is mounting a mirror of the orignal read-only partitions, some changes can't be done like before. The only way I could figure out was
    to add the fstab.ranchu in my ramdisk.img and let Magisk overlay it during boot time.
    Root Directory Overlay System
    For this you can use my script rootAVD.sh

    Code:
    # Set PATCHFSTAB=true if you want the RAMDISK merge your modded fstab.ranchu before Magisk Mirror gets mounted
    PATCHFSTAB=false
    #PATCHFSTAB=true
    # cp the read-only fstab.ranchu from vendor partition and add usb:auto for SD devices
    # kernel musst have Mass-Storage + SCSI Support enabled to create /dev/block/sd* nodes
    ...

    How to root the AVD and patch fstab.ranchu:

    The script runs in Linux, Darwin MacOS and Windows. It needs the path to the ramdisk.img of the system-image as a parameter.
    The AVD needs to be running and accessible via adb shell.
    Then just run it and restart, NOT adb reboot, your AVD. It works with
    Android 7, Android 10 and Android 11. But not with Android 8 and Android 9.
    It also copys every .apk within the Apps Folder to the AVD.
    ./rootAVD.sh ~/Android/Sdk/system-images/android-30/google_apis_playstore/x86_64/ramdisk.img

    To get the fstab.ranchu patched, set PATCHFSTAB=true, make some adjustments, and let the rootAVD script run.

    Miscellaneous:
    Special Cherrys for Googe Play Store AVD with Stock Kernel:

    The EHCI USB Driver is already implemented in the Stock Kernel, even in the Google Play Version AVD.
    By adding the android.hardware.usb.host.xml file to its rightful place, a well
    written App, like X-plore File Manager, could use its own USB-Driver to access the USB Storage.

    Screenshot_1609879051.png

    But how to get it there? Once Magisk is installed via the rootAVD script. Which are basicly the
    original scripts from Magisk, just a bit tuned. You can install my Magisk Module: usbhostpermissons

    Don't forget to start the AVD with usb-ehci command. The USB Stick won't pop up systemwide,
    but you can still use them within X-plore and copy & paste files with it.

    Replace the emulator with a script to pass arguments and run it from the GUI:

    Code:
    mv ~/Android/Sdk/emulator/emulator ~/Android/Sdk/emulator/emulator-original
    cat <<EOF > ~/Android/Sdk/emulator/emulator
    #!/bin/bash
    ~/Android/Sdk/emulator/emulator-original \[email protected] \
        -writable-system -no-snapshot-load \
        -kernel ~/avdkernelcompile/goldfish/arch/x86/boot/bzImage \
        -qemu -usb \
        -device usb-ehci,id=ehci \
        -device usb-host,bus=ehci.0,vendorid=0x8564,productid=0x1000 \
        -device qemu-xhci,id=xhci \
        -device usb-host,bus=xhci.0,vendorid=0x1f75,productid=0x0917 \
        -device usb-host,bus=usb-bus.0,vendorid=0x067b,productid=0x2303
    EOF
    chmod +x ~/Android/Sdk/emulator/emulator

    If you have your original emulator file renamed, don't forget to change it when you are
    calling it manual from the command line.

    [Update 15.12.2021]
    For Windows Only.

    Since Emulator Version 31.1.4, Google re-implemented the USB pass through feature along with
    some tools:
    and emulator parameters:
    The Windows drivers must be installed from an Adminstrator Command Shell
    Code:
    Install_Drivers.bat
    Installing Android USB Assistant...
    call Android_USB_Assistant_Install.bat
    Microsoft PnP Utility
    
    Processing inf :            Android_USB_Assistant.inf
    Successfully installed the driver.
    Driver package added successfully.
    Published name :            oem89.inf
    
    
    Total attempted:              1
    Number successfully imported: 1
    
    Installing Android Emulator USB Passthrough Assistance Driver
    
    SERVICE_NAME: UsbAssist
            TYPE               : 1  KERNEL_DRIVER
            STATE              : 1  STOPPED
            WIN32_EXIT_CODE    : 0  (0x0)
            SERVICE_EXIT_CODE  : 0  (0x0)
            CHECKPOINT         : 0x0
            WAIT_HINT          : 0x0
    [SC] DeleteService SUCCESS
    
    SERVICE_NAME: UsbAssist
            TYPE               : 1  KERNEL_DRIVER
            STATE              : 4  RUNNING
                                    (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
            WIN32_EXIT_CODE    : 0  (0x0)
            SERVICE_EXIT_CODE  : 0  (0x0)
            CHECKPOINT         : 0x0
            WAIT_HINT          : 0x0
            PID                : 0
            FLAGS              :

    Find your connected USB Devices
    Code:
    emulator -list-usb
    VID:PID 058f:6387 (Bus 1, Port 5.1.1)
            Manufacturer:
            Product:
            SerialNumber:   40A0FE0A
    
    VID:PID 067b:2303 (Bus 1, Port 5.1.2)
            Manufacturer:   NA
            Product:        NA
            SerialNumber:   NA
    
    VID:PID 0403:6001 (Bus 1, Port 5.1.2)
            Manufacturer:   FTDI
            Product:        USB-to-Serial
            SerialNumber:   FT9QIQ6Y
    
    VID:PID 1bcf:284c (Bus 1, Port 5.1.2)
            Manufacturer:   SunplusIT Inc
            Product:        5MP USB webcam
            SerialNumber:   N2020040701

    Now you can use those VID : PID combination to pass it through your AVD
    Code:
    emulator -netdelay none -netspeed full -avd Pixel_4_API_3 -usb-passthrough vendorid=0x058f,productid=0x6387

    Multible VID : PID combinations are also possible
    Code:
    emulator -netdelay none -netspeed full -avd Pixel_4_API_32 -usb-passthrough vendorid=0x058f,productid=0x6387 -usb-passthrough vendorid=0x067b,productid=0x2303

    Unfortunately the emulator will show this Error:
    Code:
    qemu-system-x86_64.exe: libusb_kernel_driver_active: -12 [NOT_SUPPORTED]
    But the Devices are still passed through.
    They will not be shown in the AVD nor recognized as a Device in any way.
    In order to accomplish this, you must:
    • root the AVD with Magisk (Canary for 64-Bit only AVDs)
    • patch the FSTAB to get USB Drives automaticly mounted as a drive
    • install my USB Host Permissions Magisk Module
    This can be done by:
    Code:
    rootAVD.bat %LOCALAPPDATA%\Android\Sdk\system-images\android-32\google_apis_playstore\x86_64\ramdisk.img PATCHFSTAB GetUSBHPmodZ

    The Magisk Module will be put into the local Download folder of the AVD.

    AVDs with a Kernel Version lower then 5.4.65 need either a custom build kernel with the
    USB features enabled or an updated prebuild Kernel directly from the AOSP.
    Code:
    rootAVD.bat %LOCALAPPDATA%\Android\Sdk\system-images\android-30\google_apis_playstore\x86_64\ramdisk.img InstallPrebuiltKernelModules PATCHFSTAB GetUSBHPmodZ

    Thanks for reading
    Cheers NewBit


    Thanks and Credits to @topjohnwu , Alabate, Google, Qemu and Jitendra

    QEMU/Devices/USB/Root
    USB Quick Start
    USB recommendations for qemu
    qemu usb storage emulation