에뮬레이터 USB 패스 스루 통합 가이드

이 페이지에서는 두 개의 주변기기(블루투스와 Wi-Fi)를 AAOS 에뮬레이터에 연결하는 방법을 설명합니다. 이 프로세스의 핵심은 드라이버 지원과 관련된 3가지 영역입니다.

  • 게스트 커널
  • 게스트 Android
  • Linux 호스트

먼저 게스트 커널에서 관련 USB 드라이버를 컴파일하고 사용 설정합니다. 다음으로 게스트 Android에서 올바른 HAL과 서비스를 선택하여 드라이버를 불러와야 합니다. 마지막으로 Linux 호스트에서는 USB 드라이버에 액세스하고 이를 QEMU로 전송해야 합니다.

동글 테스트

다음 동글을 테스트했습니다.

다른 동글이 작동할 수도 있지만 테스트된 다른 동글은 없습니다.

네이티브 USB 지원

QEMU에서는 USB를 에뮬레이터로 전달하는 옵션이 제공됩니다. AAOS 시스템 이미지는 이미 연결된 휴대전화를 처리합니다. 자세한 내용은 AOA(Android Open Accessory)를 참고하세요.

휴대전화는 AOA 연결이 설정될 때 vendorIDproductID 값을 변경하므로 새 USB 인터페이스는 (기존 USB 인터페이스도 동일함) 휴대전화가 AOA 모드일 때 기기를 확인합니다.

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 패스 스루를 지원하려면 Emulator 30.5.0을 사용하고 있는지 확인합니다.

# Check for the emulator version
$ emulator --version

Emulator 30.5.0에는 ASUS 동글 지원의 속도 호환성을 해결하는 libusb 업그레이드 및 임시 해결 방법이 포함되어 있습니다.

블루투스 지원

블루투스 패스 스루를 지원하기 위해 Google은 ASUS USB-BT400 USB 어댑터 USBBT400과 Auscomer USB Wi-Fi 블루투스 어댑터를 테스트했습니다.

먼저 동글의 커널 지원을 추가해야 합니다. Android 블루투스 스택에 관한 자세한 내용은 블루투스를 참고하세요. HIDL의 경우 에뮬레이터는 시뮬레이션된 구현을 사용합니다. 따라서 네이티브 Linux 구현으로 바꿉니다.

게스트 커널

USB 블루투스 동글을 지원하려면 다음을 실행합니다.

  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. 실제 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. 사용자 프로세스(예: QEMU)에서 읽기/쓰기 권한을 갖도록 udev 설정을 업데이트합니다.

    $ 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 지원

Google에서는 듀얼 블루투스 및 Wi-Fi를 검증하기 위해 USB Wi-Fi 블루투스 어댑터로 테스트했습니다.

게스트 커널

이 특정 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 호스트에서는 사용자 프로세스(예: QEMU)에서 읽기/쓰기 권한을 갖도록 udev 설정을 업데이트해야 합니다.

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

변경 목록 포팅

다음 변경 목록을 포팅합니다.