.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;
};
他描述了一個進程的頁目錄,有關(guān)進程的上下文信息.以及數(shù)據(jù).代碼.堆棧的啟示結(jié)束地址.還有虛擬存儲取得數(shù)目.以及調(diào)度存儲用的鏈表指針.他的參差比較高
較高層次的vm_area-struct 是描述進程的虛擬地址區(qū)域.他形成一個算相鏈表.按虛地址下降排列.這樣當(dāng)內(nèi)核需要在一個給定進程頁上執(zhí)行給定操作時.客從雙向列表中找到該項.在世想有關(guān)頁的處理.如.頁錯誤.頁換出等等
他的具體結(jié)構(gòu)如下:
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 結(jié)構(gòu) 則是對物理頁進行描述的一個數(shù)據(jù)結(jié)構(gòu),他不是一個真正的物理頁.而只不過是描述了一個物理頁的內(nèi)容和框架.作了邏輯頁的一個標(biāo)志;.他的標(biāo)志域定義了這個頁在進行的操作.鏈域則定義了一個雙項鏈表.時的頁框.可以很容易的查找到.為實際物理內(nèi)存的使用直到方便
他的具體結(jié)構(gòu)如下
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 結(jié)構(gòu)將都被轉(zhuǎn)入一個叫做mem_map 的數(shù)組中.
當(dāng)一個進程運行時,他的代碼段和數(shù)據(jù)段將都會被調(diào)入內(nèi)存.如果它使用了共享庫.共享客的內(nèi)容也將貝雕如內(nèi)存.進程運行時.系統(tǒng)首先分配一個vm_area_struct 給進程.并將這各進程連結(jié)到虛擬內(nèi)存的連標(biāo)中去.這是根據(jù)進程的可執(zhí)行影像中的信息.吧數(shù)據(jù)段和客執(zhí)行代碼非配內(nèi)存.新分配的內(nèi)存必須和進程已有的內(nèi)存連結(jié)起來才能應(yīng)用.這樣聚會出現(xiàn)頁故障.系統(tǒng)利用了請頁機制來避免對物理內(nèi)存的過分使用.但進程訪問的虛存不在當(dāng)前的物理內(nèi)存時,這時系統(tǒng)會將需要的頁調(diào)入內(nèi)存.同時修改進程的頁表.用來標(biāo)志虛擬頁是否在物理內(nèi)存中.
因此,系統(tǒng)用了較復(fù)雜的數(shù)據(jù)結(jié)構(gòu)來跟蹤進程的虛擬地址.在task_struct 中包含一個指向mm_struct 結(jié)構(gòu)的指針.進程的mm_struct 中則包含了進程可執(zhí)行影像的頁目錄指針pgd.還包含了指向vm_area_struct 的幾個指針,每個vm_area_struct 包含一個進程的虛擬地址區(qū)域.
一個進程有多個vm_area_stuct 結(jié)構(gòu).linux 要經(jīng)常對進程分配..或調(diào)整vm_area_struct .這樣對vm_area_stuct 的查找效率.對系統(tǒng)很有影像.所以在這里將所有的vm_area_struct 形成了一個查找效率較高的平衡二叉樹結(jié)構(gòu).
我個人認為,在整個linux內(nèi)核中這個地方.數(shù)據(jù)結(jié)構(gòu)是最復(fù)雜的.如果把這一部分肯下來以后,整個內(nèi)核便開始清晰了