概念

关键是在于这个虚拟化层,我们用虚拟化层来实现对硬件抽象层的虚拟化.

虚拟化的效率高是因为Hypervisor的体系结构环境是相同的.

这里的II型是KVM这种.1.5型可能更多的是

物理设备只有一个CPU的时候用多任务假装是vcpu.

有点像虚拟内存<->物理内存.用的也是页表的方式来建立对应关系.

和
vcpu的方式是一样的实现vDev.其实就是怎么把一个设备的划分成很多小的粒度,然后再分配资源给它.
最简Hypervisor执行流程:
- 加载Guest OS内核Image到新建地址空间。
- 准备虚拟机环境,设置特殊上下文。
- 结合特殊上下文和指令sret切换到V模式,即VM-ENTRY。
- OS内核只有一条指令,调用sbi-call的关机操作。
- 在虚拟机中,sbi-call超出V模式权限,导致VM-EXIT退出虚拟机,切换回Hypervisor。
- Hypervisor响应VM-EXIT的函数检查退出原因和参数,进行处理,由于是请求关机,清理虚拟机后,退出。
这里这个
V模式一定要注意,之前我们只涉及了U和S模式.

S变成了HS.HS是关键,作为联通真实世界和虚拟世界的通道.体系结构设计了双向变迁机制.
后边实现的很多东西都来自于HS这个特权级的寄存器.

H扩展后,S模式发送明显变化:原有s[xxx]寄存器组作用不变,新增hs[xxx]和vs[xxx]
hs[xxx]寄存器组的作用:面向Guest进行路径控制,例如异常/中断委托等
vs[xxx]寄存器组的作用:直接操纵Guest域中的VS,为其准备或设置状态
意思好像是要用
HS里的H去假冒VS?

根据
spv的不同决定sret会进入虚拟化还是进入user.

这里还多一个
spvp,指示HS对V模式下地址空间是否有操作权限,1表示有权限操作,0无权限.
总结下来感觉虚拟机更像是一个进程,但是它又比进程多很多东西,需要运行自己的一套寄存器.
实验
运行之后是触发了一个IllegalInstruction的trap.
所以确实是会报错的.
这里要注意是
QEMU的版本问题,如果是默认的6.x会导致无法正常进入vmexit_handler.
我这里安装的QEMU是9.1.0版本,可以参见我自己的博客[rCore学习笔记 03]配置rCore开发环境 - winddevil - 博客园,下载的时候把版本改成9.1.0即可.
这里知道li指令访问了a7寄存器违反了不能访问csr的规定.
由于li的长度为4,我们做出如下修改tf.sepc += 4;:
1 | // modules/axhal/src/arch/riscv/trap.rs |
课后作业
注意触发缺页异常之后要调整
sepc的值,防止再回去再触发缺页异常然后无限循环了.
因为未知原因会卡住,这题的解题思路应该和h_1_0是一样的.