คู่มือการรวม Passthrough USB ของ Emulator

หน้านี้อธิบายวิธีเชื่อมต่ออุปกรณ์ต่อพ่วงสองตัว (บลูทูธและ Wi-Fi) เข้ากับโปรแกรมจำลอง AAOS ในกระบวนการนี้ สิ่งสำคัญสามประการสำหรับการสนับสนุนผู้ขับขี่คือ:

  • เคอร์เนลแขก
  • แขกรับเชิญ Android
  • โฮสต์ลินุกซ์

ขั้นแรก คุณคอมไพล์และเปิดใช้งานไดรเวอร์ USB ที่เกี่ยวข้องในเคอร์เนล Guest จากนั้น Guest 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 โปรดยืนยันว่าคุณกำลังใช้ Emulator 30.5.0 :

# Check for the emulator version
$ emulator --version

Emulator 30.5.0 มีการอัพเกรด libusb และวิธีแก้ปัญหาชั่วคราวเพื่อแก้ไขความเข้ากันได้ด้านความเร็วของการรองรับ ASUS dongle:

รองรับบลูทูธ

เพื่อรองรับการส่งผ่านบลูทูธ Google ได้ทดสอบ อะแดปเตอร์ USB ASUS USB-BT400 USBBT400 และอะแดปเตอร์ USB Wi-Fi Bluetooth โดย Auscomer

ขั้นแรก คุณต้องเพิ่มการรองรับเคอร์เนลสำหรับดองเกิล หากต้องการทำความเข้าใจสแต็ก Bluetooth ของ Android โปรดดูที่ Bluetooth สำหรับ HIDL ตัวจำลองจะใช้การใช้งานจำลอง ดังนั้นให้เปลี่ยนสิ่งนั้นด้วยการใช้งาน Linux แบบเนทีฟ

เคอร์เนลแขก

หากต้องการรองรับดองเกิล Bluetooth 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 ให้รวม 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:

  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

Google ทดสอบกับอะแดปเตอร์ USB Wi-Fi Bluetooth เพื่อตรวจสอบความถูกต้องของบลูทูธและ Wi-Fi คู่

เคอร์เนลแขก

ดองเกิล USB นี้ใช้ชิป RTL8821CU ซึ่งเคอร์เนลอัพสตรีมหลักยังไม่รองรับ คุณสามารถค้นหาโมดูลเคอร์เนลที่พัฒนาขึ้นใหม่ได้ที่ 8821cu

จากนั้นใน รายการเปลี่ยนแปลง 1575108 โมดูลเคอร์เนลภายนอกถูกรวมเข้ากับแหล่งเคอร์เนลของปลาทองเพื่อคอมไพล์

ในที่สุด โมดูลเคอร์เนลจะคอมไพล์ แต่ CFI ขัดข้องบางส่วน คุณต้องแก้ไขโค้ดด้วยตนเองเพื่อแก้ไขปัญหานี้ สำหรับรายละเอียด โปรดดูที่ Control Flow Integrity ในเคอร์เนล 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 คุณต้องอัปเดตการตั้งค่า 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

รายการการเปลี่ยนแปลงพอร์ต

พอร์ตรายการการเปลี่ยนแปลงต่อไปนี้: