エミュレータ USB パススルー統合ガイド

この記事では、2 つの周辺機器 (Bluetooth と Wi-Fi) を AAOS エミュレーターに接続する方法について説明します。このプロセスでは、ドライバー サポートに固有の 3 つの領域が重要です。

  • ゲストカーネル
  • ゲスト Android
  • Linux ホスト

まず、ゲスト カーネルで関連する USB ドライバーをコンパイルして有効にします。次に、ゲスト Android は、適切な HAL とサービスを選択してドライバーを起動する必要があります。最後に、Linux ホストは USB ドライバーにアクセスし、それをQEMUに転送する必要があります。

テスト済みのドングル

次のドングルがテストされました。

他のドングルも動作する可能性がありますが、他のドングルはテストされていません。

ネイティブ USB サポート

QEMU には、USB をエミュレーターに渡すオプションが付属しています。 AAOS システム イメージは、接続された電話をすでに処理しています。詳細については、 Android オープン アクセサリ (AOA)を参照してください。

電話機は AOA 接続の確立時にvendorIDproductIDの値を変更するため、電話機が AOA モードの場合、新しい USB インターフェイス(元の USB インターフェイスも)はデバイスを認識します。

AOA モードの前後でvendorIDproductIDの値を確認するには、 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には、ASUS ドングル サポートの速度互換性に対処するためのlibusbアップグレードと一時的な回避策が含まれています。

Bluetooth サポート

Bluetooth パススルーをサポートするために、Google は、 Auscomer による ASUS USB-BT400 USB アダプター USBBT400および USB Wi-Fi Bluetooth アダプターをテストしました。

まず、ドングルのカーネル サポートを追加する必要があります。 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ファイルに、Linux ネイティブ HIDL といくつかの権限を含めます。

    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. Linux ネイティブ HIDL 実装を使用するように HIDL を切り替える一方向パス プロパティを作成します。

    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.servicepassthroughに設定されている場合は常に、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で、外部カーネル モジュールが goldfish カーネル ソースに統合され、コンパイルされました。

最後に、カーネル モジュールはコンパイルされますが、いくつかの 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

ポートチェンジリスト

次の変更リストを移植します。