Linux 程序位址空間 簡介

2021-06-16 14:52:23 字數 2629 閱讀 5954

程序虛擬位址空間是linux的乙個重要抽象,系統為每乙個執行的linux程序提供了4gb的虛擬位址空間,程序之間不會相互干擾,僅能訪問自己的虛擬位址空間位址。linux程序的虛擬位址空間分為user和kernel兩個部分,0~3g是為程序的user位址空間,3g~4g為kernel位址空間。此外程序虛擬位址空間也使得許多高階的linux技術得以實現:比如記憶體對映,延遲分配,共享記憶體等。因此程序虛擬記憶體技術和kernel部分的位址空間管理相比,要複雜的多。

希望通過如下小節,徹底搞清程序虛擬位址空間。

1 程序虛擬位址空間 簡介

2. 程序虛擬位址空間 涉及的資料結構

3. 程序虛擬位址空間 輔助操作函式

4. 程序虛擬位址空間 操作函式

5. page fault處理函式

6. 堆的管理

虛擬位址

又稱為線性位址,對於ia32和其他的32bit體系結構來說,虛擬位址範圍是0~4g,我們把虛擬位址劃分為兩個空間:user mode位址空間和kernel模式位址空間。程序只能訪問虛擬位址,通過程序頁表由mmu進行位址轉換(程序頁表儲存著虛擬位址到實體地址的對映關係),當cpu訪問虛擬位址時,mmu會自動把虛擬位址翻譯為對應的實體地址,並把請求傳送給翻譯後的實體地址。

實體地址

物理記憶體單元的位址,包括ram, rom, 模組暫存器,io單元的訪問位址。除了dma操作外,作業系統都是通過虛擬位址訪問這些記憶體,裝置和io的。實體地址散布在0~4g的位址範圍內,但是kernel會吧他們對映到3g~4g的kernel虛擬位址空間內

頁框

也是物理頁框,為了便於管理,把物理記憶體切分為4kb大小的頁框。

使用者位址空間

虛擬位址空間的一部分,大小依賴於user kernel空間的劃分比例,一般情況下是3g,使用者程序只能訪問使用者位址空間的資料,如果想要訪問核心空間,那麼必須通過系統呼叫進入核心空間。由於程序使用者位址空間的頁表不同(也有列外,從乙個程序fork出來的子程序實際上共享整個位址空間),因此訪問乙個程序的使用者位址空間不會影響到其他的程序。

kernel位址空間

虛擬(線性)位址空間的一部分,一般是1g大小,所有程序的kernel位址空間頁表都是相同的,也就是說他們的kernel空間的內容是完全相同的。在kernel空間,對系統有絕對的控制權,可以訪問任意的系統資源。一般來說(之所以用一般,是因為這也是體系結構相關,配置相關的),核心空間的劃分如下。

anonymous匿名對映

匿名對映是指對映區沒有關聯到磁碟上的檔案,通常用做程序間共享記憶體。

推遲分配頁面 demand paging

推遲分配是動態記憶體分配技術,在建立虛擬位址空間時,並不會建立虛擬位址到實體地址的對映,直到應用訪問了這個虛擬位址空間內的位址。處理器觸發page fault時,核心才會嘗試分配物理頁框,並建立這種對映關係。

推遲分配是絕對必要的:

1. 雖然大多數程序在3g的位址空間內僅占用了很小的空間,來建立虛擬位址對映,但是所有程序相加,這個數目仍然遠超過系統的物理記憶體。

2. 乙個程序映**乙個巨大的檔案進行編輯,但是實際上編輯過程僅僅操作檔案末尾的幾頁,因此根本沒有必要為整個檔案都建立頁面對映。

如果留心,就會發現推遲遍布作業系統的每個角落,比如檔案的遲寫,檔案buffer的存在,甚至處理器的cache寫操作。

堆是程序用於動態分配變數和資料的記憶體區域,堆的分配和管理對程式設計師來說是不可見的。程式設計師使用的是c庫提供的標準介面malloc,而malloc則呼叫brk系統呼叫來擴大或者縮小堆。

棧起始於stack_top,如果設定了pf_randomize,那麼起始點要比stack_top減少乙個小的隨機量。每個體系結構都定義了自己的隨機量。

copy on write

copy on write 是作業系統以及其他軟體系統常見的一種技術,即大家共享乙份初始copy,當writer1要更改時,就copy乙份資料到給writer,writer在這個新建的copy上進行修改。

當linux fork程序時,子程序最初的頁表是從父程序複製的,頁幀的內容並沒有被複製(太多了,也太低效),子程序和父程序以及兄弟們共享這些物理頁框。當然這些共享的頁框不能夠被修改的,如果想修改頁框,那麼就會發生乙個異常。頁面異常處理函式會複製乙個新頁框並標記為可寫,而原始的頁框保持write-protected。

反向對映

虛擬記憶體對映的目的就是給定虛擬位址空間,通過頁表找到虛擬位址空間對應的物理頁框。所謂反向對映就是這個查詢的反向過程,給定乙個物理頁框,找到所有映**這個頁面的虛擬位址。由於虛擬位址到實體地址的對映是多對一的,所以必須要增加一些附加的資料結構和方法,來實現這種反向對映。

之所以要引入反向對映,是因為在換出頁時,需要更新所有關聯了該物理頁面的虛擬位址對應的頁表。

linux 程序位址空間

乙個linux程序的虛擬位址空間分布如下圖所示,分為使用者空間和核心空間,對於乙個32位作業系統來說,4gb的空間分成兩部分,低位址的0 3g給使用者空間,高位址的3g 4g給核心空間 2.1 唯讀資料段 rodata,又叫做常量資料段 存放唯讀資料 字串常量和const修飾的全域性變數 const...

Linux程序位址空間

我們知道,在32位機器上linux 作業系統中的程序的位址空間大小是4g,其中0 3g是使用者空間,3g 4g是核心空間。其實,這個4g的位址空間是不存在的,也就是我們所說的虛擬記憶體空間。c程式一直由下列幾部分組成 a.正文段。這是由cpu執行的機器指令部分。通常,正文段是可共享的,所以即使是經常...

程序位址空間

這篇文章應該不能說是原創的,這裡的記錄都是我通過閱讀整理來的,並沒有太多的自己的想法。資料 現代作業系統 之所以去了解位址空間也是因為在學習dll的時候看到要將dll對映到程式的位址空間,不甚明了所以去查詢相關的資料。位址空間其實很好理解 當然針對早期的機器 早期的機器是沒有ram,rom,cach...