# AddressSpace Part1

AddressSpace，看名字就知道很牛。其中也囊括、关联了很多数据结构。这次我们主要讲讲它和MemoryRegion之间的关系。

## 初始化 -- address\_space\_init

这个初始化函数倒是不长，不过包含了很多重要的内容，这里我们只说两个：

* QTAILQ\_INSERT\_TAIL(\&address\_spaces, as, address\_spaces\_link);
* as->root = root;

## 不止一个的地址空间

从上面第一条看，所有的地址空间都会链接在一个链表上。这就说明了在qemu中不止有一个地址空间，而不是我最开始想象的一个虚拟机公用一个地址空间。

在初始化函数中我们看到两个地址空间： address\_space\_memory, address\_space\_io。所以此时这个链表长成这样：

```
    address_space(global)
    +-------------------------------+
    |tqh_last                       |
    |tqh_first                      |
    +-+-----------------------------+
      |        
      |   address_space_memory             address_space_io
      |   (AddressSpace)                   (AddressSpace)
      |   +------------------------+       +------------------------+
      +-->|address_spaces_link     | ----->|address_spaces_link     |
          |                        |       |                        |
          +------------------------+       +------------------------+
```

## AddressSpace和MemoryRegion

这个root参数是一个MemoryRegion类型，所以我们得到了AddressSpace和一个MemoryRegion对应。

慢着，我们刚才看到了什么？MemoryRegion可以是一颗树是不是？那实际上我们得到的是：

> AddressSpace和一颗MemoryRegion树对应

做了一个简单的图示意：

```
    AddressSpace               
    +-------------------------+
    |name                     |
    |   (char *)              |
    |                         |
    |                         |          MemoryRegion(system_memory/system_io)
    +-------------------------+          +------------------------+
    |root                     |          |name                    |
    |   (MemoryRegion *)      | -------->|  (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()       |
                  +------------------------+                     +------------------------+
```

## 隐藏内容

地址空间就这么简单么？再看一眼初始化函数，发现其中还有两个子函数并没有打开。其中包含的奥秘让我们接着打开。
