尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Xvisor 源码深度解析:架构、vCPU 调度与内存虚拟化实现

发布时间:2026/9/29 1:16:02

资讯中心
01
ARTICLE

Xvisor 源码深度解析:架构、vCPU 调度与内存虚拟化实现

Xvisor 源码深度解析:架构、vCPU 调度与内存虚拟化实现
虚拟化这行当里大家张口闭口 KVM、Xen、VMware但真到要抠底层实现、想搞明白一条指令从 Guest 到 Host 到底走了几步的时候很多人就卡壳了。Xvisor 这个开源 Hypervisor 在国内讨论度不算高但它的代码结构干净、层次分明特别适合拿来啃虚拟化的源码。我自己前前后后花了小半年时间读它的代码从vmm_init一路跟到 vCPU 的上下文切换中间踩了不少坑也攒了一堆笔记。这篇就把这些笔记整理出来聊聊 Xvisor 的整体架构、核心数据结构、vCPU 调度、内存虚拟化和设备虚拟化这几块顺带说说读源码时容易绕进去的地方。不管你是刚接触 Hypervisor 的新手还是想从 KVM 换换口味看看别的实现的老手应该都能捞到点东西。1. 为什么挑 Xvisor 来读虚拟化源码1.1 读源码这件事选对项目比努力更重要虚拟化源码不好读这是共识。KVM 跟 Linux 内核缠在一起几万行代码散落在arch/x86/kvm、virt/kvm各处读着读着就迷失在调度器、内存管理的汪洋里。Xen 的代码量更大而且历史包袱重PV 和 HVM 两套路径交织新手很容易劝退。Xvisor 不一样它是个 Type-1裸机型Hypervisor代码量相对可控核心逻辑集中在core/、arch/、drivers/几个目录下模块边界清晰读起来有种终于能看清全貌的爽感。Xvisor 的定位是轻量级、可移植、支持全虚拟化的 Hypervisor最早由 Anup Patel 发起现在在 GitHub 上持续维护。它支持 ARM、ARM64、RISC-V、x86 等多种架构能跑在真实硬件上也能在 QEMU 里模拟运行。对读源码来说这种能在 QEMU 里跑起来的特性太重要了——你可以改一行代码重新编译启动看日志验证自己的理解对不对。这种即时反馈是纯静态阅读给不了的。1.2 Xvisor 的代码组织先看目录再钻细节拿到一个陌生项目我习惯先tree一下看目录结构。Xvisor 的顶层目录大致是这样core/Hypervisor 的核心包括 vCPU 管理、调度、内存管理、设备框架、中断处理等是读源码的主战场。arch/按架构分目录arch/arm、arch/arm64、arch/riscv、arch/x86每个下面有cpu/、mmu/、vcpu/等负责架构相关的底层实现。drivers/各种设备驱动比如串口、网卡、显示等Guest 访问设备时最终会走到这里。libs/通用库字符串、链表、数学运算之类。include/头文件数据结构定义基本都在这里。读源码的顺序我建议是先看include/里的核心结构体定义搞清楚struct vcpu、struct vmm_addr_space、struct vmm_guest这些长什么样然后进core/看初始化流程和主循环最后按需深入arch/和drivers/。这个顺序能让你先建立骨架再填血肉不至于一上来就陷进某个函数的细节里出不来。1.3 搭建一个能跑起来的调试环境光读不跑理解会打折扣。Xvisor 在 QEMU 里跑起来其实不难以 ARM64 为例大致流程是# 拉代码 git clone https://github.com/xvisor/xvisor.git cd xvisor # 配置交叉编译工具链以 aarch64 为例 export CROSS_COMPILEaarch64-linux-gnu- # 选择默认配置 make ARCHarm64 generic-defconfig # 编译 make ARCHarm64 # 用 QEMU 启动 qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic \ -kernel build/vmm.bin -device loader,filebuild/vmm.bin,addr0x0这里有个坑Xvisor 的启动镜像格式和普通 Linux 内核不一样它需要vmm.bin这种扁平二进制加载地址也要对。我第一次跑的时候因为地址填错QEMU 直接卡死没有任何输出排查了半天才发现是-device loader的addr参数问题。建议先用官方文档里给的 QEMU 命令跑通再自己改。跑起来之后你会看到 Xvisor 的启动日志打印 CPU 信息、内存布局、初始化了哪些子系统。这时候配合-s -S参数启动 QEMU再用 GDB 连上去就能单步调试了。能单步跟一遍vmm_init比读十遍代码都管用。2. Xvisor 的启动流程与核心数据结构2.1 从第一条指令到 vmm_init启动链路拆解Xvisor 的启动入口在arch/arm64/cpu/entry.S以 ARM64 为例第一条指令开始执行时CPU 还处于 EL2Hypervisor 异常级别。这段汇编做的事情很关键设置栈指针、保存启动参数比如设备树地址、然后跳转到 C 语言的vmm_init。为什么要有这么一段汇编因为 C 语言函数运行需要栈而刚上电时栈还没建立所以必须先用汇编把栈搭好。另外启动时 CPU 的一些状态比如 MMU 是否开启、缓存是否使能是不确定的汇编里也要做相应处理。这段代码不长但每一行都有讲究建议对照 ARM 架构手册看。vmm_init在core/vmm_init.c里是整个 Hypervisor 的初始化总入口。它按顺序做这几件事初始化早期控制台这样后面才能打印日志。解析设备树获取内存布局、CPU 数量等信息。初始化内存管理子系统vmm_host_memory。初始化 vCPU 管理子系统。初始化调度器。初始化设备框架和驱动。创建第一个 Guest通常是 Guest0并启动它。这个顺序不能乱因为后面的子系统依赖前面的。比如调度器初始化需要知道有多少个 vCPU而 vCPU 的创建又需要内存管理已经就绪。读vmm_init的时候建议把每个子系统的初始化函数都点进去看一眼哪怕不深究细节也要知道它大概干了什么这样对整个系统的启动脉络就有数了。2.2 struct vmm_guest一个 Guest 到底包含什么struct vmm_guest是描述一个虚拟机的核心结构体定义在include/vmm/vmm_guest.h。它大致包含这些字段idGuest 的唯一标识。nameGuest 名字调试时很有用。addr_spaceGuest 的地址空间管理 Guest 的物理内存映射。vcpu_arrayvCPU 数组一个 Guest 可以有多个 vCPU。vcpu_countvCPU 数量。device_list这个 Guest 拥有的虚拟设备列表。reset、init、exit等回调函数Guest 生命周期管理。理解这个结构体的关键是addr_space和vcpu_array。addr_space决定了 Guest 能看到什么样的内存vcpu_array决定了 Guest 能跑多少个核。这两个东西配合起来就构成了一个 Guest 的基本运行环境。我读这块的时候有个体会Xvisor 把Guest 是什么这件事抽象得很干净。Guest 不直接管内存怎么映射也不直接管 vCPU 怎么调度它只是持有这些资源的引用具体的活儿交给addr_space和调度器去干。这种职责分离的设计读起来思路很清晰自己写系统的时候也可以借鉴。2.3 struct vmm_vcpuvCPU 的状态机与上下文struct vmm_vcpu定义在include/vmm/vmm_vcpu.h是读源码时绕不开的结构体。它最核心的部分是struct vmm_vcpu_context也就是 vCPU 的上下文保存了 Guest 运行时的寄存器状态。vCPU 有个状态机状态定义在enum vmm_vcpu_state里主要有状态含义VMM_VCPU_STATE_UNKNOWN初始未知状态VMM_VCPU_STATE_INITIALIZED已初始化但还没准备好运行VMM_VCPU_STATE_READY就绪可以被调度VMM_VCPU_STATE_RUNNING正在运行VMM_VCPU_STATE_PAUSED暂停VMM_VCPU_STATE_HALTED停止状态之间的转换由调度器和事件驱动。比如一个 vCPU 被调度器选中就从 READY 变成 RUNNING执行了 WFIWait For Interrupt指令就变成 HALTED等中断来了再变回 READY。这里有个容易混淆的点vCPU 的状态和物理 CPU 的状态是两回事。物理 CPU 可能正在跑某个 vCPU也可能在跑 Hypervisor 自己的代码。vCPU 的状态描述的是这个虚拟核现在处于什么阶段跟它当前是否真的在物理核上执行没有必然关系。读代码时要把这两个概念分开。2.4 地址空间抽象vmm_addr_space 的设计意图struct vmm_addr_space是 Xvisor 内存虚拟化的核心抽象定义在include/vmm/vmm_addr_space.h。它描述了一个地址空间里面包含多个区域region每个区域有起始地址、大小、属性等。为什么要有这层抽象因为 Hypervisor 需要管理多种地址空间Host 的地址空间、每个 Guest 的地址空间、甚至设备 MMIO 的地址空间。如果每种都单独写一套管理逻辑代码会非常冗余。Xvisor 用vmm_addr_space统一抽象配合vmm_addr_space_region描述具体区域就能用同一套代码处理不同场景。读这块的时候重点关注vmm_addr_space_map和vmm_addr_space_unmap这两个函数。它们负责在地址空间里建立和拆除映射。映射的建立过程其实就是 Guest 物理地址到 Host 物理地址或 Host 虚拟地址的转换规则的注册过程。后面讲内存虚拟化时会再展开。3. vCPU 调度Xvisor 怎么决定下一个跑谁3.1 调度器的基本模型每个物理 CPU 一个运行队列Xvisor 的调度器在core/vmm_scheduler.c。它的模型不复杂每个物理 CPU 维护一个运行队列run queue队列里放的是处于 READY 状态的 vCPU。物理 CPU 空闲时就从自己的运行队列里挑一个 vCPU 来跑。这个设计和 Linux 的 CFS 调度器思路类似但简单得多。Xvisor 没有搞复杂的红黑树而是用链表加优先级的方式管理 vCPU。每个 vCPU 有个priority字段调度时选优先级最高的。同优先级的按先来后到FIFO处理。为什么不用更复杂的调度算法因为 Hypervisor 的调度目标和通用操作系统不一样。Hypervisor 更关心的是实时性和可预测性而不是公平性和吞吐量。一个 Guest 的 vCPU 被调度出去可能导致这个 Guest 卡顿所以调度决策要快、要可预测。简单的优先级加 FIFO虽然粗糙但胜在行为确定调试起来也容易。3.2 vCPU 上下文切换保存和恢复到底存了什么上下文切换是虚拟化的核心操作之一。当调度器决定从 vCPU A 切换到 vCPU B 时需要把 A 的寄存器状态保存起来再把 B 之前保存的状态恢复回去。Xvisor 里这个操作由arch/arm64/vcpu/vcpu_asm.S里的vmm_vcpu_switch实现以 ARM64 为例。它保存的寄存器包括通用寄存器 x0-x30栈指针 SP程序计数器 PC也就是 ELR_EL2程序状态寄存器 SPSR_EL2系统寄存器比如 TTBR0_EL1、TTBR1_EL1、VBAR_EL1 等这里有个关键点Guest 运行在 EL1Hypervisor 运行在 EL2。当从 Hypervisor 切换到 Guest 时需要做异常级别的切换从 EL2 降到 EL1这个动作由eret指令完成。eret会从 ELR_EL2 恢复 PC从 SPSR_EL2 恢复处理器状态从而实现异常级别的切换。读这段汇编的时候建议对照 ARM 架构手册里的异常处理章节。搞清楚 ELR_EL2、SPSR_EL2 这些系统寄存器的作用以及eret指令的行为整个切换过程就通了。我第一次读的时候没看手册对着代码猜了半天效率很低。3.3 调度触发的时机主动让出与被动抢占vCPU 的调度触发有两种情况主动让出和被动抢占。主动让出是指 vCPU 自己执行了某些指令导致它不再适合继续运行。比如执行了 WFI等待中断或者执行了 HVCHypervisor Call请求 Hypervisor 服务。这时候 vCPU 会主动调用调度器把自己从 RUNNING 变成 HALTED 或 READY然后触发一次调度。被动抢占是指 Hypervisor 因为某些原因强制把当前 vCPU 换下来。比如时间片用完或者有更高优先级的 vCPU 变成 READY 了。被动抢占通常由定时器中断触发在中断处理程序里调用调度器。这两种触发方式在代码里的入口不一样但最终都会走到vmm_scheduler_switch这个函数。读代码时可以把这两个入口都找出来看看它们是怎么汇合的这样对调度器的调用时机就有完整认识了。3.4 调度器的初始化与 vCPU 的注册调度器初始化在vmm_scheduler_init里主要做两件事初始化每个物理 CPU 的运行队列注册调度器的相关回调。vCPU 的注册则发生在创建 vCPU 的时候。vmm_vcpu_create会分配 vCPU 结构体初始化它的状态为 INITIALIZED然后把它加到某个物理 CPU 的运行队列里此时状态还是 INITIALIZED不会被调度。等 Guest 启动vCPU 状态变成 READY才会真正参与调度。这里有个细节值得注意vCPU 创建时可以选择绑定到哪个物理 CPU。如果不指定就由调度器决定。绑定affinity这个机制在多核场景下很重要因为 vCPU 在不同物理核之间迁移会带来缓存失效的开销。Xvisor 支持设置 vCPU 的 affinity读代码时可以留意一下这个字段是怎么用的。4. 内存虚拟化从 Guest 物理地址到 Host 物理地址4.1 两阶段地址翻译Stage-1 和 Stage-2ARM 架构的内存虚拟化用的是两阶段翻译。Guest 里运行的代码用的是虚拟地址VA先经过 Stage-1 翻译变成 Guest 物理地址IPAIntermediate Physical Address再经过 Stage-2 翻译变成 Host 物理地址PA。这两阶段翻译分别由 Guest 的页表和 Hypervisor 的页表控制。Xvisor 作为 Hypervisor主要负责 Stage-2 翻译也就是 IPA 到 PA 的映射。Stage-1 翻译由 Guest 自己管理Hypervisor 一般不干预除非要做内存去重之类的优化。Stage-2 翻译的页表基址寄存器是 VTTBR_EL2。Xvisor 在创建 Guest 地址空间时会分配页表把基址写到 VTTBR_EL2 里。当 CPU 在 EL1 执行 Guest 代码时硬件会自动用 VTTBR_EL2 指向的页表做 Stage-2 翻译。理解这个机制的关键是搞清楚谁管哪一段。Guest 管 VA 到 IPAHypervisor 管 IPA 到 PA。Guest 以为自己访问的是物理地址实际上还要再过一层 Hypervisor 的映射。这种欺骗正是虚拟化的精髓所在。4.2 vmm_addr_space 的映射建立过程前面提到vmm_addr_space是地址空间的抽象现在来看它的映射是怎么建立的。以 Guest 内存映射为例流程大致是Guest 启动时Xvisor 根据设备树或配置知道要给这个 Guest 分配多少内存。调用vmm_addr_space_map传入 Guest 的地址空间、IPA 起始地址、大小、对应的 Host 物理内存信息。vmm_addr_space_map内部会分配 Stage-2 页表项建立 IPA 到 PA 的映射。映射建立后Guest 访问这段 IPA 时硬件会自动翻译到对应的 PA。这里有个容易踩的坑页表项的属性设置。ARM 的 Stage-2 页表项里有内存属性字段比如是否可缓存、是否可共享、访问权限等。如果属性设错可能导致 Guest 访问内存时出现数据不一致或者权限异常。Xvisor 里对这些属性有默认配置但特殊场景比如设备 MMIO需要单独设置。读代码时要留意vmm_addr_space_map的 flags 参数是怎么处理的。4.3 页表管理的细节多级页表与按需分配ARM64 的 Stage-2 翻译支持多级页表通常是 3 级或 4 级取决于 IPA 的位宽和页大小。Xvisor 的页表管理代码在arch/arm64/mmu/下。页表的分配策略是按需分配。一开始只分配顶级页表当需要映射某个地址时才逐级分配下级页表。这样做的好处是节省内存——一个 Guest 可能只用了几百 MB 内存但 IPA 空间可能有几十 GB如果一开始就把所有页表都分配好浪费太大。按需分配的实现里有个页表遍历的过程从顶级页表开始根据地址的各位段逐级找到对应的页表项。如果中间某级页表不存在就分配一个。这个过程在vmm_mmu_get_next_table之类的函数里实现。读的时候注意地址位段是怎么切的这跟页大小和级数有关。4.4 内存虚拟化中的常见问题与排查思路内存虚拟化出问题症状往往很隐蔽。Guest 可能莫名其妙地崩溃或者数据读出来是错的但又不报明显的错误。根据我的经验常见问题有这么几类第一类是映射缺失。Guest 访问了某个 IPA但 Hypervisor 没有为这个 IPA 建立 Stage-2 映射导致翻译失败触发异常。这种问题通常在 Guest 启动早期出现因为那时候内存布局还没完全建立。排查方法是看 Hypervisor 的异常日志找到出错的 IPA然后检查这个 IPA 是否在映射范围内。第二类是属性错误。映射建立了但页表项的内存属性设得不对。比如该可缓存的地方设成了不可缓存导致性能极差或者该只读的地方设成了可写导致 Guest 意外修改了不该改的数据。这类问题比较难查因为不会直接报错而是表现为性能异常或数据异常。排查时可以用 Hypervisor 提供的调试命令dump 出页表项看看属性位。第三类是映射冲突。同一个 IPA 被映射了两次或者映射到了错误的 PA。这种问题通常出现在动态修改映射的场景比如 Guest 做内存热插拔。排查方法是检查映射建立和拆除的代码路径看看有没有遗漏的清理操作。5. 设备虚拟化Guest 怎么访问一个虚拟网卡5.1 设备虚拟化的两种思路全虚拟化与半虚拟化设备虚拟化有两条路全虚拟化和半虚拟化。全虚拟化是指 Hypervisor 模拟一个真实的硬件设备Guest 用访问真实硬件的方式访问它不需要修改 Guest 代码。比如模拟一个 Intel e1000 网卡Guest 里的 e1000 驱动能直接跑。这种方式的优点是兼容性好缺点是性能差因为每次寄存器访问都要陷入 Hypervisor。半虚拟化是指 Guest 知道自己运行在虚拟化环境里使用专门优化的接口跟 Hypervisor 通信。比如 virtioGuest 和 Hypervisor 共享一段内存通过描述符环传递数据减少了陷入次数性能好很多。缺点是需要 Guest 里有对应的驱动。Xvisor 两种都支持。它的设备框架在core/vmm_device.c驱动在drivers/下。读设备虚拟化代码时先搞清楚一个设备从创建到被 Guest 访问的完整链路再深入具体驱动的实现。5.2 设备注册与 Guest 设备树的生成Xvisor 启动时会根据配置创建虚拟设备并把这些设备注册到设备框架里。每个设备有个struct vmm_device结构体包含设备 ID、操作函数集struct vmm_device_ops、私有数据等。设备注册后Xvisor 会为 Guest 生成设备树Device Tree。Guest 启动时读取这个设备树就能发现有哪些设备可用。设备树里描述了设备的类型、寄存器地址、中断号等信息。Guest 里的驱动根据这些信息去访问设备。这里有个关键点设备树里的寄存器地址是 IPA不是 PA。Guest 访问这个 IPA 时会触发 Stage-2 翻译最终落到 Hypervisor 为这个设备分配的 Host 地址上。所以设备虚拟化的一个核心工作就是建立设备 IPA 到 Host 设备地址的映射并处理 Guest 对这些地址的访问。5.3 以虚拟串口为例一次完整的设备访问流程串口是调试时最常用的设备也是理解设备虚拟化最好的例子。Xvisor 的虚拟串口驱动在drivers/serial/下。一次完整的串口访问流程是这样的Guest 里的串口驱动往串口的发送寄存器某个 IPA写一个字符。CPU 访问这个 IPA触发 Stage-2 翻译发现这个地址被映射到了 Hypervisor 的某个处理函数或者被标记为需要陷入。如果配置了陷入CPU 会触发异常进入 Hypervisor 的异常处理程序。异常处理程序识别出这是串口访问调用串口设备的处理函数。串口处理函数把字符真正写到物理串口或者 QEMU 的模拟串口上。处理完毕返回 GuestGuest 继续执行。这个流程里第 2 步到第 4 步是关键。Xvisor 怎么知道某个 IPA 访问需要陷入答案是页表项里设置了相应的权限位。如果页表项标记为不可直接访问CPU 就会触发异常。Hypervisor 在异常处理里根据出错的 IPA 找到对应的设备再调用设备的处理函数。5.4 中断注入设备怎么通知 Guest设备访问是 Guest 到 Hypervisor 的方向中断注入是反方向设备有数据了怎么通知 GuestXvisor 的中断注入机制大致是这样设备产生中断后Hypervisor 把这个中断记录下来然后通过设置虚拟中断控制器比如 GIC 的虚拟化扩展的状态让 Guest 感知到中断。Guest 里的中断处理程序被调用处理设备数据。ARM 的 GICGeneric Interrupt Controller有虚拟化扩展支持把中断直接注入到 Guest而不需要 Hypervisor 每次都介入。Xvisor 利用了这些硬件特性减少了中断注入的开销。读这块代码时需要先了解 GIC 的虚拟化机制否则容易看不懂。中断注入的代码在core/vmm_interrupts.c和arch/arm64/gic/下。重点关注vmm_interrupt_raise和vmm_interrupt_inject这两个函数它们分别负责记录中断和注入中断。6. 读 Xvisor 源码时容易绕进去的几个地方6.1 异常级别切换的代码路径容易看晕ARM 有 EL0 到 EL3 四个异常级别Guest 跑在 EL1Hypervisor 跑在 EL2。代码里到处是eret、hvc、svc这些指令还有 ELR_EL2、SPSR_EL2 这些寄存器第一次读很容易晕。我的建议是画一张图把异常级别和代码路径对应起来。比如Guest 执行hvc指令从 EL1 陷入 EL2进入 Hypervisor 的hvc处理程序。Hypervisor 处理完执行eret从 EL2 返回 EL1Guest 继续执行。中断来了CPU 从 EL1 自动跳到 EL2进入 Hypervisor 的中断处理程序。Hypervisor 处理完中断执行eret返回 EL1。把这几条路径画清楚再看代码就不会迷路。我当初就是靠一张手画的图才把vcpu_asm.S里的切换逻辑理顺的。6.2 配置宏太多条件编译让人头大Xvisor 支持多种架构、多种配置代码里大量使用条件编译。同一个函数在 ARM64 和 RISC-V 下的实现可能完全不同读的时候要时刻注意自己在看哪个架构的代码。应对方法是先确定自己关注的架构然后在编辑器里把其他架构的代码折叠起来。另外generic-defconfig里的配置项也要看一眼知道哪些功能是默认开启的哪些是关闭的。不然你可能会对着一段永远不会被编译的代码研究半天。6.3 调试手段有限日志是主要抓手Xvisor 的调试手段不像 Linux 那么丰富没有 ftrace、perf 这些工具。主要靠日志和 GDB。日志方面Xvisor 有vmm_printf之类的函数可以在关键路径打印信息。我读代码时习惯在关键函数入口加一行打印跑一遍看调用顺序这样能快速建立谁调用谁的认识。当然加打印要注意别加在太热点的路径上否则日志会刷屏反而看不清。GDB 方面配合 QEMU 的-s -S参数可以单步调试。设置断点在vmm_init、vmm_scheduler_switch这些关键函数上一步步跟能看到很多静态阅读看不到的细节比如某个变量在运行时的实际值。6.4 文档少社区讨论也不多Xvisor 的文档确实不算丰富官方 wiki 有一些但不够细。社区讨论也主要集中在邮件列表和 GitHub issue 上中文资料更少。这种情况下读代码本身就成了主要的学习方式。我的经验是遇到不懂的地方先看结构体定义和函数注释再结合 ARM 架构手册理解硬件行为最后用 QEMU 跑一遍验证。这三板斧下来大部分问题都能解决。实在搞不懂的可以去 GitHub 上搜相关的 issue或者看看 commit log有时候作者的提交信息里会解释设计意图。7. 从 Xvisor 源码里能学到什么读 Xvisor 源码收获不只是知道了一个 Hypervisor 怎么实现更重要的是理解了一些通用的系统设计思路。比如职责分离。Xvisor 把 Guest、vCPU、地址空间、设备这些概念拆得很清楚每个结构体只负责自己的事通过清晰的接口交互。这种设计让代码可读性大大提高也方便扩展。自己写系统的时候这种一个结构体只干一件事的原则很值得借鉴。再比如抽象的力量。vmm_addr_space这个抽象把 Host 地址空间、Guest 地址空间、设备地址空间统一起来避免了大量重复代码。抽象做得好代码量能少一大截维护起来也轻松。还有就是简单优先的取舍。Xvisor 的调度器没有追求复杂的公平性算法而是选择了简单可预测的优先级加 FIFO。这种取舍在 Hypervisor 场景下是合理的因为可预测性比吞吐量更重要。做技术选型时想清楚自己的场景最需要什么比盲目追求先进更重要。最后说个实际的如果你正在做嵌入式虚拟化或者想在自己的项目里引入 HypervisorXvisor 是个不错的参考。它的代码量适中架构清晰改起来也相对容易。我见过一些项目直接基于 Xvisor 做二次开发加自己的设备驱动或者调度策略效果还不错。读源码这件事急不得。我读 Xvisor 的前两周基本都在打转今天看懂了明天又忘了。后来改变策略先跑起来再抓主线最后抠细节效率才上来。如果你也在读建议别一上来就啃最难的 MMU 代码先从启动流程和 vCPU 管理入手把主干摸清楚再往深处钻。遇到卡壳的地方跑一遍 QEMU加几行日志往往比盯着代码看半天管用。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。