天天看點

mm_struct

一個程序的虛拟位址空間主要由兩個資料結來描述。一個是最高層次的:mm_struct,一個是較高層次的:vm_area_structs。最高層次的mm_struct結構描述了一個程序的整個虛拟位址空間。較高層次的結構vm_area_truct描述了虛拟位址空間的一個區間(簡稱虛拟區)。每個程序隻有一個mm_struct結構,在每個程序的task_struct結構中,有一個指向該程序的結構。可以說,mm_struct結構是對整個使用者空間的描述。

  mm_strcut 用來描述一個程序的虛拟位址空間,在/include/linux/sched.h 中描述如下:

struct mm_struct {

  struct vm_area_struct * mmap; /* 指向虛拟區間(VMA)連結清單 */

  rb_root_t mm_rb; /*指向red_black樹*/

  struct vm_area_struct * mmap_cache; /* 指向最近找到的虛拟區間*/

  pgd_t * pgd; /*指向程序的頁目錄*/ 

  atomic_t mm_users; /* 使用者空間中的有多少使用者*/

  atomic_t mm_count; /* 對"struct mm_struct"有多少引用*/

  int map_count; /* 虛拟區間的個數*/

  struct rw_semaphore mmap_sem;

  spinlock_t page_table_lock; /* 保護任務頁表和 mm->rss */

  struct list_head mmlist; /*所有活動(active)mm的連結清單 */

  unsigned long start_code, end_code, start_data, end_data; /*start_code 代碼段起始位址,end_code 代碼段結束位址,start_data 資料段起始位址, start_end 資料段結束位址*/

  unsigned long start_brk, brk, start_stack; /*start_brk 和brk記錄有關堆的資訊, start_brk是使用者虛拟位址空間初始化時,堆的結束位址, brk 是目前堆的結束位址, start_stack 是棧的起始位址*/

  unsigned long arg_start, arg_end, env_start, env_end; /*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;

  mm_context_t context; /* Architecture-specific MM context, 是與平台相關的一個結構,對i386 幾乎用處不大*/

};

  下面是通過程式列印出來的MM_STRUCT的樣例:

 取自Memory Management structure的相關資訊 針對如下任務 'cat' (pid=31334)

pgd=D2862000 mmap=D28CFAC4 map_count=17 mm_users=1 mm_count=1

start_code=08048000 end_code=0804C7B4

start_data=0804D7B4 end_data=0804DE40

start_brk=0804E000 brk=0806F000

arg_start=BFCD1973 arg_end=BFCD1980

env_start=BFCD1980 env_end=BFCD1FF3

start_stack=BFCD14E0 down_to=BFCBC4E0

<a href="http://blog.163.com/tianhail@126/blog/static/140395915201031944326379/">http://blog.163.com/tianhail@126/blog/static/140395915201031944326379/</a>

 Linux核心中,關于虛存管理的最基本的管理單元應該是struct vm_area_struct了,它描述的是一段連續的、具有相同通路屬性的虛存空間,該虛存空間的大小為實體記憶體頁面的整數倍。

  下面是struct vm_area_struct結構體的定義:

QUOTE:

/*

* This struct defines a memory VMM memory area. There is one of these

* per VM-area/task. A VM area is any part of the process virtual memory

* space that has a special rule for the page-fault handlers (ie a shared

* library, the executable area etc).

*/

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 long 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 an address space and backing store,

* one of the address_space-&gt;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;

struct vm_operations_struct * vm_ops;

unsigned long vm_pgoff; /* offset in PAGE_SIZE units, *not* PAGE_CACHE_SIZE */

struct file * vm_file;

unsigned long vm_raend;

void * vm_private_data; /* was vm_pte (shared mem) */

  vm_area_struct結構所描述的虛存空間以 vm_start、vm_end成員表示,它們分别儲存了該虛存空間的首位址和末位址後第一個位元組的位址,以位元組為機關,是以虛存空間範圍可以用 [vm_start, vm_end)表示。

  通常,程序所使用到的虛存空間不連續,且各部分虛存空間的通路屬性也可能不同。是以一個程序的虛存空間需要多個vm_area_struct結構來描述。在vm_area_struct結構的數目較少的時候,各個vm_area_struct按照升序排序,以單連結清單的形式組織資料(通過vm_next 指針指向下一個vm_area_struct結構)。但是當vm_area_struct結構的資料較多的時候,仍然采用連結清單組織的化,勢必會影響到它的搜尋速度。針對這個問題,vm_area_struct還添加了vm_avl_hight(樹高)、vm_avl_left(左子節點)、

vm_avl_right(右子節點)三個成員來實作AVL樹,以提高vm_area_struct的搜尋速度。

  假如該vm_area_struct描述的是一個檔案映射的虛存空間,成員vm_file便指向被映射的檔案的file結構,vm_pgoff是該虛存空間起始位址在vm_file檔案裡面的檔案偏移,機關為實體頁面。

  一個程式可以選擇MAP_SHARED或MAP_PRIVATE共享模式将一個檔案的某部分資料映射到自己的虛存空間裡面。這兩種映射方式的差別在于:MAP_SHARED映射後在記憶體中對該虛存空間的資料進行修改會影響到其他以同樣方式映射該部分資料的程序,并且該修改還會被寫回檔案裡面去,也就是這些程序實際上是在共用這些資料。而MAP_PRIVATE映射後對該虛存空間的資料進行修改不會影響到其他程序,也不會被寫入檔案中。

  來自不同程序,所有映射同一個檔案的vm_area_struct結構都會根據其共享模式分别組織成兩個連結清單。連結清單的鍊頭分别是:vm_file-&gt;f_dentry-&gt;d_inode-&gt;i_mapping-&gt;i_mmap_shared, vm_file-&gt;f_dentry-&gt;d_inode-&gt;i_mapping-&gt;i_mmap。而 vm_area_struct結構中的vm_next_share指向連結清單中的下一個節點;vm_pprev_share是一個指針的指針,它的值是連結清單中上一個節點(頭節點)結構的vm_next_share(i_mmap_shared或i_mmap)的位址。

  程序建立vm_area_struct結構後,隻是說明程序可以通路這個虛存空間,但有可能還沒有配置設定相應的實體頁面并建立好頁面映射。在這種情況下,若是程序執行中有指令需要通路該虛存空間中的記憶體,便會産生一次缺頁異常。這時候,就需要通過vm_area_struct結構裡面的 vm_ops-&gt;nopage所指向的函數來将産生缺頁異常的位址對應的檔案資料讀取出來。

  vm_flags主要儲存了程序對該虛存空間的通路權限,然後還有一些其他的屬性。vm_page_prot是新映射的實體頁面的頁表項pgprot 的預設值。

<a href="http://www.deansys.com/doc/ldd3/ch15.html">http://www.deansys.com/doc/ldd3/ch15.html</a>

繼續閱讀