Guía de integración del emulador USB Passthrough

Este artículo describe cómo conectar dos periféricos (Bluetooth y Wi-Fi) al emulador AAOS. En este proceso, tres áreas específicas de apoyo al conductor son clave:

  • Núcleo invitado
  • Android invitado
  • anfitrión de Linux

Primero, compila y habilita los controladores USB relevantes en el kernel invitado. A continuación, Guest Android debe seleccionar el HAL y los servicios correctos para mostrar los controladores. Finalmente, el host Linux debe obtener acceso al controlador USB y luego transferirlo a QEMU .

Dongles probados

Se probaron los siguientes dongles:

Es posible que funcionen otros dongles, sin embargo, no se probaron otros.

Soporte USB nativo

QEMU viene con opciones para pasar USB al emulador. La imagen del sistema AAOS ya maneja un teléfono conectado. Para obtener más información, consulte Accesorio abierto de Android (AOA) .

Debido a que el teléfono cambia los valores de vendorID y productID al establecer una conexión AOA, la nueva interfaz USB (así como la interfaz USB original) ve el dispositivo cuando el teléfono está en modo AOA.

Para determinar los valores de vendorID y productID antes y después del modo AOA, use lsusb :

# Note Vendor ID and Product ID of your phone
$ lsusb
Bus 001 Device 079: ID 18d1:4ee1 Google Inc. Nexus/Pixel Device (MTP)
# Start up an emulator!
$ ./emulator @AVD_NAME -no-snapshot -qemu -device usb-ehci,id=ehci -device usb-host,bus=ehci.0,vendorid=0x18d1,productid=0x4ee1 -device usb-host,bus=ehci.0,vendorid=0x18d1,productid=0x2d00

Alternativamente, pase el puerto físico a QEMU:

# First plug something into the interested USB port and note the Bus and Device number.
$ lsusb
Bus 001 Device 012: ID 0bda:c820 Realtek Semiconductor Corp. 802.11ac NIC
# Now figure out where the Port number is.
$ lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 480M
    |__ Port 4: Dev 12, If 1, Class=Wireless, Driver=btusb, 480M
    |__ Port 4: Dev 12, If 2, Class=Vendor Specific Class, Driver=, 480M
    |__ Port 4: Dev 12, If 0, Class=Wireless, Driver=btusb, 480M
# Launch the emulator
 ./emulator @AVD_NAME -no-snapshot -qemu -device usb-ehci,id=ehci -device usb-host,bus=ehci.0,hostbus=1,hostport=4
# Now, whatever you plug into the emulator, USB passthrough will happen on the fly.

La imagen del sistema AAOS reconoce el teléfono, lo pone en modo AOA y lo reconoce nuevamente cuando se ejecuta el modo AOA.

Para admitir la transferencia USB, confirma que estás usando el emulador 30.5.0 :

# Check for the emulator version
$ emulator --version

Emulator 30.5.0 incluye una actualización libusb y una solución temporal para abordar la compatibilidad de velocidad del soporte de dongle ASUS:

soporte bluetooth

Para admitir la transferencia de Bluetooth, Google probó el adaptador USB ASUS USB-BT400 USBBT400 y el adaptador USB Wi-Fi Bluetooth de Auscomer.

Primero, debe agregar soporte de kernel para el dongle. Para comprender la pila Bluetooth de Android, consulte Bluetooth . Para HIDL, el emulador utiliza una implementación simulada. Por lo tanto, cambie eso con una implementación nativa de Linux.

Núcleo invitado

Para admitir una llave USB Bluetooth:

  1. Agregue el btusb.ko que falta a su kernel:

    --- a/goldfish_defconfig.fragment
    +++ b/goldfish_defconfig.fragment
    @@ -1,6 +1,7 @@
     # CONFIG_CRYPTO_DEV_VIRTIO is not set
     CONFIG_BLK_DEV_MD=m
    +CONFIG_BT_HCIBTUSB=m
     CONFIG_CPUFREQ_DUMMY=m
    

