Google 致力于为黑人社区推动种族平等。查看具体举措

架构

AAOS 中为支持 VirtIO 所需进行的大部分更改都涉及到 Android 通用内核中 HAL 实现级别及以下级别的更改。Android 框架使用 AAOS 客户机虚拟机内核中的 VirtIO 驱动程序与一个与硬件无关的通用 HAL 进行通信,而 VirtIO 驱动程序使用 VirtIO 协议与主机端的 VirtIO 设备进行通信。主机端的 VirtIO 设备可以使用 SoC 专用设备驱动程序来访问物理硬件。

VirtIO 驱动程序与 VirtIO 设备之间的通信是通过 virtqueue 进行的,virtqueue 是分散聚集表的类似于 DMA 的环形缓冲区。多种传输方式(如 MMIOPCI)可用于在虚拟机之间交换 VirtIO 消息。

在某些情况下,vsock 已被用于虚拟机间通信。通过 vsock 接口使用与独立虚拟机上的对等代理的连接来支持车载 HAL、音频控制和转储状态通信。GRPC-vsock 用于访问这些非标准化子系统。Android 源代码树中的 GRPC 已经过修改,可以与 vsock(地址格式为 vsock:CID:PORT_NUMBER)搭配使用。

虚拟化架构
图 1. 虚拟化架构

图形

当 AAOS 作为客户机虚拟机与其他汽车操作系统一起运行时,Android 可能无法直接访问 GPU 或显示控制器。在这种情况下,Android 客户机虚拟机上的 Mesavirtio-gpu 驱动程序以及 virtio-gpu 设备可用于访问 GPU。

在 Android 客户机虚拟机上,Mesa 使用 Gallium3D 框架将着色器编译为 TGSI 中间表示形式,并将 API 转换为状态对象。Gallium3D 随后将编译后的状态对象和绘制调用提交到 Mesa Virgl,而 Mesa Virgl 随后又使用 virtio-gpu 作为传输协议来将命令和着色器发送到主机虚拟机。

在主机端,virglrenderer 会接收 virtio-gpu 命令流,并将该流转换为 OpenGL ES 命令。此外,它还会将着色器从 TGSI 格式转换为 GLSL 格式,然后在现有 GPU 驱动程序之上重放这些着色器。

AAOS 参考平台 trout 目前仅支持 OpenGL ES,预计会在未来的版本中支持 Vulkan。

图形架构
图 2. 图形架构

传感器

当 AAOS 作为客户机虚拟机与其他汽车操作系统一起运行时,Android 可能无法直接访问传感器。在这种情况下,Android 客户机虚拟机上的 Virtio-SCMI 驱动程序和主机虚拟机上的 VirtIO-SCMI 设备用于访问传感器。AAOS 虚拟化参考平台提供了一个与硬件无关的通用传感器 HAL,它可用于基于 ARM 的 SoC 以访问传感器。

传感器 HAL 与 Linux 内核 IIO 子系统中的 IIO SCMI 驱动程序进行通信,该驱动程序使用 ARM 系统控制和管理接口 (SCMI) 规范提供的 SCMI 传感器管理协议来发现和配置传感器、读取传感器数据,以及接收有关传感器值变化的通知。IIO SCMI 驱动程序使用 VirtIO SCMI 驱动程序,后者使用 virtio-scmi 规范中指定的 VirtIO 传输协议来与主机虚拟机上的 VirtIO SCMI 设备交换 SCMI 消息。VirtIO SCMI 设备可以通过 SoC 专用传感器驱动程序直接访问传感器。

传感器架构
图 3. 传感器架构

传感器 HAL 位置

传感器 HAL 的参考实现(使用 VirtIO SCMI)位于 device/google/trout/hal/sensors

传感器 HAL 配置

传感器 HAL 可能需要修改从主机虚拟机接收的传感器数据,以符合 Android 汽车传感器坐标系。传感器配置的架构可以在 device/google/trout/hal/sensors/2.0/config/sensor_hal_configuration.xsd 中找到。

