struct vm_area_struct結構體學習
阿新 • • 發佈:2018-12-20
Linux通過型別為vm_area_struct的結構體物件實現線性區,該結構定義了記憶體VMM記憶體區域。 每個VM區域/任務中有一個。 VM區域是程序虛擬記憶體空間的任何部分,它具有頁面錯誤處理程式的特殊規則(即共享庫,可執行區域等)。
vm_area_struct具體內容如下所示:
struct vm_area_struct { /* The first cache line has the info for VMA tree walking. 第一個快取行具有VMA樹移動的資訊*/ 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 每個任務的VM區域的連結列表,按地址排序*/ struct vm_area_struct *vm_next, *vm_prev; struct rb_node vm_rb; /* 此VMA左側最大的可用記憶體間隙(以位元組為單位)。 在此VMA和vma-> vm_prev之間, 或者在VMA rbtree中我們下面的一個VMA與其->vm_prev之間。 這有助於get_unmapped_area找到合適大小的空閒區域。 */ unsigned long rb_subtree_gap; /* Second cache line starts here. 第二個快取行從這裡開始*/ struct mm_struct *vm_mm; /* 我們所屬的address space*/ pgprot_t vm_page_prot; /* 此VMA的訪問許可權 */ unsigned long vm_flags; /* Flags, see mm.h. */ /* 對於具有地址空間(address apace)和後備儲存(backing store)的區域, 連結到address_space->i_mmap間隔樹,或者連結到address_space-> i_mmap_nonlinear列表中的vma。 */ union { struct { struct rb_node rb; unsigned long rb_subtree_last; } linear; struct list_head nonlinear; } shared; /* 在其中一個檔案頁面的COW之後,檔案的MAP_PRIVATE vma可以在i_mmap樹和anon_vma列表中。 MAP_SHARED vma只能位於i_mmap樹中。 匿名MAP_PRIVATE,堆疊或brk vma(帶有NULL檔案)只能位於anon_vma列表中。 */ struct list_head anon_vma_chain; /* Serialized by mmap_sem & * page_table_lock 由mmap_sem和* page_table_lock序列化*/ struct anon_vma *anon_vma; /* Serialized by page_table_lock 由page_table_lock序列化*/ /* 用於處理此結構體的函式指標 */ const struct vm_operations_struct *vm_ops; /* 後備儲存(backing store)的資訊: */ unsigned long vm_pgoff; /* 以PAGE_SIZE為單位的偏移量(在vm_file中),*不是* PAGE_CACHE_SIZE*/ struct file * vm_file; /* 我們對映到檔案(可以為NULL)*/ void * vm_private_data; /* 是vm_pte(共享記憶體) */ #ifndef CONFIG_MMU struct vm_region *vm_region; /* NOMMU對映區域 */ #endif #ifdef CONFIG_NUMA struct mempolicy *vm_policy; /* 針對VMA的NUMA政策 */ #endif };
我們可以把vm_area_struct稱為線性區描述符,它標識了一個線性地址區間。
程序所擁有的線性區從來不重疊,並且核心盡力把新分配的線性區與緊鄰的現有線性區進行合併。如果兩個相鄰區的訪問許可權相匹配,就能把他們合併在一起。
程序所有的線性區是通過一個簡單的連結串列連結在一起的,出現在連結串列中的線性區是按記憶體地址的升序排列的。每兩個線性區可以由未用的記憶體地址區隔開。核心通過程序的記憶體描述符的mmap欄位來查詢線性區,其中mmap欄位指向連結串列中的第一個線性區描述符。同時記憶體描述符的map_count欄位存放程序所擁有的線性區數目。