RAMBlock
对于一个地址空间,我们有了树状的MemoryRegion,有了一维的FlatView,但是还没有讲真正对应的内存在哪里。
在qemu中,这部分的工作交给了RAMBlock。
虚拟机内存的分配流程
按照惯例,我们来看一眼一台虚拟机是如何获得对应的内存的。这个过程有点长,在这里只列出关键的部分。
pc_memory_init()
memory_region_allocate_system_memory()
allocate_system_memory_nonnuma()
memory_region_init_ram_nomigrate()
memory_region_init_ram_shared_nomigrate()
{
mr->ram = true;
mr->destructor = memory_region_destructor_ram;
mr->ram_block = qemu_ram_alloc(size, share, mr, errp);
}埋得很深,最终还是找到。主要工作还是和MemoryRegion相关,设置了其中几个关键的成员:
ram: 表示有内存对应
destructor: 释放时的操作
ram_block: 这个就是本节要讲的RAMBlock了
ram_list按照空间大小排序的链表
其实到这里已经没啥好多说的了,RAMBlock数据结构就是描述虚拟机在主机上对应的内存空间的。不过呢,在qemu上还用了一个链表把他们连起来。这说明qemu上可以分配不止一个RAMBlock。而且在链表上,他们是按照空间大小排序的。
这部分可以看ram_block_add()函数的注释。
用一张图来让大家增加一些直观印象。
地址对应关系
有了RAMBlock后,其中关键的一点就是GPA(Guest Physical Address)是如何和HVP(Host Virtual Address)的映射关系就建立了。
我们用一张图来解释。
GPA -> HVA 的映射由MemoryRegion->addr到RAMBlock->host完成。
是不是有种明心见性的感觉~
Last updated
Was this helpful?