Linux中存储管理使用的数据结构和函数

来源:互联网 发布:淘宝自动充值 编辑:程序博客网 时间:2024/04/30 15:50
从硬件角度来说,Linux内核只要能为硬件准备好页面目录PGD、页面表PT以及全局段描述表GDT和局部段描述表LDT,并正确地设置有关的寄存器,就完成了内存管理机制中的地址映射部分的准备工作。


页面目录PGD、中间目录PMD和页面表PT分别是由表项pgd_t、pmd_t以及pte_t构成的数组,定义于include/asm-i386/page.h中。


定义了一个用来说明页面保护的结构pgprot_t。
在实际使用中,pgprot的数值总是小于0x1000,而pte中的指针部分则总是大于0x1000,将二者合在一起就得到实际用于页面表中的表项。


表项PTE的高20位可以看作是物理页面的序号。
pte_t中的低12位用于页面的状态信息和访问权限。


内核中有个全局量mem_map,是一个指针,指向一个page数据结构的数组。
每个page数据结构代表着一个物理页面,整个数组就代表着系统中的全部物理页面。


页面表项的高20位对于软件和MMU硬件有着不同的意义。
对于软件,这是一个物理页面的序号,可以通过它从mem_map找到代表这个物理页面的page数据结构。
对于硬件,就是物理页面的起始地址。


在内核代码中,常常需要根据虚存地址找到相应物理页面的page数据结构。

宏操作vir_to_page,代表物理页面的page数据结构是在文件include/linux/mm.h中定义。



系统中的每一个物理页面都有一个page结构(或mem_map_t)。


系统在初始化时根据物理内存的大小建立起一个page结构数组mem_map,作为物理页面的“仓库”。
物理页面划分成ZONE_DMA和ZONE_NORMAL两个管理区(根据系统配置,还可能有第三个管理区ZONE_HIGHMEM,用于物理地址超过1GB的存储空间)。


DMA使用的页面要单独加以管理:
有些外设(ISA)要求用于DMA的物理地址不能过高。
DMA不经过MMU提供的地址映射,当DMA所需的缓冲区超过一个物理页面的大小时,就要求两个页面在物理上连续。


每个管理区都有一个数据结构,即zone_struct数据结构。
在zone_struct数据结构中有一组“空闲区间”(free_area_t)队列,按块的大小分别加以管理。


“均质存储结构”(uniform Memory Architecture),简称UMA。
“非均质存储结构”(Non-Uniform Memory Architecture),简称NUMA。


虚存空间的管理以进程为基础,每个进程都有各自的虚存(用户)空间。
一个进程所需要使用的虚存空间中的各个部位未必是连续的,通常形成若干离散的虚存“区间”。
对虚存空间的抽象是一个重要的数据结构,在Linux内核中,就是vm_area_struct数据结构,定义于include/linux/mm.h中。


结构中的成员vm_page_prot和vm_flags用于表示应有的访问权限和属性。


属于同一个进程的所有区间都要按虚存地址的高低次序链接在一起,结构中的vm_next指针就是用于这个目的。


在两种情况下虚存页面(或区间)会跟磁盘文件发生关系。
一种是盘区交换(swap),当内存页面不够分配时,一些久未使用的页面可以被交换到磁盘上去,腾出物理页面以供更急需的进程使用,“按需调度”页式虚存管理(demand paging)。
另一种情况是使用系统调用mmap()时,它使得一个进程可以将一个已经打开的文件映射到其用户空间中,此后就可以像访问内存一样来访问这个文件的内容,而不必通过lseek()、read()或write()等进行文件操作。


由于虚存区间(最终是页面)与磁盘文件的这种联系,在vm_area_struct结构中相应地设置了一些成员,如mapping、vm_next_share、vm_pprev_share、vm_file等,用以记录和管理此种联系。


虚存区间结构中另一个重要的成员是vm_ops,这是指向一个vm_operations_struct数据结构的指针。

vm_area_struct中有一个指针vm_mm,该指针指向一个mm_struct数据结构。

mm_struct数据结构是进程整个用户空间的抽象,也是总的控制结构。

一个进程只适用一个mm_struct结构,但一个mm_struct结构却可能为多个进程所共享。

mm_struct和vm_area_struct说明了对页面的需求;page、zone_struct等结构说明了对页面的供应;页面目录、中间目录以及页面表是中间的桥梁。

内核中经常用到的操作:给定一个属于某个进程的虚拟地址,要求找到其所属的区间以及相应的vm_area_struct结构。
这由find_vma()来实现,其代码在mm/mmap.c中。
0 0
原创粉丝点击