Android invitado

  1. En el archivo vendor.mk , incluya el HIDL nativo de Linux y varios permisos:

    PRODUCT_PACKAGES += \
        android.hardware.bluetooth@1.1-service.btlinux
    PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.hardware.usb.host.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.usb.host.xml
    
  2. Cree una propiedad de ruta unidireccional para cambiar el HIDL de modo que utilice una implementación HIDL nativa de Linux:

    selinux/common/domain.te
    
    get_prop(domain, qemu_prop)
    +get_prop(domain, vendor_build_prop)
    
    selinux/common/property_contexts
    
    qemu.cmdline            u:object_r:qemu_cmdline:s0
    +qemu.preferred.bt.service u:object_r:qemu_prop:s0
    
  3. Siempre que una propiedad qemu.preferred.bt.service esté configurada como passthrough , cambiará la implementación HIDL:

    service btlinux-1.1 /vendor/bin/hw/android.hardware.bluetooth@1.1-service.btlinux
      class hal
      user bluetooth
      group bluetooth net_admin net_bt_admin
      capabilities NET_ADMIN NET_RAW SYS_NICE
      disabled
    
    on property:qemu.preferred.bt.service=passthrough
      stop vendor.bluetooth-1-1
      start btlinux-1.1
    
  4. Agregue un archivo de configuración de Bluetooth para obtener funciones completas, como en un dispositivo USB real:

    hal/bluetooth/bdroid_buildcfg.h
    
    #ifndef _BDROID_BUILDCFG_H
    #define _BDROID_BUILDCFG_H
    #define BTM_DEF_LOCAL_NAME "gCar Emulator"
    #define BTA_AV_SINK_INCLUDED TRUE
    /* Handsfree device */
    #define BTA_DM_COD {0x26, 0x04, 0x08}
    #endif
    
  5. Modifique el archivo BoardConfig.mk para determinar dónde se guarda el archivo de configuración:

    BoardConfig.mk
    
    # Bluetooth
    BOARD_HAVE_BLUETOOTH := true
    BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := vendor/auto/embedded/hal/bluetooth
    

anfitrión de Linux

En el servidor Linux:

  1. Actualice la configuración udev para permitir que el proceso de usuario (por ejemplo, QEMU) tenga permisos de lectura/escritura:

    $ echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="0b05", ATTRS{idProduct}=="17cb", MODE="0666", GROUP="plugdev"' | sudo tee /etc/udev/rules.d/99-mynew.rules >/dev/null
    $ sudo udevadm control --reload
    $ sudo udevadm trigger
    
  2. Para ejecutar el emulador, configure los siguientes parámetros de línea de comando:

    # Start up an emulator!
    $ ./emulator @AVD_NAME -no-snapshot -prop qemu.preferred.bt.service=passthrough -qemu -device usb-ehci,id=ehci -device usb-host,bus=ehci.0,vendorid=0x0b05,productid=0x17cb
    # Start Bluetooth Passthrough
    

Soporte wifi

Para validar Bluetooth y Wi-Fi duales, Google probó con el adaptador USB Wi-Fi Bluetooth.

Núcleo invitado

Este dongle USB en particular utiliza el chip RTL8821CU, que el kernel principal aún no admite. Puede encontrar un módulo de kernel recientemente desarrollado en 8821cu .

Luego, en la lista de cambios 1575108 , los módulos externos del kernel se integraron en la fuente del kernel goldfish para compilarlo.

Finalmente, el módulo del kernel se compila pero con algunos fallos de CFI. Debes parchear el código manualmente para solucionar este problema. Para obtener más información, consulte Controlar la integridad del flujo en el kernel de Android .

Puede resultar útil habilitar CONFIG_CFI_PERMISSIVE y seguir adelante con la depuración del resto de la pila primero:

--- a/goldfish_defconfig.fragment
+++ b/goldfish_defconfig.fragment
@@ -1,6 +1,7 @@
 CONFIG_CFI_CLANG=m
+CONFIG_CFI_PERMISSIVE=m

En cualquier caso, vaya a la lista de cambios 1575109 para ver la solución adecuada para los fallos del CFI.

Android invitado

Para obtener más información sobre la pila de Wi-Fi, consulte Descripción general de Wi-Fi . El emulador viene con la configuración para que funcione Wi-Fi.

anfitrión de Linux

En el host Linux, debe actualizar la configuración udev para permitir que el proceso de usuario (por ejemplo, QEMU) tenga permisos de lectura/escritura.

# /lib/udev/rules.d/40-usb_modeswitch.rules
$ ATTR{idVendor}=="0bda", ATTR{idProduct}=="1a2b", RUN+="usb_modeswitch '/%k'"
$ echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="c820", MODE="0666", GROUP="plugdev"' | sudo tee /etc/udev/rules.d/99-mynew2.rules >/dev/null
$ sudo udevadm control --reload
$ sudo udevadm trigger

Para pasar el dongle a QEMU:

# Start up an emulator!
$ ./emulator @AVD_NAME -no-snapshot -qemu -device usb-ehci,id=ehci -device usb-host,bus=ehci.0,vendorid=0x0bda,productid=0xc820

Listas de cambios de puertos

Porte las siguientes listas de cambios: