Linux内核对于虚拟内存的管理是以进程为基础的,每个进程都有自己的虚存空间。而系统空间是所有进程所共享的。对虚拟空间常用数据结构vm_area_struct来描述。
struct vm_area_struct { struct mm_struct * vm_mm; /* The address space we belong to. */ unsigned long vm_start; /* Our start address within vm_mm. */ unsigned long vm_end; /* The first byte after our end address within vm_mm. */ /* linked list of VM areas per task, sorted by address */ struct vm_area_struct *vm_next; pgprot_t vm_page_prot; /* Access permissions of this VMA. */ unsigned long vm_flags; /* Flags, listed below. */ rb_node_t vm_rb; /* * For areas with an address space and backing store, * one of the address_space->i_mmap{,shared} lists, * for shm areas, the list of attaches, otherwise unused. */ struct vm_area_struct *vm_next_share; struct vm_area_struct **vm_pprev_share; /* Function pointers to deal with this struct. */ struct vm_operations_struct * vm_ops; /* Information about our backing store: */ unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE units, *not* PAGE_CACHE_SIZE */ struct file * vm_file; /* File we map to (can be NULL). */ unsigned long vm_raend; /* XXX: put full readahead info here. */ void * vm_private_data; /* was vm_pte (shared mem) */ };
其中vm_start和vm_end决定了一个虚存空间,vm_page_prot和vm_lags表示页面的访问权限。同一进程的所有区间都要按虚拟地址的高低次序链接在一起,vm_next指向下一个区间,组成一个线性链表。
区间数量较大的时候会建立AVL树,它搜索的时间复杂度为olog (n)。其中vm _mm指向mm_struct结构,是进程用户空间的抽象,在task_struct中有相应的指针指向mm_struct。
struct mm_struct { struct vm_area_struct * mmap; /* list of VMAs */ rb_root_t mm_rb; struct vm_area_struct * mmap_cache; /* last find_vma result */ pgd_t * pgd; atomic_t mm_users; /* How many users with user space? */ atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */ int map_count; /* number of VMAs */ struct rw_semaphore mmap_sem; spinlock_t page_table_lock; /* Protects task page tables and mm->rss */ struct list_head mmlist; /* List of all active mm's. These are globally strung * together off init_mm.mmlist, and are protected * by mmlist_lock */ unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; unsigned long rss, total_vm, locked_vm; unsigned long def_flags; unsigned long cpu_vm_mask; unsigned long swap_address; unsigned dumpable:1; /* Architecture-specific MM context */ mm_context_t context; };
mmap用于建立一个虚存区间结构的单线性列表;mmap_avl用于建立一个虚存区间的AVL树;mmap_cache指向最近一次用到的虚存空间;mm_count说明队列中(AVL树)有几个虚存结构;pdg指向该进程的页面目录,当进程运行的时候,pdg转换成物理地址保存在寄存器CR3中。