地址的映射机制 地址的映射机制,主要完成主存.辅存.和虚存之间的关联.包括磁盘文件到虚存的映射和虚存与内存的映射关系.为了虚拟存储和进程调度相一致.linux 采用可一系列的数据结构,和一个硬件缓存(TLB)来实现地址映射机制. mm_strut 用来描述进程的缓存. struct mm_struct { struct vm_area_struct * mmap; /* list of VMAs */ struct vm_area_struct * mmap_avl; /* tree of VMAs */ struct vm_area_struct * mmap_cache; /* last find_vma result */ pgd_t * pgd; atomic_t count; int map_count; /* number of VMAs */ struct semaphore mmap_sem; spinlock_t page_table_lock; unsigned long context; 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_cnt; /* number of pages to swap on next pass */ unsigned long swap_address; /* * This is an architecture-specific pointer: the portable * part of Linux does not know about any segments. */ void * segments; }; 他描述了一个进程的页目录,有关进程的上下文信息.以及数据.代码.堆栈的启示结束地址.还有虚拟存储取得数目.以及调度存储用的链表指针.他的参差比较高 较高层次的vm_area-struct 是描述进程的虚拟地址区域.他形成一个算相链表.按虚地址下降排列.这样当内核需要在一个给定进程页上执行给定操作时.客从双向列表中找到该项.在世想有关页的处理.如.页错误.页换出等等 他的具体结构如下: struct vm_area_struct { struct mm_struct * vm_mm; /* VM area parameters */ unsigned long vm_start; unsigned long vm_end; /* linked list of VM areas per task, sorted by address */ struct vm_area_struct *vm_next; pgprot_t vm_page_prot; unsigned short vm_flags; /* AVL tree of VM areas per task, sorted by address */ short vm_avl_height; struct vm_area_struct * vm_avl_left; struct vm_area_struct * vm_avl_right; /* For areas with inode, the list inode->i_mmap, for shm areas, * the list of attaches, otherwise unused. */ struct vm_area_struct *vm_next_share; struct vm_area_struct **vm_pprev_share; struct vm_operations_struct * vm_ops; unsigned long vm_offset; struct file * vm_file; unsigned long vm_pte; /* shared mem */ }; 而page 结构 则是对物理页进行描述的一个数据结构,他不是一个真正的物理页.而只不过是描述了一个物理页的内容和框架.作了逻辑页的一个标志;.他的标志域定义了这个页在进行的操作.链域则定义了一个双项链表.时的页框.可以很容易的查找到.为实际物理内存的使用直到方便 他的具体结构如下 typedef struct page { /* these must be first (free area handling) */ struct page *next; struct page *prev; struct inode *inode; unsigned long offset; struct page *next_hash; atomic_t count; unsigned long flags; /* atomic flags, some possibly updated asynchronously */ wait_queue_head_t wait; struct page **pprev_hash; struct buffer_head * buffers; int owner; /* temporary debugging check */ } mem_map_t; 所有的page 结构将都被转入一个叫做mem_map 的数组中. 当一个进程运行时,他的代码段和数据段将都会被调入内存.如果它使用了共享库.共享客的内容也将贝雕如内存.进程运行时.系统首先分配一个vm_area_struct 给进程.并将这各进程连结到虚拟内存的连标中去.这是根据进程的可执行影像中的信息.吧数据段和客执行代码非配内存.新分配的内存必须和进程已有的内存连结起来才能应用.这样聚会出现页故障.系统利用了请页机制来避免对物理内存的过分使用.但进程访问的虚存不在当前的物理内存时,这时系统会将需要的页调入内存.同时修改进程的页表.用来标志虚拟页是否在物理内存中. 因此,系统用了较复杂的数据结构来跟踪进程的虚拟地址.在task_struct 中包含一个指向mm_struct 结构的指针.进程的mm_struct 中则包含了进程可执行影像的页目录指针pgd.还包含了指向vm_area_struct 的几个指针,每个vm_area_struct 包含一个进程的虚拟地址区域. 一个进程有多个vm_area_stuct 结构.linux 要经常对进程分配..或调整vm_area_struct .这样对vm_area_stuct 的查找效率.对系统很有影像.所以在这里将所有的vm_area_struct 形成了一个查找效率较高的平衡二叉树结构. 我个人认为,在整个linux内核中这个地方.数据结构是最复杂的.如果把这一部分肯下来以后,整个内核便开始清晰了 |