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?