对应的印刷约定.
主要是一些编码的格式.
makefile 还有各种的登录模式.
slash(/). 分割路径.
去社区或者网站获取对应的支持.
-----------------------------------------------------------------
popek/ goldberg 理论.
参考.
https://zh.wikipedia.org/wiki/%E6%B3%A2%E4%BD%A9%E5%85%8B%E4%B8%8E%E6%88%88%E5%BE%B7%E5%A0%A1%E8%99%9A%E6%8B%9F%E5%8C%96%E9%9C%80%E6%B1%82.
等价性:一个运行于VMM下的程序,其行为应与直接运行于等价物理机上的同程序的行为完全一致。
(有一些部分虚拟化的设备)
资源控制:VMM对虚拟资源进行完全控制。
(安全性:
除了 guest 直接访问的一些 pass-through(直传)的设备, hypervisor 应该一直维护硬件的资源的控制.
)
效率性:机器指令中经常使用的那一部分应在没有VMM干预下执行。
这个理论 可以参照一本书.
-----------------------------------------------------
nomentclature.
命名法.
terminology.
术语.
-----
device, vdevs.
guest, qvm 主持一个guest, guest 在 qvm 中运行.
spell it out: 讲清楚,是关闭进程还是 guest os.
-----------------------
host, 在大多case中, 术语主机host 不是一个 主机电脑(那种桌面,笔记本用来连接 目标系统加载新的镜像 或者 调试的).
但指向 hypvervisor 或者 hyppervisor 中的一些东西, (例如, cpus 指引客户线程 去退出客户模式, 并且在 host模式继续) .
如果上下文 不能将 host 指定清晰, 我们使用"development host" 去指向 桌面.
用"host domain" 或者 "hypervisor host" 去指定 hypervisor 以及 它的组件.
讨论 优先级 或者 异常等级时, 我们会用 hypervisor host或者 hyper host domain 来判断,
hypervisor上面跑的一些进程.
-------------------------
qvm.
qvm 是一个 在hypervisor 中运行的, guest os 在qvm上运行.
hyper 为每个guest 开启一个qvm 进程,
3个guest,你就有3个qvm.
at times: 有时
qvm 有时在 hypervisor host domain 允许下运行.
有时在 它所包容的 guest 的低优先级下运行.
--------------------
vdev.
虚拟设备vdevs 有时候来表示 hypver 虚拟化的任何设备,
vdevs 的例子 包含了一个 “中断控制”, 或者以太网的设备控制器.
如果我们曾经 当作一个设备 指向一个 虚拟设备,会很疑惑,请让我们知道.
-----
Terminilogy 就是一个 未来的术语的集合.
=======================================================================================
文件名
我们使用以下术语 (nomenclature, term, terminology), 来命名对应的qnx的 虚拟化环境.
<1>.prefixes 前缀.
hypervisor 后面跟随着的是遗传发布的数字.
<2>.suffixes 后缀.
.build 这是为了qnx 以及 hypervisor,其他os的请看对应的其他文档.
.img 可以加载的img, 可以包含一个或者多个镜像.
.qvmconf. 虚拟机的配置文件, qvm进程起来之后解析 来集合 VM.
<3>
例子.
下面告诉我们如何撰写文件名字.
----------------------------------------
hypervisor release-board.type.
release 是 hypervisor 的发布number,
board 是硬件平台的名字.
type 就是文件的类型. build 或者 img 等等.
hypervisor2.0-broadwell.build.
----------------------------------------------
guestos,type.
guestos: qnx70, qnx66,linux44
如果同样的os有多个实例, qnx7a.build 以及 qnx7b.img.
linux 以及其他的使用主机的术语.
--------------------------
VM 配置文件.
qvm 进程的一个配置文件是这样的:
guest.qvmconf.
qnx7a.qvmconf. qnx7b.qvmconf.等等.
=====================================================================================
Architecture.
架构.
hypervisor 2.0 包括微内核 以及 qvm的多个实例.
这个图展现了一个 qnx hypervisor的架构 以及 访问所有虚拟以及 物理设备的一个配置文件.
不是所有的 客户机-设备 配置文件都被展示了;
那些只是 illustrate(说明) 了 一些可能的配置.
****
注意pass-through 以及 shared 配置.
message handles 以及 private memory. 等等.????
---------------------------------------------------------------------------------
支持的架构与硬件.
Arm 与 x86.
注意:
对于所有的 ARM 与 x86 平台, hyper host 需要64位的硬件,但是支持 64位和 32 位的客户机.
guest os 必须在hyper host 运行的硬件架构 上进行编译.
例如, Arm 32 以及 64 客户机 arm64 的架构.
---------------------------------------------------------------------------------------
CPU 特权等级.
一个 cpu 特权等级 控制 运行在处理器上的程序,对资源的访问权限,例如 记忆区,
I/O 口, 以及特殊的指定.
一个 客户机 比 hyper 更加低特权级别,
一个在 客户机上运行的程序 有更加低的特权,< guest level.
这个架构 从非信任的软件组件中 提供了 硬件-等级 的安全.
------------------------------------------------------------------------------------------
设计安全状态.
hyper 提供了两种的 设计安全状态(DDSs).
如果一个内部的 和 外部的检测机制 警报(提醒) 它有一个情况, 它不是被设计以其他任何方式来处理.
(说白了有个case , 之前没有定义,无法处理这个case?)
VM DSS
如果一个未定义的条件 被限定在 VM( 接待 guest的 一个qvm 进程实例).
hyper 终止了 qvm 进程实例. (以 SIGSEGV 信号).
终止了 托管qvm process的实例,终止了它的guest.
(按照之前所讲的,终止了 qvm, 也就是终止了 guest).
Hypervisor host DSS
hypervisor = qnx os + 虚拟化的插件.
导致os 移动到 它的 DSS的同样的条件 导致了 hypervisor host 移动至其 DSS.
这就是, 如果未定义的条件 不限定于 VM, hypervisor 关闭了.
这个DSS 和 QOS 2.0 DSS, 一样.
警告.
qnx hypervisor 2.0 不是一个 安全认证的 产品, 它必须 用在 安全相关的产品系统.
如果你想在一个安全相关的系统中去跑一个hypervisor,
你必须 当它变成可用的时候获取对应的qnx hyper 参数.
==============================================================================
Virual machines.
虚拟机.
一个运行的 hypervisor 组合了 一个 hypervisor 的微内核 + 它的虚拟化库 (libmod_qvm.a)
以及 一个或多个 虚拟机进程的实例.(qvm).
什么是虚拟机?
paragrphy 1.在一个qnx hyper 环境中, 每一个 vm 是一个 qvm 进程实例.
qvm 进程是在 hyper 主机 运行的 一个 OS 进程.
kernel 之外的.
每一个实例都有一个标识 标记它 所以 微内核 知道它是一个qvm进程.
(还有之前说的一些命名规则,但是这个是为了让微内核知道).
paragraphy 2.
如果你记得 VMs的任何事情, 记住从guest os 的视角看,
托管guest 的Vms 就是一个 硬件.
这意味着 ,只是作为一个 运行在 物理板子的 os , 期望某些硬件特性,
(架构, 板子-指定, 内存, cpus ,设备等).
一个os 运行在 VM 上的期待那些特性:
一个客户机在 vm 上运行的必须满足 客户机的需求.
pagraphy 3.
当你配置 一个VM, 你在 组装 一个硬件平台.
不同的是 替代了 集合物理内存卡, CPUs ,等等.
你指定了 你机器的 虚拟组件,
qvm会根据你指定的进行 创建和 配置.
对于事情将出现在哪的规则 和 真实的板子一样:
1. 不要安装两个东西 尝试回应同样的物理地址.
2. 你的VM 配置集成的环境 必须是一个 你即将运行的能够准备处理(时间,消息)的环境.
硬件仿真 也能在其他方向做的好. 一个VM 不需要知道"它的客户机 做的什么 比 硬件需要知道一个os干什么的 多”,程度上的多.
(意思是vm 不需要知道特别多, 相对于以前的硬件知道 os一样)
更多的配置 VM 的信息, 看 "assembling and configuration VMs"
qvm serives.
每个 qvm 进程 提供了 关键的 hypervisor 技术, (qvm 就是我们说的vm, 加载配置文件,就是os的硬件配置平台).
VM startup
为了创建一个 guest os 运行的虚拟环境,
qvm 当它启动时候做以下的事情:
1. 读取, 解析 以及 验证vm 的配置文件, (*.qvmconf) 并且配置 "进程命令行的启动输入"的信息,
如果配置信息非法 并且 打印一个 有意义的错误数据到log, 就退出.
2. 设置 内部即时的 stage tables,(应该是设置页表).
3. 创建 配置它的vm, 包含:
*** ram 是内存 rom 是 硬盘存储.
1). 分配 读写的内存 以及 rom(硬盘存储)
2).为每一个虚拟化之后呈现给 guest os的cpu 规定一个线程 .(为cpu开一个线程)
3).规划 passthrough 设备 让他们对guest都是可得的.
4). 为被托管的 guest os定义和 配置 虚拟设备(vdevs).
VM operation(vm 操作)
在操作一个 qvm 进程需要做以下的事情:
traps(陷阱就是捕获) 访客(guest)
1. 捕获出站和入站guest访问尝试 并且决定 对他们做什么(如果地址指向一个 vdev,调用 vdev 代码(访客退出, vdev代码完成后,然后访客进入= 退出-> 进入的流程); )
2. 在退出一个 物理的cpu之前, 保存guest 的上下文.
3.在 将 guest 重新执行的时候, 恢复guest 的上下文.
4. 照顾到所有的错误处理.
5. 执行(需要确保虚拟机的完整性的) 维持性操作
Manage guest contexts.
管理客户机的上下文.
在虚拟化的环境中, cpu虚拟化插件的职责是 从一个客户机的操作中识别出 什么时候客户机要退出.
当一个 cpu 触发了一个客户机退出, 但是, 是qvm进程实例托管了 保存着客户的上下文的客户机,
当一个 客户机 已经完成了它的任务 并且已经准备好重新进入, 进程实例(qvm) 重新存储了 客户机的上下文.
manage privilege levels
qvm进程实例 在 guest 进入和退出的时候 管理 特权等级, 确保 guests 能够运行,并且 系统 免受错误代码的影响.
在 客户机进入时候, qvm 实例 向cpu 请求给出 客户机(它需要运行的, 定义好的)特权等级,但是更多的是.
当客户机退出的时候, qvm 进程实例 要求 cpu 去返回到 需要在 hypervisor host 运行中的特权等级.
(所以特权等级是时刻都在调整的).
只有cpu的硬件 能够改变特权等级. qvm 进程 执行 需要cpu 改变特权等级 的操作.
这种机制(因此操作), 特定架构.
guest access to vitual and physical resources.
访问 虚拟和 物理资源的 客户机.
每个qvm 进程实例 管理它托管的 客户机 对 所有虚拟的和物理资源的权限.
当一个 客户机 尝试去访问 它的 客户机-物理 内存中的地址.
这个访问 可以是以下的一种,
托管了客户机的 qvm 进程 检查了权限尝试,并且回应描述如下:
Permitted:
guest在访问 它自己拥有的存储区,
qvm 进程 不做任何事.
Pass-through devices:
guest在尝试直接访问 物理地址,
并且 guest 的vm 知道有直接权限,
qvm 进程实例不做任何事情, guest 直接和设备去沟通.
virual devices:
guest 尝试去访问一个 分配到虚拟设备的地址(无论虚拟的或者是 部分虚拟的???)
qvm 进程实例 请求相应的特权等级改变, 并且传递执行到它的代码 或者 请求的设备.
(代码改变或者设备驱动的等级改变)
例如, 一个客户机 CPUID 请求触发 qvm 实例去仿真硬件 以及 对客户机的精确回应, 和硬件对非虚拟化的系统的回应一样.
fault:
客户机尝试访问一些它没有权限的内存.
qvm 进程 返回一个 不正确的一个错误到客户机.
上述的 是 经过cpu的 访问尝试, DMA 的访问控制 被 SMMU 管理 所管理.
==================================================================================================
memory.
在 QNX 虚拟化的环境中, "客户机能够见到的当做 连续物理内存的" 客户机-物理 内存 实际上是 "虚拟化组装的 不连续的 主机-物理 内存".
qnx 虚拟环境的客户机 使用内存来:
1.普通操作; (虚拟环境下的一个内存)
2. 访问 pass-through 设备; (pass-through memory)
3. 和其他的客户机 分享信息. (shared memory)
memory in a vitualized environment.
虚拟化环境的内存.
在 qnx 虚拟化环境, 一个 配置 1G RAM 的客户机 将见到1 GB 可用,
就跟它 在虚拟化环境下 见到的RAM 一样.
这个内存分配 在客户机看来 就是一个物理内存.
实际上 内存是由 虚拟化配置的 从不连续的物理内存中 分配的.
intel 管它叫 guest-physical memory, (概念出现了,就是传说中的 guest0物理的 内存).
为了简洁,我们将使用 guest-physical 内存, 不管平台.(看"guest memory").
当你 在 qnx 虚拟化环境, 配置 并且访问内存的时候, 去记住以下的比较重要:
1. 分配给 guest 的所有内存 以及 其他的使用 不能超过 板子上的物理内存.
2. 内存分配 必须在 qnx 7.0 的system page size(4KB) 的倍数.
3. 一个客户机的 见到的内存 是由不连续的内存块组成的.
这个 展现给 guest的 guest-physical 内存 就像 (在一个非虚拟化的系统中 展现给它的一样).
(又强调一遍).
例如, 在x86系统中, 和传统设备的差距 相同.
4. 一个客户机见到的物理地址 显然 实际上就是 guest-physical内存中的 guest-physical addresss,
当hyper-host 创建一个 VM 时,是由 qvm 进程 分配的.
5. 一个客户机见到的地址(guest-physical) 和 物理地址(主机地址) 没有对应, (to which) 然而 guest-physical
在 虚拟机层 进行最终转换.
一张图: 指导 guest os 见到连续的物理内存,
实际上是由 物理内存中的 不相关的区域 中的 虚拟化配置 出来去集成.
这张上面的图 展现了一个简单的指导 在qnx虚拟化 系统, guest 内存分配 是由 物理内存的一大块不连续内存分配的.
为了 简化这个图, Guest1 的内存分配是不完整的, 为了清晰起见, 一个隔离 已经被添加进 guest 之间.
注意 一些 物理内存的区域也被保留了.
(例如, 为了 板子架构在指定位置需要的 设备 ),并且不能够 分配到 guest.
pass-through memory
guests 以 pass-through 设备的身份访问 物理设备
需要 将 这些设备 映射到 (可以访问他们的)内存区域,
注意 为了 一个 pass-through 的设备 的 guest-physical 的地址 ,没有必要 和 hypervisor-domain的 host-physical 地址一样.
换而言之, 在 guest 能够见到的 physical address 和 hypervisor host domain 见到的 physical address 之间没有对应.
(但是会转换)
例如, 设备A 可能在 Guest 1 的物理地址 的0x100处 配置. (0x100 表示的是一个已经被虚拟化后的一个物理地址)
这个设备 为了guest 1 在同样的位置上(0x100) 的 可能会被配置成一个 pass-through 设备,
所以当 guest1 需要访问设备的时候,它看起来像在 0x100.
但是, 我们应该记住 当一个 guest 看起来像在一个物理地址,
它其实正在看向一个 guest-physical 地址,
转换成 host-physical 内存的其他地址, 表示 "0xc000000".
一张图,
guest 见到的 pass-through 设备的 guest-physical 的地址 被当做是一个物理设备, 与设备的 host-physical 地址并不对应.
(意思是没有映射,和shared 区别, 但是在虚拟化层可以进行转换)
(从设备角度有几个映射)
----------------------------------------------------------
shared memory
部分物理内存 可以在 guests 之间进行分配.
Guests 将会使用 一个虚拟设备 例如 vdev-shmem 来附加到 相同的物理地址(PA) 并且使用 共享内存域 去分享数据.
触发对方,只要数据可得到或者 已经被读了.
(共享内存只适合大数据传输,不适合做 消息通信,
你操作的是一片内存,加握手,就会延时其他进程,
全部要分段???只适合大数据传输,没有队列消息).
两个客户机的内存分享 的指导,
每个客户机 将 内存视作自己的内存.
可以参见 "using your hypervisor system "中的 "memory sharing".
----------------------------------
configuring memory
为了虚拟机 配置内存, 你必须 为了每部分的系统配置内存.
你没必要 为VM 在一大块里面 分配内存.
相比较而言, 你要分配 镜像需要的内存,
然后 你各种设备的 内存, 等等.
许多系统 已经保留了内存区域,
这特别是对 x86 系统, 需要许多 在特殊的位置的 vestigial(残余的) 设备 ,
这些 适应 guests 的规则 跑在 虚拟环境中,
因为 OS们 期待 vestigial(残余的) 设备可以展现出来.
当你为VM 分配内存时,它 应当是权宜(衡量多方balance) 以及有效的 "在guest-physical 内存"只去指定 "可以加载的镜像" 的位置 ,
并且让 qvm 进程 决定 设备的最佳位置, 共享内存, 等等.
如果一个 RAM 位置 被用来 客户机的 "可加载的镜像",
(ram 就是内存,掉电丢失的).
客户机 被配置成 在这个地址(host 地址???) 去寻找镜像文件 在它的内存中 .
(起了qvm之后,已经配置好虚拟化内存的地址, 包括所谓的镜像文件的地址,也可以读进来???, 就是物理板子上已经全部flash进去了,
并且镜像文件已经读到内存了.
然后跳转到对应的 地址,让guest 运行????).
此外, 如果使用 qvm "配置文件,加载组件" 去装载你的可启动的镜像文件.
(就是硬件加载 启动文件),
你加载镜像的地址 必须匹配你客户机的配置.(说白了这个加载镜像要跟客户机启动的时候一致)
(如果你不指定 地址, qvm 会为你照看这个).
举个例子.
对于qnx 客户机来说, 你可能做以下的东西,
1.为 guest 镜像 分配一个 起始地址, 0x80000000.
ram 0x80000000, 128M.
2.加载 可启动的镜像到这个位置.
3.在guest 的buildfile 去指定启动.
这个镜像文件ifs 应该是kernel 吧.
(
你可以看一下bsp的一些启动
还有一些 guest laucher.
).
----------------------------------
DMA 设备包含器 (smmuman).
hypervisor 使用一个 IOMMU/SMMU 管理器(summan),
确保了 没有 pass-through 设备能够 访问 host-physical 内存 到 它还没有明确地被 授予权限.
整个内存的地址布局????
============================================================================================
Devices.
qnx hypervisor 提供客户机 访问物理设备的权限,
包括 pass-through 以及 shared 设备,以及 虚拟设备, 包括部分虚拟化的设备.
关于 设备权限.
当你配置你的qnx 虚拟化环境(hypervisor, 虚拟机的qvm 进程, 以及客户机).
你需要 去分配 物理设备和 虚拟设备(vdevs) 到hypver 和 guests.
为了正确地做,你需要知道, 不仅仅 一个设备是 物理的 或者 虚拟的设备,
并且 是 一个物理的或者虚拟的设备的类型, (设备类型也要分虚拟的和物理的????)
因为这个决定了:
1. 如果guest 或者 hypervisor 必须包含一个 设备驱动.
2. 如果 托管了一个客户机的qvm 必须包含 相关的 vdev.
3. 如果 guest 需要知道 它运行在 一个虚拟化的环境内.
只是作为 在一个 非-虚拟化 的系统
操作系统里面的 设备驱动 必须匹配 物理板子上的 一个硬件设备.
在虚拟化的系统中,客户机中的设备驱动 必须匹配一个 "vdev",虚拟设备.
*******
例如, 如果你使用 vdev-p1011 vdev(如下配置: vdev vdev-p1011 loc 0x1c090000 intr gic:37).
你必须告诉你的客户机 使用一个 PLO11 设备 在 位置0x1c090000 以及 中断 37.
你不能 通过客户机的指导 去使用一个 UART 设备,
说" earlycon = msm_hsl_uart, 0x75b0000", 并且期望它能够找到 PLO11 设备,
比你 在 非虚拟化的环境中 要做的多.
********
配置 hypervisor host,qvm 进程, 设备, 看configuration 那一章节.
--------------------------------------------------------------------------------------------
物理设备
一个物理的设备 可以是hypverisor host 或者 guest 的独家使用,或者可以被分享.
虚拟环境中的 物理设备 (或者 简单的设备) 和 非虚拟化环境中的设备是一样的.
他们需要 驱动, 断言中断 以及 收取信号,等.
在qnx虚拟环境中 运行的客户机 可能直接访问一个物理设备 或者 通过一个虚拟设备(访问物理设备).
或者他们可能被禁止访问一个设备,
物理设备的访问 被 虚拟环境的 配置所控制.
一个物理设备可以配置成:
1. 对特别的客户机 是专属可得到的; (pass -through)
2. 在客户机内部共享, 不是所有的设备都可以共享. (shared devices)
pass-through 设备.
hypervisor 系统中, pass-through 设备是 (有直接的和独立的访问的权限)的客户机的一个物理设备 .
因为它是直接的 以及 独立的, 这种物理设备的访问类型 可能比 通过虚拟设备的访问 要快.
或者说 比 和其他客户机或者 hypver host 分享的访问要快.
(要比shared 快?)
为了使用一个 pass-through 设备, guest 必须有它自己的 物理设备的驱动.
没有 vdev 在托管guest'的qvm 中被需要,
没有 hypvervisor 本身需要的驱动.
(定义,就是pass through 不需要vdev从 host 到 guest 的这些映射?????)
hypervisor host domain 只需要知道它必须 从物理设备那 规划一些中断 直接到客户机.
并且直接传递 来自 客户端的信号.
所有的相互作用 是在 客户机 和 设备之间的;
hypervisor 只负责去辨别 以及 允许 来自设备的中断的通过,以及来自于客户机的信号.
在客户机启动之前, pass-through 设备必须在 *.qvmconf 文件中配置, 为了将会托管 guest 的一个虚拟机.
注意:
只有虚拟化系统的 一个居民 被允许 在任何时间 访问 pass-through 设备.
如果 host 拥有一个 客户机要求是pass-through 设备的 设备;
在guest 在它的虚拟环境中 启动一个这个设备的驱动之前, host必须 终止设备驱动.
相似的, 如果一个客户机 拥有一个 作为pass-through 的设备
在 其他客户机 在它的空间内使用这个设备 之前,它必须在它的虚拟空间中 终止这个设备驱动,
(就是同一时间,总允许只有一个可以访问此设备,无论是hyper或者 host????)
简而言之, 永远不要配置 相同的 pass-through 设备超过一个简单的客户机.
和 复杂设备的 pass-through 属性一起运作:
一些设备(例如 audio 以及 video 设备) 由多个硬件接口组成, 为了操作正常 需要特定的非常的配置 .
一个知识丰富的 (知道和了解 如何使用所有的设备接口,并且可以在vm定义中 可以正确定义他们 )的系统设计者应该能够 让任何复杂的设备
以一个 pass-through 设备 在qnx的hypervisor系统中正常运行.
联系qnx services 获得更多的 客户机之间的复杂设备一些共享.
shared 设备.
在一个 hypervisor 系统中, 共享设备 可以是被超过一个客户机来使用的 物理设备,
或者是 被一个或者多个客户机 以及 hypvervisor 自己本身.
有几种方法 和 模型用来设备共享, 包括了,
1.referred sharing (推荐分享)
2.mediated sharing(调和分享)
hypervisor 提供了服务 类似于 tcp/ip, 共享内存, virtqueue 支持,
(https://www.ibm.com/developerworks/cn/linux/1402_caobb_virtio/index.html. )
***virtio 这个应该是通用接口.
你可以用来设备共享.
这些服务和你实现的配置 将取决于你的系统的需求.
注意:
qnx hypvervisor 支持 vdevs 使得 audio 以及 graphics 的物理设备 的分享,
请联系 qnx 代表.
referred sharing
推荐共享
在 推荐共享 的模式下, 将要共享的物理设备被 指派给一个客户机,
该客户机对设备有绝对控制权.
如果物理设备 被当作一个 pass-through 设备来访问,
guest 需要一个物理设备的驱动.(就是正常的一个dev)
如果物理设备通过一个虚拟设备(vdev)被访问, 托管客户机的qvm 进程 必须有对应的虚拟设备(vdev),
并且客户机 和 hypervisor 都需要对应的设备驱动.???就是驱动之上的虚拟化???
为了虚拟化的设备(guest), 并且为了真实的物理设备(hypervisor)
其他客户端 也需要使用类似 tcp 机制来访问 物理设备, (或者 共享内存 和 virtqueue,机制 )和guest 去沟通,
来控制设备, 并且根据需求去传输数据.
例如, 假设 两个客户机 跑在一个hypervisor 系统上.
guest 0 是一个qnx 安全相关的客户机.
而 guest 1 是一个 “花园式”的 没有安全需求的 linux 系统的客户机.
他们都需要 访问一个设备去输出 声音, guest 0 去发射报警音, guest1 播放音乐.
(仪表以及 中控).
我们分配 audio 设备作为一个 pass-through 设备到 guest 0.
托管guest 1 的vm的 qvm进程里面的 audio 虚拟设备(vdev??) 被设计来和 另外一个qvm进程的虚拟设备 共享数据的.
(应该是设备的共享,而不是仅仅是这个设备的混音???,所以设备会共享,内部实现还是不一样的,对于驱动而言,会生成几个设备)
并且 它是被配置来知道 这个其他的虚拟设备 是在 qvm进程 为了 托管guest0 的虚拟机的.
****:所以共享设备知道 在其他地方是被共享的.
在这种配置下, guest1 上所有的audio 设备活动 被称为 guest 0 来处理.
当 在 guest 0 的qvm进程 的虚拟设备, 接收guest 1 的中断和数据,
它将他们 传递给 guest1 的qvm的虚拟设备.
当 guest1 的qvm进程的虚拟设备 从 guest1 接收 audio devices的信号和数据,(也就是播放的一些样本数目,或者是一些音频流???)
它将这些 传递给 guest0 传递给到它的 audio 设备驱动 以及, 最终, 传递给物理audio设备.
自从 guest 0 控制了audio 设备的所有的输入 以及 输出.
它可以设置优先级来确保 安全相关的 进程和线程 在输入和输出 到 "花园式" 的系统以及它的进程 上取得优先权,
****(gardenvariety 就是普通的,老百姓)
甚至 拒绝去和其他guest os或者 设备合作, 如果合作可能导致自己的 安全相关的活动至于危险中.
***jeoprady 危险.
Mediated sharing
调和共享.
调和共享模式 和 推荐共享模式 相似,不同的是 在调和模式下,
它是hypvervisor的进程 而不是 一个假设负责 控制 物理设备的接口, 并且确保配置的属性是被认可的 guest os.
在这种模式下,被分享的设备 被指派到hypervisor自身.
每个VM 的qvm进程中的虚拟设备 连接到 hypervisor 的中间件(调解员),
这个调解员 决定哪些中断 和 数据 可以从 物理设备到 客户机,
并且 哪些信号 和 数据 是从 客户机 到hypervisor的 设备驱动.
最终, 到了物理设备.
这个调节员 也保证了 配置的属性是被尊敬的(认可的),(例如 确保安全相关的活动有最高的优先级.)
甚至 拒绝 和一个可能对系统上的其他guest 或者hypervisor 本身有害的活动的 guest或者 device.
注意:
调节器 进程 不需要 定居?? 在hypervisor host.
他们可以在其中一个guest中。
注意的是,但是, 依据这种设计, 一个客户机失败 将会导致
调和分享 没有定义的行为.
(没法处理这种错误么?)
综上,一个在guest里面,一个在hyervisor 里面.
最好画一个交互的图.
--------------------------------------------------------------------------------------------
虚拟设备
一个虚拟设备可以仿真一个物理设备,或者它可以 做一个 半虚拟化的设备(一个虚拟设备, 不存在确定的物理设备).
虚拟设备(或者说 vdevs) 只存在 虚拟化环境.
他们是 运行在 hypervisor 层的软件代码 以及要么仿真 一个物理设备.
或者提供一个 物理设备提供的功能 而 没有仿真任何指定的物理设备.(???没有仿真,直接提供么)
为了使用vdev, guest 需要一个驱动, 就像它需要 一个驱动 在非虚拟化的环境中 去使用物理设备一样.
****vdev 也需要对应的驱动去生成.
一个vdev 可能从未访问一个物理地址, 或者它会像一个(全都直接回应guest 并且 在guest和物理地址间 传递请求 和回应的)
中间件运行.
在一个 hypervisor 系统中,在qvm进程里, hypervisor 为"托管客户机的 虚拟机 "提供了 vdevs.
托管在 虚拟机的 客户机 收到来自于 虚拟设备的中断,并且 发送信号给它.
和 它在物理的硬件设备一样.
guest 和 系统上的任何的物理设备 有直接联系;
例如 一个设备 有可能甚至不存在.
guest 需要一个 为它将使用的各种 vdev 一个设备驱动,
就跟当它运行在一个非虚拟化的环境 并且需要访问一个物理设备, 需要一个设备驱动,
hypervisor 支持 虚拟设备的以下类型.
1.仿真设备
2.部分虚拟化设备.
注意:
当前的 hypervisor发布, 没有 qnx的支持, 不支持用户-创建 的vdevs.
如果你的hypervisor 系统实现 需要 vdevs 这次发布没有包含进去,
请联系你的 qnx 代表 去获取 qnx 工程 服务 写 vdev 权限.
(连创建vdev 都要花钱去买. 具体你内部的中断是怎么玩的???)
-------
仿真设备.
一个仿真的 vdev(或者简单的vdev) 是一个 (为guest 仿真一个真实的物理设备)虚拟设备.
以下的 是qnx 虚拟化环境中 仿真 vdevs 的关键点:
1. 为了使用 vdev ,一个 guest 不需要知道 它是运行在虚拟化环境的.
它和这些设备都是相互作用的, 和 它和物理设备的交互方式一样,
并且它没有指示 它正在与虚拟设备合作, 或者没有硬件设备能够参与其中.
(并不需要知道运行在虚拟环境的,这个是由hypervisor 出版的)
2. vdev 仿真了一个真实的物理设备(例如, 一个x86 的电脑键盘).实际上,
一些 vdevs(例如 电脑键盘) 存在简单的因为 一个运行在 x86 平台上的期望它在那.
(存在的意义)
3. 仿真的物理设备 存在或者不存在系统上.
(或许根本不存在)
4. 取决于 物理设备的类型, 仿真的vdevs 可能所有事情都是自己处理,
(例如 仿真一个 计时器芯片(vdev-timer8254)), 或者它可以当作 guest 和 一个真实的物理设备的 中间件(例如 vdev-ser8250).
5. 客户机 为了 vdev 可以使用同样的设备驱动,和(它在非虚拟化环境中 为仿真的物理设备 使用的)一样,
(都要有设备驱动,生成的代码都一样,但是设备需要做映射????)
------
部分虚拟化的 设备.
部分虚拟化的设备 是一个 虚拟设备的类型, 他们是运行在 hypervisor 层的一个 软件代码,
但是这个代码 不仿真 任何指定的硬件设备.
反而, 一个部分虚拟化 的设备 提供了 "可能在 非虚拟化环境中 由物理设备(或者几个 物理设备) 提供的" 功能,
但是 没有 仿真一系列硬件的一个约束.
一个传统的 部分虚拟化 的设备有 运行在客户端的 代码,和 运行在客户端(后端)的一个代码;
举例, 一个运行在 客户机的 文件系统的 设备驱动,连接到 一个 运行在hypervisor host 的块设备驱动.
部分虚拟化设备的关键点包括:
1. 为了使用 部分虚拟化的 设备, guest 必须知道 它正在运行在一个虚拟化的环境.
例如, 为了使用 virtio-net, guest必须知道 它正在运行在一个虚拟化的环境,
只有因为 virtio-net 没有对应的 物理设备( 它只是作为一个部分虚拟化的设备).
2. 不存在 物理设备 完全对应 部分虚拟化的设备.
3. 客户机 必须有 适当的驱动 以及 接口 去和 部分虚拟化的设备 进行合作.
部分虚拟化的设备需要一些 初始投资(例如 写驱动),
但是这些 驱动可能比 (必须仿真一个硬件组件的)vdevs更加有效.
例如, 仿真一个 (提供了一个控制终端的) 串口接口 可能导致许多客户机退出以及返回.
一个 virtio-console 驱动(一个部分虚拟化 的串口接口) 提供了同样的功能.
但在 guest端的开销更小.
部分虚拟化的 设备 不一定是 VirtIO 设备,
VirtIO 是简单的 并且当前受欢迎的标准.
==========================================================================================
基于优先级的 调度
在qnx的虚拟化环境中 去理解 基于优先级 调度如何 影响系统行为.
hypvervisor 线程 优先级 和 客户机线程的优先级.
和其他的 任何的高级的软件系统一样, 为了在带有 qnx hypervisor 系统中 正确的配置 调度优先级,
需要一个 对你的系统需求和你的系统能力 都有直观的了解.
为了开始, 你应该记住以下:
1. hypervisor host 并不知道 它的 虚拟机上运行着什么, 或者 客户机 如何调度 他们自己内部的软件.
当你在 客户机 中设置优先级, 这些优先级 只被客户机知道.
2. 虚拟 CPUs (vCPUs) 是被 qvm vCPU 调度线程所调度的;这些线程 存在于 hypervisor host 域.
3. 客户端的 线程优先级 和 hypervisor host 中的线程优先级 没有关系.
qvm 处理 vCPU 调度线程 的相关属性 决定 哪个 vCPU 可以访问 pCPU.
这下面的这张图 显示了 客户机内的属性 只和客户机内部相关,并且 对"两个竞争的客户机 获取对 pCPUs 的访问权" 没有影响,
阴影区域 显示了 两个竞争的 vCPU 线程获取pCPU 的权限 的其中一种.
(没有统筹统一的优先级,就是大类是区分,而后才是 vcpu 之后的一个优先级)
图5. 访问 一个pCPU 最重要的优先级 就是 qvm 进程的 vCPU 的优先级.
如果两个 vCPUs 为一个单个的 物理 CPU(pCPU) 竞争, vCPU 更高优先级的线程 会立即获取 pCPU.
客户机内部运行的线程的优先级 对这个访问是没有影响的.
上述的例子中:
1.guest 1 中的线程 有一个比 guest0 中更高优先级的线程.
2. hypervisor 为 guest 0 提供了 vCPU 的线程(200), 比 为guest 1提供了 vCPU的线程(100) 有一个更高的优先级.
3. 所以, 内部guest 0 线程 获取了 pCPU 的访问权限 并且运行.
4. 内部的 guest1 线程被阻塞了 直到 guest0 中的线程 资源 自愿地锁住.
简而言之, 决定性的线程 就是 qvm 进程的 vCPU 调度线程的优先级.
客户机退出
以下引起了客户机退出:
客户机的停止;
一个 vdev 的访问; 这种类型的 退出 没有必要 引起 客户机去放弃 cpu 的控制;
host 上的一个中断(包括 内部处理器 的中断 (IPIs)).
一个虚拟的定时器, 例如 仿真在 intel 8254 芯片的 vdev.
一个指导, 例如一个 CPUID 指导.
==========================================================================================
时间
在 qnx hypervisor 上的客户机的定时器 总是 滞后于 host的时间, 但是hypervisor 采取正确的操作来 最小化 偏移.
drift 偏移
hypervisor 系统中的客户机的时间也是虚拟化. 也就是说, 托管客户机的 vm(qvm 进程实例)
提供了 一个虚拟的 “计时器滴答” 和 (客户机期望在它的环境下 找到的)虚拟的硬件 定时器.
所以, hypervisor host 控制着 它的客户机见到的时钟。
hypervisor host 给 客户机的时钟做的 就是当一个 客户机退出的时候, 对客户机有一个重要的影响,
特别是 客户机的 时间预算.
当一个客户机 退出的时候, hyervisor host 可以 要么让 客户机时钟运行, 要么停止客户机的是中国,
这些选项中没有一个是理想的.
guest clock runs during exit
退出的时候,客户时钟正在运行.
如果 hypervisor host 允许 客户机的时钟去运行,
客户机 时钟 保持了和 hypvervisor host 时钟的同步,
仅仅被偏离量分开,
host 开始计算时间 以及 客户机开始计算时间 之间经过的时间.
允许 时钟 跑偏 客户机的时间计算, 但是, 在客户机退出 以及 它的再进入 的周期被添加到 时间流逝,
为了客户机 需要退出的 的任务.
任务会消耗 他的 时间预算 并且 可能会被抢占,举例,除了退出,没有做实际上的任何事情.
(应该就是cpu 资源的使用).
guest clock is stopped during exit.
当客户机退出的时候, 停止 客户机的 时钟, 解决了 存在的跑偏 客户的 时间预算.
当客户机退出的时候, 客户机的时钟 停止 直到 客户机重新进入, (重新进入,会开始计时)
并且客户机只会计数 它真实运行在任务的 时间预算 的时间.
但是,客户机在 各个客户机退出的时候停止, 这个时钟 落后 host clock 增加地. 这个落后称之为 偏移.
在每个 客户机退出的时候, 偏移增加. 如果偏移量 被允许 不正确的增加,
遇到可能阻止 其按照要求运行的行为:
客户机 可能会丢失 时间器 中断,
它一天中的时间可能会不正确的增加,等.
Skipping,
跳过.
为了给客户机 他们时间预算的合理控制, qnx hypvervisor 在每一个客户机退出的时候, 停止 客户机的时钟.
但是, 为了减轻 偏移的影响 以及 避免最终创建的 不争取的偏移的 问题,
qnx hypervisor 周期 引起 客户机的时间 "向前跳过";
也就是说, 它设置了 客户机的时间 前移一部分偏移的时间(也就是时间的矫正).
hypervisor 只会向前跳过 客户机和host之间的落后的一部分,
因为 客户机的 向前跳过时间 歪斜客户机的时间 计算.
例如, 考虑到 一个客户机 落后 host 有10ms的偏移.
这个客户机 正在运行 foo,
如果hypervisor 让客户机时间向前 整个10ms,
这些10ms(foo 没有使用的)尽管如此,但是还要foo 收费,
当foo 开始和 它结束的时候,因为时间内的增量 包含了 10ms的的向前跳跃.
所以, hypervisor 只会 让 客户时间 向前偏移 的一小部分, 为了 将"skip" 平均分配给客户机的活动.
如果你 在你的客户机 已经实现了 任何类型的 时间预算,
你应该考虑到 所有偏移量 和 纠正性跳过 的这些预算 的影响.
特别,记住.
1. 客户机已经退出了所有的 vCPUs, skipping是可能的; 这意味着 在不规则的间隔发生的 skip的必要性.
2. hypervisor host 在每个它要这样做的机会上 将客户机的时间 向前跳跃.
3. hypervisor host 只会向前跳跃 当前偏移量的一部分.
4. 总是有一些偏移量, 并且这些偏移的变量 贯穿客户机的生命周期.
如何找回一个客户机的当前的时间偏移的信息,
看"finding current time drift " 在“monitoring, troubleshooting and Tuning”
-----------------------
offset
一个客户机 在host开始之后 可以启动,所以一个客户机 需要比 它的托管者 计算时间要晚(在hypervisor 系统之外的衡量).
不同的是 简单的偏移量, 只有在它关心的时间里面 是和偏移相关的.
(drift).
==========================================================================================
共享资源
在一个 hypervisor 系统中,除了 共享内存中一小块区域,
内存和设备 只被 一个单独的实体 所拥有.
多个运行在不同的 虚拟机中的 客户机 可能使用 同样的系统资源, 例如一个物理的cpu,
这些资源的管理 完全是 hypervisor的domain.
系统集成者的职责 限制于(非常重要) 位每个虚拟机 配置正确的 vPCU 的个数的问题,
设置 他们的优先级, 并且绑定 vCPU 线程 去指定特定的物理 CPUs, 如果需要的话.
其他资源, 例如 内存和物理设备, 通过 VM 配置分配到 指定的虚拟机,
hypervisor 使用来 组装虚拟机(看见"配置"这一章).
这些资源 变成 运行在各个虚拟机之间的客户机 的独立的属性.
他们不能够在客户机之间分享 , 像 两个独立的板子之间的硬件设备一样.
共享内存
当你为你的 虚拟机 配置 RAM 和 ROM, 让qvm进程 为内存 选择 host-physical 地址 通常是最佳方案.
因为进程 不会 给超过一个 虚拟机 分配一个同样的内存位置.
一个小型的 共享内存区域 可以是一个 在guest 于不同虚拟机之间 传递数据的 有效的机制,
但是, 如果你需要配置一个 共享内存区域, 你可以这样做, 使用一个vdev 例如 vdev-shmem, 取代 hypervisor的共享内存服务,
共享内存 如何实现的,
看"memory sharing" 在 "using your hypervisor system".
共享设备
像内存一样, 设备不能直接分享.
虚拟设备(无论是仿真 还是部分虚拟化.) 是隐式的(在qvm 进程代码),或者他们是 配置进VM 的 共享的对象 ;
因此,他们是虚拟机专有的.
物理 设备 直接分配给 客户机 当作 pass-through 设备,
或者 分配给hypervisor host, 并且 被客户机 通过一个 虚拟设备去访问.
如果一个实体 而不是 (需要访问设备的)物理设备的拥有者 ,它必须经过 设备的拥有者,
就像 如果设备物理的在另一个板上 做的一样.
如果 设备 由 hypervisor host 拥有的, 这就称之为 中介分享;
如果 被其他客户机 拥有, 这就称之为 “参考分享”.
更多的信息,请见 这章的 "shared devices".