SylixOS的VMM子系统共有三个功能:物理地址的管理、虚拟地址的管理、映射虚拟地址和物理地址。SylixOS下对物理地址空间和虚拟地址空间是通过页面来管理,单个页面的大小是4KB。
1. SylixOS对物理内存的划分
SylixOS将物理内存划分了4个区域,分别是:内核代码区、内核数据区、DMA内存区、APP内存区:
在内核、驱动中所申请的内存都是在内核数据区分配,内核数据区有着一套自己的内存管理方法。VMM子系统管理的内存区域是DMA内存区和APP内存区:
2. VMM子系统一些数据结构
2.1 页面控制块
VMM子系统对已分配的物理内存和虚拟内存、已经释放的物理内存和虚拟内存采用LW_VMM_PAGE数据结构来管理,我们称之为页面控制块。页面控制块中记录了物理或者虚拟内存的地址和页面个数,还有其他的一些属性:
2.2 空闲页面管理块
VMM子系统对可分配物理或者虚拟内存采用LW_VMM_ZONE数据结构来管理,我们称之为空闲页面管理块。空闲页面管理块中记录了可分配页面数量和已经释放的页面控制块的散列表。
2.3 已释放页面控制块散列表
在内存空间多次的分配-释放后,会产生许多不同大小的页面控制块,为了有效的管理,将被回收的页面控制块以页面数量为关键参数进行HASH散列放置。
2.4 已分配页面控制块散列表(地址反查表)
已经分配的连续页面采用LW_VMM_AREA数据结构来管理。释放页面时,为了从页面地址快速定位到对应的页面控制块,SylixOS首先以该连续页面的起始地址为关键参数进行HASH散列,然后将具有相同散列值的页面控制块以红黑树数据结构进行管理,提高了页面回收的时间确定性。
2.5 页面控制块邻居链表
SylixOS中的页面控制块邻居链表是在内存分配过程中形成的。申请内存时,根据需要分配的页面数量,快速定位到已释放页面控制块散列表内具有相同散列值的链表头,在遍历以找到最佳大小的页面控制块。如果找到的最佳大小的页面控制块所表示的页面数量比需要分配的多,则分裂该页面,并将剩余的空闲页面控制块插入到已释放页面控制块散列表内。同时将刚刚分裂的两个页面控制块形成邻居链表,表示这两个控制块是分裂得来的。
3.VMM内存回收算法
VMM回收页面控制块时,会检查这个页面控制块的邻居链表中左右相邻的页面控制块是否是空闲的。如果是空闲的,就需要将这控制块合成1个,以减少多余控制块对内存的占用,这种操作叫做聚合。
假设经过多次分配回收过后,现存在这样一个页面控制块邻居链表:
3.1左右都不聚合
释放控制块3或者控制块4都属于这种情况,这里假设释放控制块4;
3.2 左聚合
左聚合情况,在3.1中的情景下,释放控制块2属于这种情况:
3.2 右聚合
右聚合情况,在3.1中的情景下,释放控制块3属于这种情况:
3.3 左右都聚合
在3.1或者3.2情景下,再回收控制块都属于这种情况。这时会先执行左聚合,然后执行右聚合。以2.2情景为例,先左聚合:
再右聚合:
4. VMM子系统对物理内存的管理
4.1 空闲物理页面控制块池
系统初始化的时候根据DMA内存区和APP内存区总的物理页面数量预先分配了相应数量的物理页面控制块,并将这些物理页面控制块形成单向链表。物理内存除了DMA内存区,绝大多数都是进程使用,进程很多页面都是在缺页中断分配物理内存。初始化时预分配控制块是保障缺页中断执行时间相对较短,确定性好,保证控制块一定比物理页面的数量多,只要物理页面存在就不会出现控制块不够用的情况,而且分配控制块的时间是一个确定时间,实时系统的确定性非常关键,用空间换取时间确定性。
4.2 空闲物理页面管理块
VMM子系统最多有8个空闲物理页面管理块,常用的有2个,分别用于管理可分配的DMA内存区和APP内存区内存。管理DMA内存区的管理块一般是_G_vmzonePhysical[0],管理APP内存区的管理块一般是_G_vmzonePhysical[1]。
4.3 物理地址反查表
VMM子系统最多有8个物理地址反查表,常用的有2个,分别用于反查DMA内存区和APP内存区内存地址。反查DMA内存区的反查表一般是_G_vmareaZoneSpace[0],反查APP内存区的反查表一般是_G_vmareaZoneSpace[1]。
4.4 回收物理页面控制块
- 只有发生聚合操作时,才会有一个物理页面控制块被放回空闲物理页面控制块池中
- 不管是左聚合还是右聚合,都是保留左边的控制块并更新,右边的控制块被回收到控制块池中
- 只要释放一个控制块管理的内存空间时,空闲的控制块会被链入HASH空闲链表中
4.5 使用注意
在申请到一个空闲的物理页面控制块后,一般都需要将这个物理页面控制块插入到物理地址反查表中,但是也有例外,在申请逻辑地址连续,物理地址可能不连续的内存时,就不需要将物理页面控制块插入到物理地址反查表中,原因会在下一小节讲明。
5. VMM子系统对虚拟内存的管理
VMM子系统主要管理2类虚拟内存:
- APP虚拟内存,这部分内存被SylixOS中所有动态加载的对象使用。比如内核模块,动态链接库,应用程序,这些对象所使用的内存都来自APP区虚拟内存。对象加载时,只会获得虚拟页面,只有真正使用时,才会在缺页中断处理中分配物理页面。
- IO Remap区虚拟内存,外设IO寄存器空间重新映射后的虚拟地址空间都来自这部分虚拟内存。
VMM子系统对物理内存和虚拟内存的映射关系如下:
由图中的映射可以看出:
- 内核代码区、内核数据区、DMA内存区的虚拟地址和物理地址是一样的,也就是平板映射。
- 中断向量表被映射了2次,因为在arm体系中,当发生中断和异常时,cpu自动跳转到0x00000000地址去执行,所以需要将中断向量表再次映射到0地址去。
- 外设寄存器地址空间可以被平板映射,也可以再次被映射到IO映射区。
其中APP虚拟内存区大小一般在1GB~2GB之间,IO映射区大小一般是几百MB。
5.1 空闲虚拟页面控制块的分配
VMM子系统对虚拟页面控制块的分配不同于物理页面控制块的分配方法,虚拟页面控制块是“用时分配”,也就是用到的时候分配一个。
5.1.1 物理页面控制块散列表
这个表只有在申请逻辑地址连续,物理地址可能不连续的内存时才会用到。这时虚拟页面控制块只有一个,但是物理页面控制块可能有多个,于是将这多个物理页面控制块散列在物理页面控制块散列表中。这样在回收虚拟内存时,可以根据此表找到所有的分配出去的物理内存页面控制块,然后分别回收物理内存。这也就解释了5.5小节中的疑问,为什么不需要将物理页面控制块插入到物理地址反查表中,因为已经可以通过物理页面控制块散列表找到相应的物理页面控制块,所以就需要插入到物理地址反查表中。
物理页面控制块散列表的内存空间是紧接着虚拟页面控制块的,其地址保存在虚拟页面控制块中。
5.2 空闲虚拟页面管理块
5.3 虚拟地址反查表
VMM子系统只有一个虚拟地址反查表,用于反查APP虚拟内存区和IO映射虚拟内存区内存。记录在mmuctxGlobal中。
5.4 回收虚拟页面控制块
- 只有发生聚合操作时,才会有一个虚拟页面控制块被删除
- 不管是左聚合还是右聚合,都是保留左边的控制块并更新,右边的控制块被回收到控制块池中
- 只要释放一个控制块管理的内存空间时,空闲的控制块会被链入HASH空闲链表中
6. VMM子系统映射物理内存和虚拟内存
SylixOS下采用的是2级页表映射,也就是最小映射单位是4KB。所谓的映射就是在已知物理地址和虚拟地址和内存属性的情况下,构造好相应的页目录项和页表项,二级页表如何映射网上的资料很多,这里不再赘述。
6.1 预分配页目录和页表内存空间
SylixOS对页目录和页表所占的内存区域是使用两个定长内存分区来管理的。页目录只申请一次,建立映射时,如果发现对应的页表不存在,则从页目录的定长分区中分配一个定长内存出来,然后填写好相应的页目录项和页表项。
MM中用于管理的数据结构,如页面控制块,空闲页面管理块等等,所在的内存区域都是内核数据区。
2021年4月7日 17:57 1F
强👍