OEM 可以在 sensor_hal_configuration.xml 中提供传感器配置(如方向和位置),还能复制 /odm/etc/sensors//vendor/etc/sensors/ 下的文件。下面提供了一个传感器配置示例:

<sensorHalConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
    <modules>
        <module halName="android.hardware.sensors@2.0-Google-IIO-Subhal" halVersion="2.0">
            <sensors>
                <sensor name="scmi.iio.accel" type="1">
                    <configuration>
<!-- Attribute rotate denotes if HAL needs to modify the sensor data to comply with //
        the Android car sensor coordinate system -->
                        <orientation rotate="true">
               <!-- Attribute map denotes the indexes of data in sensor data received -->
               <!-- Attribute negate denotes if data needs to be negated -->
                            <x map="0" negate="false"/>
                            <y map="1" negate="true"/>
                            <z map="2" negate="true"/>
                        </orientation>
                        <location>
               <!-- Attribute x, y, z denotes location of the sensor placement -->
                            <x>10</x>
                            <y>15</y>
                            <z>20</z>
                        </location>
                    </configuration>
                </sensor>
         </sensors>
        </module>
    </modules>
</sensorHalConfiguration>

音频

在虚拟化 AAOS 中,Android 客户机虚拟机可以使用 virtio-snd 访问音频。virtio-snd 会向 Android 虚拟机提供虚拟化 PCM 设备,以便音频 HAL 实现可以与带有 TinyALSA 库的虚拟化声音设备进行互动。

默认的音频 HAL 实现位于 AOSP 中的 /device/google/trout/hal/audio/6.0 下。OEM 可以为其平台修改 ro.vendor.trout.audiohal.{in,out}_period_{ms,count}。此外,OEM 还可以通过替换 /device/google/trout/aosp_trout_common.mk. 中与音频相关的变量来实现他们自己的音频 HAL。

音频控制 HAL 管理 AAOS 中的音频焦点。例如,当系统正在播放紧急声音时,正在播放的背景音乐可能需要静音。在这种情况下,音频控制 HAL 将通知那些正在播放音乐的应用静音。在虚拟化系统中,声音可能来自其他虚拟机。在参考实现中,AAOS 客户机虚拟机运行一个音频控制服务器守护程序,该守护程序使用 GRPC-vsock 接收来自其他虚拟机的音频焦点请求。主机虚拟机可以使用 device/google/trout/hal/audiocontrol/2.0/libandroid_audio_controller 将音频控制请求发送到 AAOS。当 libandroid_audio_controller 持有音频焦点时,它将继续向 AAOS 发送检测信号,直到释放焦点。

音频架构
图 4. 音频架构

蓝牙

当 AAOS 作为客户机虚拟机与其他汽车操作系统一起运行时,Android 可能无法直接访问蓝牙控制器。在这种情况下,Android 客户机虚拟机上的 VirtIO-Console 驱动程序和主机虚拟机上的 VirtIO-Console 设备可用于打开一个虚拟 COM 端口,将 HCI 数据包发送到蓝牙控制器并接收事件。这种设计可让 Android 蓝牙堆栈使用与硬件无关的通用蓝牙 HAL。主机虚拟机可以处理硬件专用任务,如蓝牙控制器的初始化和固件下载。

蓝牙实现基于下面的设计示意图。

蓝牙架构
图 5. 蓝牙架构

车载 HAL

车载 HAL 实现由两个组件组成:

  • 客户端 - 提供 Android 在虚拟化 AAOS 中使用的 API。
  • 服务器 - 直接与车载总线等硬件(或模拟器)进行通信。

在虚拟化环境中,VHAL 服务器在主机虚拟机上运行。VHAL 客户端和服务器通过 GRPC-vsock 进行通信(如需了解详情,请查看 device/google/trout/hal/vehicle/2.0/proto/VehicleServer.proto)。OEM 可以通过替换通信 API 来使用除 GRPC 之外的其他传输协议。有关示例,请查看 device/google/trout/hal/vehicle/2.0/GrpcVehicle{Client,Server}.cpp

增强型视觉系统

增强型视觉系统 (EVS) 用于显示由后视摄像头和环视摄像头拍摄的视频。在虚拟化 AAOS 中,EVS 堆栈可以从使用 VirtIO-video 驱动程序的虚拟化 V4L2 流式传输设备访问视频流。

车库模式

如需了解详情,请参阅什么是车库模式?

进入和退出车库模式由车载 HAL 发送的 AP_POWER_STATE_REQ 属性触发。在虚拟化模式下,车库模式从主机端触发。主机虚拟机应保持开机状态,以便为 Android 虚拟机提供虚拟设备,直到 Android 关机。主机虚拟机上的 VHAL 服务器会向 AAOS 客户机虚拟机发送关闭信号。收到信号后,VHAL 客户端(即 AAOS 虚拟机)会进入车库模式,并开始发送检测信号,以使主机虚拟机保持活动状态。

转储状态

在为虚拟化 AAOS 生成 bug 报告时,包括主机虚拟机信息很有用,这样开发者就可以更全面地了解系统。为此,trout 参考实现实现了 IDumpstateDevice HAL,该 HAL 可通过 GRPC-vsock 收集主机虚拟机信息。以 tar 格式打包的主机虚拟机信息在 bug 报告中命名为 dumpstate_board.bin,而转储日志位于 dumpstate_board.txt

如需配置要执行的命令,请执行以下操作:

  1. 将配置详细信息从下面的文件复制到一个 XML 文件中,例如 config.xml
    <dumpstateHalConfiguration version="1.0">
        <services>
            <service name="coqos-virtio-blk"        command="/bin/journalctl --no-pager -t coqos-virtio-blk"/>
            <service name="coqos-virtio-net"        command="/bin/journalctl --no-pager -t coqos-virtio-net"/>
            <service name="coqos-virtio-video"      command="/bin/journalctl --no-pager -t coqos-virtio-video"/>
            <service name="coqos-virtio-console"    command="/bin/journalctl --no-pager -t coqos-virtio-console"/>
            <service name="coqos-virtio-rng"        command="/bin/journalctl --no-pager -t coqos-virtio-rng"/>
            <service name="coqos-virtio-vsock"      command="/bin/journalctl --no-pager -t coqos-virtio-vsock"/>
            <service name="coqos-virtio-gpu-virgl"  command="/bin/journalctl --no-pager -t coqos-virtio-gpu-virgl"/>
            <service name="coqos-virtio-scmi"       command="/bin/journalctl --no-pager -t coqos-virtio-scmi"/>
            <service name="coqos-virtio-input"      command="/bin/journalctl --no-pager -t coqos-virtio-input"/>
            <service name="coqos-virtio-snd"        command="/bin/journalctl --no-pager -t coqos-virtio-snd"/>
            <service name="dumpstate_grpc_server"   command="/bin/journalctl --no-pager -t dumpstate_grpc_server"/>
            <service name="systemd"                 command="/bin/journalctl --no-pager -t systemd"/>
            <service name="systemctl"               command="/bin/systemctl status"/>
            <service name="vehicle_hal_grpc_server" command="/bin/journalctl --no-pager -t vehicle_hal_grpc_server"/>
        </services>
        <systemLogs>
            <service name="dmesg" command="/bin/dmesg -kuPT"/>
        </systemLogs>
    </dumpstateHalConfiguration>
    
  2. 在启动时,将新 XML 文件的路径传递给转储状态服务器。例如:
    --config_file my_config.xml
    

其他子系统

VirtIO 已经为块存储、网络、控制台、输入、套接字和熵等组件提供了明确定义的接口。对于这些子系统,AAOS 按原样使用驱动程序,如 virtio-blkvirtio-inputvirtio-consolevirtio-net

在虚拟化 AAOS 参考平台中,系统会使用 mac80211_hwsim 支持 Wi-Fi 以启用 VirtWifi 无线网络,该网络随后使用 virtio-net 隧道将网络流量发送到主机虚拟机,主机虚拟机可以直接访问实际 Wi-Fi 网络。