15.1 位址空間
程序位址空間由程序可定址的虛擬記憶體組成。每個程序都有乙個32位或64位的平坦位址空間,空間的大小取決於體系結構。術語「平坦」指的是位址空間範圍是乙個獨立的連續區間。一些作業系統提供了段位址空間,這種位址空間並非乙個獨立的線性區域,而是被分段的,現代採用虛擬記憶體的作業系統通常都使用平坦位址空間而不是分段式的記憶體模式。通常,每個程序都有唯一的這種平坦位址空間,乙個程序的位址空間與另一進城的位址空間即使有相同的記憶體位址,實際上也互不相干,我們稱這樣的程序為執行緒。
儘管乙個程序可以定址4gb的虛擬記憶體(32位),並不表示它有權訪問所有的虛擬位址。可以被合法訪問的位址空間稱為記憶體區域。通過核心,程序可以給自己的位址空間動態的新增或減少記憶體區域。
程序只能訪問有效區域的記憶體位址。每個記憶體區域也具有相關許可權如對相關程序有可讀、可寫、可執行屬性。如果乙個程序訪問了不在有效範圍中的記憶體區域,或以不正確的方式訪問了有效位址,那麼核心就會終止該程序,並返回段錯誤資訊。
記憶體區域包含各種記憶體物件:
1、可執行檔案**的記憶體對映,稱為**段;
2、可執行檔案的已初始化全域性變數的記憶體對映,稱為資料段;
3、未初始化全域性變數,bss段的零頁的記憶體對映
4、用於程序使用者空間棧的零頁記憶體對映
5、每乙個諸如c庫或動態連線程式等共享庫的**段、資料段和bss也會被載入程序的位址空間
6、任何記憶體對映檔案
7、任何共享記憶體段
8、任何匿名對映,比如由malloc()分配的記憶體。
15.2 記憶體描述符
核心使用記憶體描述符結構體表示程序的位址空間,該結構包含了和程序位址空間有關的全部資訊。由mm_struct結構體表示
struct mm_structvm_set;
struct prio_tree_node prio_tree_node;
}shared;
struct list_head anon_vma_node;//anon_vma項
struct anon_vma *anon_vma;//匿名vma物件
struct vm_operations_struct *vm_ops;//相關操作
unsigned long vm_pgoff; //檔案的偏移量
struct file *vm_file; //被對映的檔案
void *vm_private_data;//私有資料
15.3.1 vma標誌
15.3.2 vma操作
struct vm_operations_structelse
rb_node = rb_node->rb_right;
if(vma)
mm->mmap_cache = vma;
return vma;
15.4.2 find_vma_prev()
與find_vma()工作方式相同,但是他返回第乙個小於addr的vma。
struct vm_area_struct * find_vma_prev(struct mm_struct *mm,unsigned long addr,struct vm_area_struct *pprev);
pprev引數存放指向先於addr的vma指標。
15.4.3 find_vma_intersection()
返回第乙個和指定位址區間相交的vma
static inline struct vm_area_struct *
find_vma_intersection(struct mm_struct *mm,unsigned long start_addr,unsigned long end_addr){
struct vm_area_struct *vma;
vma = find_vma(mm,start_addr);
if(vma&&end_addr<=vma->vm_start)
vma = null;
return vma;
核心使用do_mmap()函式建立乙個新的線性位址區間。如果建立的位址區間和乙個已經存在的位址區間相鄰,並且他們具有相同的訪問許可權,則這兩個區間合併為乙個。do_mmap()會將乙個位址區間加入到程序的位址空間中。
如果系統呼叫do_mmap()的引數中有無效引數,那麼它返回乙個負值;否則,它會在虛擬記憶體中分配乙個合適的新記憶體位址。如果可能,將新區域和鄰近區域進行合併,否則核心從vm_area_cachep長位元組(slab)快取中分配乙個vm_area_struct結構體,並且使用vma_link()函式將新分配的記憶體區域新增到程序位址空間的記憶體區域鍊錶和紅黑樹中,隨後還要更新記憶體描述符中的total_vm域,然後才返回新分配的位址空間的初始位址。
在使用者空間可以通過mmap()系統呼叫獲取核心函式do_mmap()的功能。
15.6 munmap()和do_munmap():刪除位址區間
int do_munmap(struct mm_struct *mm,unsigned long start,size_t len);
系統呼叫munmap()給使用者空間提供了一種從自身位址空間中刪除指定位址區間的方法。
int munmap(void *start,size_t length);
15.7 頁表
位址轉換工作需要通過查詢頁表才能完成。多數體系結構實現了乙個翻譯後的緩衝器(translat lookaside buffer,tlb).tlb作為乙個將虛擬位址對映到實體地址的硬體快取,當請求訪問乙個虛擬位址時,處理器將首先檢查tlb中是否快取了改虛擬位址到實體地址的對映,如果在快取中直接命中,實體地址立刻返回;否則,就需要再通過頁表搜尋需要的實體地址。
程序位址空間
這篇文章應該不能說是原創的,這裡的記錄都是我通過閱讀整理來的,並沒有太多的自己的想法。資料 現代作業系統 之所以去了解位址空間也是因為在學習dll的時候看到要將dll對映到程式的位址空間,不甚明了所以去查詢相關的資料。位址空間其實很好理解 當然針對早期的機器 早期的機器是沒有ram,rom,cach...
程序位址空間
kernel筆記 程序位址空間 2013 09 03 09 53 49 分類 linux 下圖是x86 64下linux程序的預設記憶體布局形式 下面逐一分析以上各個位址段的含義。text 段 段,從虛擬記憶體位址00400000開始,使用pmap 可以檢視到,這個位址是固定的 linux pmap...
程序位址空間
程序位址空間 1.可執行檔案 的記憶體對映,稱為 段 2.可執行檔案的已初始化全域性變數的記憶體對映,稱為資料段 3.包含未初始化的全域性變數,也就是bss段的零頁的記憶體對映 4.用於程序使用者控制項棧的零頁的記憶體對映 5.任何記憶體對映檔案 6.任何共享記憶體段 7.任何匿名的記憶體對映,比如...