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 del apoyo al conductor son clave:

  • Núcleo invitado
  • Androide invitado
  • servidor Linux

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

Dongles probados

Se probaron los siguientes dongles:

Otros dongles pueden funcionar, sin embargo, no se probaron otros.

Compatibilidad con 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 de proveedor y de 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 de proveedor y de producto antes y después del modo AOA, lsusb productID

# 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 vuelve a reconocer cuando se está ejecutando el modo AOA.

Para admitir el paso de USB, confirme que está utilizando Emulator 30.5.0 :

# Check for the emulator version
$ emulator --version

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

Soporte Bluetooth

Para admitir el paso 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 de Bluetooth de Android, consulte Bluetooth . Para HIDL, el emulador usa una implementación simulada. Por lo tanto, cambie eso con una implementación nativa de Linux.

Núcleo invitado

Para admitir un dongle Bluetooth USB:

  1. Agregue el btusb.ko faltante a su núcleo:

    --- 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
    

Androide 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 use 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 se establezca en passthrough , cambiará la implementación de 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
    

servidor Linux

En el host de Linux:

  1. Actualice la configuración de 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 el Bluetooth dual y Wi-Fi, Google probó con el adaptador USB Wi-Fi Bluetooth.

Núcleo invitado

Este dongle USB en particular usa el chip RTL8821CU, que el núcleo de la línea principal aún no es compatible. Puede encontrar un módulo kernel recientemente desarrollado en 8821cu .

Luego, en la lista de cambios 1575108 , los módulos del kernel externo se integraron en el código fuente del kernel de Goldfish para compilarlo.

Finalmente, el módulo del kernel se compila pero con algunos bloqueos de CFI. Necesita parchear el código manualmente para arreglar esto. Para obtener más información, consulte Integridad del flujo de control en el kernel de Android .

Puede ser útil habilitar CONFIG_CFI_PERMISSIVE y avanzar 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 bloqueos de CFI.

Androide 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 hacer que Wi-Fi funcione.

servidor Linux

En el host de Linux, debe actualizar la configuración de 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 puerto

Porte las siguientes listas de cambios: