0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

探索Mac mini M1的QEMU/KVM虚拟化实现

OSC开源社区 来源:OSC开源社区 2023-04-26 14:15 次阅读

背景

目前业界云平台一般会提供 Windows 虚拟机和 Linux 虚拟机,用户可以在这些虚拟机上部署符合 Windows生态和 Linux 生态的服务和应用。MacOS 作为 Apple 生态的基本操作系统,MacOS 虚拟化的实现将会为使用 Apple 生态的用户带来很大的便利,如直接在 MacOS 的虚拟机上进行测试、构建iOS 应用,甚至使用 MacOS 虚拟机作为办公环境等。

目前社区对于 Intel x86 Mac mini 平台的 MacOS虚拟化方案已经比较成熟,随着 2020年 Apple 推出自研的 ARM64 M1芯片,Mac mini 增加了对 ARM64 平台的支持,后续 Apple 将逐渐从 Intel x86 芯片转向自研的 ARM64 芯片。相对于 Intel x86 平台,社区对 ARM64 平台的 MacOS 虚拟化方案还在探索和起步阶段,于是字节跳动 STE 团队和 App Infra 团队率先进行了深入的研究,本文将与大家分享针对采用 ARM64 M1 芯片的 Mac mini M1 机型虚拟化方案的探索和实现。

方案介绍

什么是 Mac mimi 虚拟化

Mac mini 虚拟化是指在一台 Mac mini 物理机上模拟出多个互相隔离的 Mac mini 虚拟机,使得每个虚拟机用户都认为自己在一台真正的物理机上以独占的方式运行。

整个方案中,我们采用了云平台常见的 Linux + KVM(Kernel-based Virtual Machine)+ QEMU(Quick EMUlator) 这样全开源的虚拟化软件栈,以方便把控和实现对 Mac mini M1 机型(包括 CPU / MEM /片上设备/外设等)的全方位模拟。在 Mac mini M1 的虚拟化实现中,我们基于 QEMU 既有的机型框架实现了对 Mac mini M1 的软件模拟(TCG, Tiny Code Generator)支持,又通过 KVM 为Mac mini M1 提供了ARM64平台硬件虚拟化能力的支持。

1616609a-e3f6-11ed-ab56-dac502259ad0.png

Linux

Asahilinux 对 M1 机型上的硬件设备做了足够多的逆向工程分析,并根据推出来的硬件逻辑来尝试实现linux下的各设备驱动,目前已实现了对 M1 机型的基本支持,其中对 M1 GPU的支持也在不断完善中。Asahilinux这部分工作也在不断的合入Linux upstream。

我们采用Asahilinux作为运行在M1裸机上的操作系统。依赖Asahilinux,我们可以获得M1 的 linux 运行时物理机环境,并以此为基础逐步构建和实现M1虚拟化所需的虚拟化软件栈。

QEMU

QEMU 作为机型/系统模拟的常用软件,构造了机型模拟的基本框架,并在此基础上提供了不同平台上很多具体机型的模拟实现,比如 x86 平台的 piix 和 Q35 机型,ARM 的 virt 和 raspi2 等。在 M1 机型的虚拟化中我们需要基于 ARM64 通用机型,构造一个新的 M1 机型,并集成到 QEMU 提供的机型模拟框架中。

QEMU 提供的基本模拟方式是纯软件的,即对于每一条虚拟机内部执行的指令都需要退出到 QEMU 的上下文来翻译执行(TCG),该方式性能很低。KVM 可以帮助我们解决 QEMU 纯软件模拟带来的低性能问题。

KVM

KVM 作为 Linux 下支持虚拟化的内核模块,将虚拟化场景下的硬件加速功能通过 ioctl 的方式导出给QEMU使用。在 KVM 的支持下,虚拟机内部的常用指令将不再需要退出到QEMU来模拟执行,而是在虚拟机的 CPU 上下文中直接执行,只有个别特权指令才需要退出到物理机上,由物理机来具体执行。对于虚拟机的内存访问,也不再需要 QEMU 进行页表翻译,而是直接依赖硬件实现的两级页表翻译机制(虚拟机内部页表实现 Guest Virtual Address向Guest Physical Address的转化,使用stage2 page table 实现 Guest Physical Address向Host Physical Address的转化),从而实现内存的快速访问。

M1机型的模拟

了解了基本的虚拟化软件栈后,我们开始考虑如何模拟一台真正的 Mac mini M1。那么,模拟 M1 机型包括模拟哪些内容呢?

M1 VCPU

QEMU 中使用线程来模拟 VCPU,即每一个 VCPU 对应一个单独的 QEMU 线程;使用必要的数据结构记录 VCPU 相关的信息,如寄存器/运行状态等。区别于其他机型的 VCPU,M1 需要增加的特有支持如下: 1)多个 M1 特有寄存器和对应的读写逻辑; 2)对 Apple PMGR(电源管理模块)的模拟。M1 通过 PMGR 来实现多核(SMP,symmetric multiprocessing)的唤醒和管理;

3)Cluster 内和 Cluster 间的 Fastipi 通信机制;

16238220-e3f6-11ed-ab56-dac502259ad0.png

M1 内存布局

M1 的内存布局,是指将VM的整个地址空间按照设备和用途进行合理的划分,如 Flash device、CPU 相关的固件、中断控制器、Spec 设备地址、MMIO 和 PCI 地址范围以及虚拟内存等。在 QEMU 层设置 M1 机型的内存布局需要注意以下几个问题: 1)注意 CPU 地址域和设备地址域的关系; 2)System Memory 范围不能跟 DTB(Device Tree Blob) 中各设备的物理地址空间冲突; 3)需要连续的足够大的地址范围来映射 System Memory;

16302c6e-e3f6-11ed-ab56-dac502259ad0.png

System Memory 作为虚拟机的主存,在启动初期会被用来存放内核镜像、设备树以及Ramdisk等,这些内容的加载地址也需要额外配置,注意不能存在交叉,以避免内存中内容互相覆盖。

M1 设备模拟

区别于 M1 物理机,M1 虚拟机的存储和网络主要采用虚拟化场景下常见的 virtio-pci 设备,如 virtio-blk / virtio-net 设备等。我们需要在模拟的 M1 机型上插上 PCIE 的线,其下接各种 PCI / PCIE 设备。另外,为了让设备的中断能够顺利分配、触发并递送到目的 VCPU 中,还需要模拟 M1 的中断控制器 AIC。

AIC 是 M1 Apple Interrupt Controller 的简称, 主要负责中断掩码/中断状态设置、接受/递送中断等。对 AIC 的模拟主要是对上述的功能的模拟,可以通过 Asahilinux 的 AIC 驱动部分的代码逻辑来推断出 AIC 具体地址空间的含义,从而实现 AIC 的模拟。对 AIC 的模拟中我们使用了 MMIO(Memory-Mapped IO) 空间来实现对 AIC 内部相关硬件地址的访问逻辑。

对 M1 新插上的 PCIE 总线的模拟基于 QEMU 提供的通用 PCIE 线——gpex-pcihost 来实现,在通用的 gpex-pcihost 模型的基础上,我们需要根据 M1 的 DTB 文件来制定 M1 PCIE 总线配置空间和bar空间,以及其下 PCI 设备的 PCI 配置空间和 Bar 地址空间范围。

整体的中断设计如下:

将模拟的 M1 PCIE (gpex-pcihost )总线的 4 个 gpio_out pin 依次连接到 AIC 的 gpio-in pin 上去。gpex-pcihost 通过该连线传递中断给AIC;

AIC 有 cpu_num 个 gpio_out pin ,这些引脚分别连接到各个 CPU 上,AIC 通过该连线递送中断给 CPU。

1638770c-e3f6-11ed-ab56-dac502259ad0.png

至此,我们已经在 QEMU 层面实现了对 M1 的 CPU、PMGR、AIC、PCIE 总线等设备的基本模拟,可以通过 QEMU 命令在 PCIE 线上插上所需的 PCI 设备,如 virtio-blk、virtio-net 等,来尝试启动 MacOS 虚拟机了。

虚拟化下的MacOS和启动

既然已经完成了对 M1 虚拟机所需要的基本组件的模拟,接下来我们考虑如何在模拟的 M1 机型上启动真正的 MacOS 。

预启动阶段

MacOS 的启动流程是怎样的呢?MacOS 在 M1 物理机上的启动流程如下(更多详见M1 启动过程:https://eclecticlight.co/2022/01/05/booting-an-m1-mac-from-hardware-to-kexts-2-llb-and-iboot/)

机器上电,由 Boot ROM 验证并加载位于 Flash 中的 LLB(Low Level Bootloader)

LLB 设置安全策略、解密/认证并加载位于 preboot volume 中的 iBoot 文件

iBoot 根据 DTB 对 M1 固件和设备做早期的初始化,验证并加载 KernelCache(KernelCache 是 MacOS 启动镜像,类似于 linux 的 Image.gz),更新并加载 DTB

进入 MacOS 内核启动流程。

其中无论是 LLB 还是 iBoot 都是闭源的,这为我们完整的模拟 M1 启动带来了难处。为了能成功的在 QEMU / KVM 虚拟化场景下启动 M1,我们对 MacOS 的启动过程做了简化,割舍掉 LLB 和 iBoot 阶段,直接由 QEMU 来完成早期设备的初始化(如 CPU 状态等)、KernelCache 文件的解析与加载、DTB 的更新与加载等。

在 QEMU 完成早期初始化和预加载后,虚拟机启动时刻的 System Memory 地址空间布局状态如下:

163d03c6-e3f6-11ed-ab56-dac502259ad0.png

其中,各文件的含义如下:

KernelCache:包含了 XNU 内核和 kext 内核扩展,是 MacOS 的内核镜像

Ramdisk:HFS 格式的 rootfs,可作为 MacOS 的启动盘使用,非必需(当使用 virtio-blk 盘作为启动盘时,可取消 Ramdisk 的使用)

DTB:M1 的设备树,MacOS 内核需要通过 DTB 来获取到 M1 的硬件信息,QEMU 模拟的 M1 设备信息(如中断路由和设备地址信息等)要和 DTB 中维护的信息一致

xnu_arm64_boot_args:Macos 内核的启动参数

随后 QEMU 将 Primary VCPU 的 pc 寄存器设置为 KernelCache 中的 start 函数地址,开始VCPU 的运行。

启动流程

MacOS 在 QEMU / KVM 虚拟化场景下整体的启动流程如图,大致分如下四个阶段:

1. QEMU 阶段

该阶段在 QEMU 中实现,主要是为 MacOS 的运行做准备,具体包括 VCPU 线程的创建,各设备状态的初始化,System Memory 的加载映射(如KernelCache、 Ramdisk、DTB),bootargs 的创建和 DTB 数据的更新等,随后将 VCPU0 的 pc 寄存器指向 MacOS XNU 内核的_start 函数,VCPU0 开始执行。

2. 早期初始化阶段

在 MacOS 启动早期的汇编代码阶段,_start 函数设置了内核启动早期的中断/异常向量表和页表等,并对内核参数进行解析,配置 MMU 和 vbar 等。

164751f0-e3f6-11ed-ab56-dac502259ad0.png

3. Kernel 阶段

在 arm_init 和 kernel_bootstrap 中, 主要是第一个内核线程启动前的准备工作,如进行 KernelCache 解析、DTB 转化,console 设置,per cpu data 设置和 process 初始化、系统内存的初始化以及内核各个子系统的启动。

kernel_bootstrap_thread/bsd 中,主要是启动其他的系统维护线程构筑 MacOS 的运行时环境,如初始化 I/O Kit 框架,初始化 BSD 子系统。其间还会根据 DTB 的配置来设置 SMP,唤醒其他 VCPU;其中, I/O Kit 是MacOS XNU 内核为设备驱动程序提供的完整的运行时环境,用户可以基于 I/O Kit 提供的面向对象能力来快速高效地编写自己的驱动程序。

在 bsdinit 中,初始化 BSD 核心子系统, 挂载 rootfs 并启动 /sbin/launched。

4. 用户态服务和进程

/sbin/launched 进程的 pid 为1,为第一个用户态进程,它根据预定的安排或者实际的需要加载位于 /System/Library/LaunchAgents 和 /System/Library/LaunchDeamons 下的其他应用程序或作业,包括守护程序如 atd、crond、inetd 等,以及代理程序如 GUI shell、 Terminal shell 等。

至此 MacOS M1 基本启动已经完成。

虚拟化下完整的MacOS 软件栈

QEMU/KVM 虚拟化场景下的 MacOS 整体架构图如下,从下到上依次是M1物理机、支持 M1 各类型设备的 Asahilinux 内核、提供硬件加速功能的内核模块 KVM、实现 M1 机型模拟的用户态 QEMU,运行在 QEMU 上的 M1 Guest OS。

164e2bc4-e3f6-11ed-ab56-dac502259ad0.png

其中,M1 Guest OS 在 XNU 内核的基础上会加载多个 Kext 以实现完整的 MacOS 功能;既支持 APFS 格式的根文件系统,也支持 HFS 格式的 Ramdisk 根文件系统;dyld 类似于 linux 上的 ld,负责加载和链接应用程序,dyld_shared_cache 提供了系统中各进程共享的基础库缓存,有效地降低了各进程通用库的内存占用率。

后续规划和展望

目前我们已经完成了 QEMU / KVM 虚拟化场景下 MacOS M1 的基本启动,后续需要有更多的优化从功能完备性、性能以及兼容性的角度来展开。

5.1 更完善的MacOS 运行时环境

目前我们的方案在 QEMU 层实现了 M1 基本设备的模拟、在 KVM 层实现了硬件加速功能、在 MacOS 中实现了部分系统服务的启动,然而整个方案与一台真正的 MacOS 还有一定的距离,如默认启动的数百个系统服务、友好的 GUI 界面、更完备的设备支持以及更好的用户支持度等等,后续将持续优化。

5.2 兼容性

在整个虚拟化方案中为了实现 MacOS 的启动,我们对 KernelCache 里的 XNU 内核和 Kext 部分进行了热 Patch。后续需要实现合理的热 patch 的工具来完成不同的 MacOS 版本热 Patch 的高效定制。

5.3 性能问题

模拟 M1 机型时,像 PMGR 和 AIC 这样的设备,我们目前是直接在 QEMU 里进行模拟的,这会使得虚拟机对 PMGR 和 AIC 的操作,都需要退回到 QEMU 中来进行具体行为的模拟,后续可考虑将这些组件集成到 KVM 中,减少用户态和内核的切换,减少虚拟化开销,提高 VM 的性能。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11342

    浏览量

    210280
  • WINDOWS
    +关注

    关注

    4

    文章

    3567

    浏览量

    89225
  • 操作系统
    +关注

    关注

    37

    文章

    6889

    浏览量

    123680
  • Mac
    Mac
    +关注

    关注

    0

    文章

    1109

    浏览量

    51649
  • 虚拟机
    +关注

    关注

    1

    文章

    931

    浏览量

    28390

原文标题:探索Mac mini M1的QEMU/KVM虚拟化实现

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    相关推荐

    苹果推出Mac电脑的自研芯片M1

    在大约 45 分钟的发布会上,苹果带来了 Mac 电脑的自研芯片 M1,同时推出了三款搭载 M1 芯片的 Mac 新品,包括 MacBook Air、
    的头像 发表于 11-11 14:13 4070次阅读

    苹果正式发布了搭载 M1 芯片新款 Mac mini

    今日,苹果正式发布了新款 Mac mini,搭载 M1 芯片。这也是苹果专为 Mac 设计的首款芯片。目前,苹果新款 Mac
    的头像 发表于 11-11 14:20 2684次阅读

    arallels:正积极开发新版适用于M1 Mac设备的虚拟应用

    本周二表示,公司正积极开发新版虚拟软件,从而确保 Parallels Desktop 应用能够支持 M1 以及后续的 Apple Silicon Mac 设备。虽然当前的 Paral
    的头像 发表于 11-12 10:22 1469次阅读

    Parallels研发虚拟应用,将适用于M1 Mac

    Parallels 本周二表示,公司正积极开发新版虚拟软件,从而确保 Parallels Desktop 应用能够支持 M1 以及后续的 Apple Silicon Mac 设备。虽
    的头像 发表于 11-12 11:22 2130次阅读

    搭载全新 M1 芯片,来看看苹果 Silicon MacBook Air/Pro/Mac mini 支持哪些软件吧

    微软宣布将在今天推出全新的 Mac Office 2019 测试版通用版,支持苹果全新的 M1 Mac mini、MacBook Air 和 13 英寸 MacBook Pro。
    的头像 发表于 11-12 16:30 3399次阅读

    苹果M1 Mac mini单核基准测试快于所有英特尔Mac

    根据最新的 Geekbench 基准测试显示,苹果最新的 Mac mini 是其首款采用 Apple Silicon M1 芯片的台式机,在单核测试中的速度大大超过所有基于英特尔的 Mac
    的头像 发表于 11-17 09:41 1829次阅读

    苹果M1芯片Mac mini外媒评测

    外媒 Techcrunch 现已发布了搭载 M1 处理器的 Mac mini 的评测,从跑分和实际应用来看,Mac mini 的性能与一同上
    的头像 发表于 11-18 11:13 7182次阅读

    M1Mac mini拆解:逻辑板尺寸比苹果12 mini更小

    最近,因为苹果的M1芯片的发布,以及搭载这个芯片的设备展现出的强大性能,让业界所有人都对苹果这个举措有了高度的关注。在这里,我们将国外读者拆解的Mac Mini展现在大家眼前,并为大家对感兴趣的
    的头像 发表于 11-19 16:17 4744次阅读

    苹果M1 Mac外置GPU有希望支持

    苹果 M1 Mac 不支持外置 GPU 可能只是暂时的,因为连接的 eGPU 仍然会被检测到。 配备 M1Mac,包括 Mac
    的头像 发表于 11-23 09:36 4517次阅读

    开发者在苹果M1 Mac上成功虚拟运行Win10 ARM

    外媒 MacRumors 报道,开发者 Alexander Graf 已经成功地在苹果 M1 Mac虚拟运行 Windows 10 ARM 系统,证明
    的头像 发表于 11-28 09:41 3441次阅读

    开发者成功在M1 Mac虚拟运行Windows on ARM

    Alexander Graf 的开发人员,已经在开源的 QEMU 虚拟方案的帮助下,成功地在 M1 Mac 设备上运行了 Windows
    的头像 发表于 11-30 16:27 2442次阅读

    苹果M1Mac系列问题汇总

    苹果推出自家研发的M1芯片系列电脑,但陆续传出灾情,现在国外有很多Mac mini M1用户出现蓝牙键盘和鼠标会造成无法联机的状况,而现在MacBook Pro、MacBook Air
    的头像 发表于 11-30 17:16 6391次阅读

    开发者成功在苹果M1 Mac虚拟运行Win10系统

    ,而且还要跑个分来嘲讽一下,你说气不气。 最近,开发者 Alexander Graf 就成功地在苹果 M1 Mac虚拟运行 Win10 ARM 系统。 利用开源的
    的头像 发表于 12-03 10:50 7442次阅读

    苹果公布M1Mac Mini的功耗数据

    去年苹果发布的M1 SoC让不少人印象深刻,极高的能耗比引发阵阵惊叹。近日,苹果官方就披露了Mac Mini M1版在测试场景下的耗电情况。
    的头像 发表于 02-02 11:51 1.2w次阅读

    QEMUKVM如何确定哪个更适合你呢?

    虚拟领域的两大巨头:QEMU vs. KVM,你该如何选择?
    的头像 发表于 08-17 14:53 3425次阅读
    <b class='flag-5'>QEMU</b>和<b class='flag-5'>KVM</b>如何确定哪个更适合你呢?