understanding_qemu
  • Introduction
  • 设备模型
    • 设备类型注册
    • 设备类型初始化
    • 设备实例化
    • DeviceClass实例化细节
    • 面向对象的设备模型
    • 接口
    • 类型、对象和接口之间的转换
    • PCDIMM
      • PCDIMM类型
      • PCDIMM实例
      • 插入系统
      • 创建ACPI表
      • NVDIMM
  • 地址空间
    • 从初始化开始
    • MemoryRegion
    • AddressSpace Part1
    • FlatView
    • RAMBlock
    • AddressSpace Part2
    • 眼见为实
    • 添加MemoryRegion
  • APIC
    • 纯Qemu模拟
    • Qemu/kernel混合模拟
    • APICV
  • Live Migration
    • 从用法说起
    • 整体架构
    • VMStateDescription
    • 内存热迁移
    • postcopy
  • FW_CFG
    • 规范解读
    • Linux Guest
    • SeaBios
  • Machine
    • MachineType
    • PCMachine
  • CPU
    • TYPE_CPU
    • X86_CPU
  • MemoryBackend
    • MemoryBackend类层次结构
    • MemoryBackend初始化流程
Powered by GitBook
On this page
  • 初始化 -- memory_region_init
  • 一棵树 -- memory_region_add_subregion
  • 内存模拟 -- address_space_rw

Was this helpful?

  1. 地址空间

MemoryRegion

MemoryRegion是qemu中管理内存空间的一个重要数据结构,这里我们就花点时间观察一下它。

初始化 -- memory_region_init

首先想到的是如何初始化这个数据结构,其中有一个重要的函数入口:memory_region_init。不过如果你打开仔细观察后,这个函数调用了另外两个函数进行初始化:

  • memory_region_initfn

  • memory_region_do_init

后者比较明显,而前者则隐藏在TYPE_MEMORY_REGION类型的实例化函数中。

但是总的来讲也没有做什么太多工作,无非是初始化了一些重要的成员:

  • name

  • ops

  • size

用一个简单的图来展示一下:

          struct MemoryRegion
          +------------------------+
          |name                    |
          |  (const char *)        |
          +------------------------+
          |ops                     |
          |  (MemoryRegionOps *)   |
          +------------------------+
          |addr                    |
          |  (hwaddr)              |
          |size                    |
          |  (Int128)              |
          +------------------------+
          |subregions              |
          |    QTAILQ_HEAD()       |
          +------------------------+

一棵树 -- memory_region_add_subregion

细心的朋友在上面这张图中可能已经发现了,在这个数据结构的末尾我列出了另一个重要的成员变量subregions。从字面上就看出一个MemoryRegion可带有多个subregions。

这个过程是通过memory_region_add_subregion()函数实现的,这个过程很简单,运行后的结果如下:

                            struct MemoryRegion
                            +------------------------+                                         
                            |name                    |                                         
                            |  (const char *)        |                                         
                            +------------------------+                                         
                            |addr                    |                                         
                            |  (hwaddr)              |                                         
                            |size                    |                                         
                            |  (Int128)              |                                         
                            +------------------------+                                         
                            |subregions              |                                         
                            |    QTAILQ_HEAD()       |                                         
                            +------------------------+                                         
                                       |
                                       |
               ----+-------------------+---------------------+----
                   |                                         |
                   |                                         |
                   |                                         |

     struct MemoryRegion                            struct MemoryRegion
     +------------------------+                     +------------------------+
     |name                    |                     |name                    |
     |  (const char *)        |                     |  (const char *)        |
     +------------------------+                     +------------------------+
     |addr                    |                     |addr                    |
     |  (hwaddr)              |                     |  (hwaddr)              |
     |size                    |                     |size                    |
     |  (Int128)              |                     |  (Int128)              |
     +------------------------+                     +------------------------+
     |subregions              |                     |subregions              |
     |    QTAILQ_HEAD()       |                     |    QTAILQ_HEAD()       |
     +------------------------+                     +------------------------+

想起了熟悉的pci树,好久没摸pci了,感慨一下。

内存模拟 -- address_space_rw

好了,该说到重点的重点了。MemoryRegion的存在是为了模拟内存空间,那究竟是怎么做的呢?

还记得刚才说MemoryRegion中有一个成员叫ops么?就是它了。当然最后进行读写的方法有很多,这里只讲其中之一:

  • address_space_rw

  address_space_rw()
    ...
    memory_region_dispatch_read()
      ...
      mr->ops->read()
      mr->ops->read_with_attrs()

中间需要跳掉一些东西,因为这些数据结构暂时还没有讲到。这里主要是展示MemoryRegion的根本作用是虚拟机和主机之间地址空间的信息交换。

Previous从初始化开始NextAddressSpace Part1

Last updated 6 years ago

Was this helpful?