QEMU下的内存结构体很多了,RAMBlock,MemoryRegion,AddressSpace,MemoryRegionSection,KVMSlot和kvm_userspace_memory_region,很多时候看代码时候都会被搅合成一坨,虽然很早时候在KVM源代码分析2:虚拟机的创建与运行KVM源代码分析4:内存虚拟化都提到了内存虚拟化的过程,但实际上这几个结构体之间的关系并没有理清,外加上lizhen童鞋要求分析讲一讲,故在此处补个补丁。

QEMU代码:git v2.8.0

RAMBLOCK才是真正分配了host内存的地方,如果把它直接理解成一个内存条也是非常合适的,但实际上不仅仅如此,还有设备自有内存,显存。它的主要元素就是mr,host, offset和used_length。

每个RAMBLOCK都有一个唯一的MemoryRegion对应,另外需要注意的是不是每个MemoryRegion都有RAMBLOCK对应的。host则是host的线性地址

offset则是这个block在ram中的base地址,如qemu_get_ram_block下的代码

offset则是block在ram中的偏移位置

然后看MemoryRegion

MemoryRegion是树状父子结构的,每一个ramblock都有一个对应的MemoryRegion,一般而言,这个MemoryRegion是最顶级的MemoryRegion,它还有很多子MemoryRegion,比如在这个ramblock地址范围内的MMIO等,这里面的重点元素是size,addr和alias_offset,

addr的由来则是

此处的addr实际也是mr的起始地址,和offset有点类似

地址空间,本来不同的设备使用的地址空间不同,但是QEMU X86里面只有两种,address_space_memory和address_space_io,所有设备的地址空间都被映射到了这两个上面,

是通过FlatView体现的,当memory region发生变化的时候,执行memory_region_transaction_commit,address_space_update_topology,address_space_update_topology_pass最终完成更新FlatView的目标。

FlatView结构如下,图片来自刘峰童鞋。

每一个flat range都投射到同一个地址空间的平面上,而上图中的R1,R2等对应的则是struct MemoryRegionSection。

在下面被调用

在MEMORY_LISTENER_CALL中调用kvm_region_add和kvm_region_del,执行kvm_set_phys_mem,组装KVMSlot

最终通过kvm_userspace_memory_region将QEMU的内存分布信息传递给KVM。

具体元素的关系,见下图

 


QEMU下的内存结构MemoryRegion和AddressSpace来自于OenHan

链接为:http://oenhan.com/qemu-memory-struct

发表评论