Руководство по интеграции эмулятора USB Passthrough

В этой статье описывается, как подключить два периферийных устройства (Bluetooth и Wi-Fi) к эмулятору AAOS. В этом процессе ключевыми являются три области, характерные для поддержки водителей:

  • Гостевое ядро
  • Гостевой Android
  • Хост Linux

Сначала вы компилируете и включаете соответствующие драйверы USB в гостевом ядре. Затем гостевой Android должен выбрать правильный HAL и службы для запуска драйверов. Наконец, Linux-хост должен получить доступ к USB-драйверу, а затем передать его в QEMU .

Донглы протестированы

Были протестированы следующие ключи:

Другие ключи могут работать, однако другие не тестировались.

Родная поддержка USB

QEMU поставляется с опциями для передачи USB в эмулятор. Образ системы AAOS уже поддерживает подключенный телефон. Дополнительные сведения см. в разделе Android Open Accessory (AOA) .

Поскольку телефон изменяет значения для vendorID и productID при установлении соединения AOA, новый интерфейс USB (а также исходный интерфейс USB) видит устройство, когда телефон находится в режиме AOA.

Чтобы определить значения для vendorID и productID до и после режима AOA, используйте 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

В качестве альтернативы передайте физический порт в 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.

Системный образ AAOS распознает телефон, переводит его в режим AOA и снова распознает, когда работает режим AOA.

Для поддержки сквозной передачи USB подтвердите, что вы используете эмулятор 30.5.0 :

# Check for the emulator version
$ emulator --version

Эмулятор 30.5.0 включает в себя обновление libusb и временный обходной путь для обеспечения совместимости скорости поддержки ключей ASUS:

Поддержка Bluetooth

Чтобы обеспечить сквозную передачу Bluetooth, компания Google протестировала USB-адаптер ASUS USB-BT400 USBBT400 и USB-адаптер Wi-Fi Bluetooth от Auscomer.

Во-первых, вам нужно добавить поддержку ядра для ключа. Чтобы понять стек Android Bluetooth, см. раздел Bluetooth . Для HIDL эмулятор использует симулированную реализацию. Поэтому переключитесь на нативную реализацию Linux.

Гостевое ядро

Для поддержки USB-адаптера Bluetooth:

  1. Добавьте недостающий btusb.ko в ваше ядро:

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

  1. В файле vendor.mk собственный HIDL для Linux и несколько разрешений:

    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. Создайте свойство одностороннего пути, чтобы отключить HIDL, чтобы он использовал собственную реализацию HIDL для 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. Всякий раз, когда для свойства qemu.preferred.bt.service установлено значение passthrough , вы отключаете реализацию 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. Добавьте файл конфигурации Bluetooth, чтобы получить все функции, например, на реальном USB-устройстве:

    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. Измените файл BoardConfig.mk , чтобы определить, где хранится файл конфигурации:

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

Хост Linux

На хосте Linux:

  1. Обновите настройки udev , чтобы позволить пользовательскому процессу (например, QEMU) иметь права на чтение/запись:

    $ 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. Для запуска эмулятора задайте следующие параметры командной строки:

    # 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
    

поддержка Wi-Fi

Чтобы проверить двойной Bluetooth и Wi-Fi, Google протестировал USB-адаптер Wi-Fi Bluetooth.

Гостевое ядро

Этот конкретный USB-ключ использует чип RTL8821CU, который пока не поддерживает основное ядро. Вы можете найти недавно разработанный модуль ядра по адресу 8821cu .

Затем в списке изменений 1575108 внешние модули ядра были интегрированы в исходный код ядра золотой рыбки для его компиляции.

Наконец, модуль ядра компилируется, но с некоторыми сбоями CFI. Вам нужно исправить код вручную, чтобы исправить это. Подробнее см. в разделе Управление целостностью потока в ядре Android .

Может быть полезно включить CONFIG_CFI_PERMISSIVE и сначала отладить остальную часть стека:

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

В любом случае перейдите к списку изменений 1575109 , чтобы увидеть правильное исправление сбоев CFI.

Гостевой Android

Дополнительные сведения о стеке Wi-Fi см. в разделе Обзор Wi-Fi . Эмулятор поставляется с настройками для работы Wi-Fi.

Хост Linux

На хосте Linux вы должны обновить настройки udev , чтобы позволить пользовательскому процессу (например, QEMU) иметь разрешения на чтение/запись.

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

Чтобы передать ключ в 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

Списки изменений портов

Портировать следующие списки изменений: