日期:2014-05-16  浏览次数:20800 次

Linux内核之虚拟内存管理(一)

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中。

?

?