Linux程序的虛擬記憶體

2022-01-30 20:07:36 字數 2441 閱讀 6777

使用者程序的虛擬位址空間是linux的乙個重要的抽象:它為每個執行程序提供了同樣的系統檢視,這使得多個程序可以同時執行,而不會干擾到其他程序記憶體中的內容。

每個應用程式都有自己的線性位址空間,與所有其他應用程式隔開。

各程序虛擬位址空間起始於0,延伸到task_sieze-1,其上是核心位址空間。

使用者程式只能訪問整個位址空間的下半部分,不能訪問核心部分。如果沒有預先達成「協議」,使用者程序也不可能操作另外乙個程序的位址空間,因為後者的位址空間對前者不可見。

虛擬位址空間由許多不同的段組成,用於不同的目的。

系統中的各個程序都具有乙個struct mm_struct的例項,它可以通過 task_struct 訪問。這個例項儲存了程序的記憶體管理資訊。

struct mm_struct
可執行**占用的虛擬位址空間,開始和接收分別通過start_code和end_code標記。

初始化資料區域用start_data 和 end_data 標記。

堆的起始位址儲存在start_brk, brk表示堆區域當前的結束區域。堆的起始位址在程序生命週期中是不變的,但是堆長度會發生改變,因而brk的值也會變。

引數列表位置arg_start和arg_end, 環境變數 env_start 和 env_end 描述。

mmap_base 表示虛擬位址空間中用於記憶體對映的起始位址。

task_size 儲存了對於程序的位址空間長度。該值通常是task_size。

使用load_elf_binary載入乙個elf二進位制檔案時,將建立程序的位址空間。

由於所有使用者程序中的虛擬位址空間比可用的實體地址記憶體大得多,因此只有最常用的部分才與物理記憶體幀關聯。

核心必須提供資料結構,以建立虛擬位址空間的區域和相關資料所在位置之間的關聯。

核心利用 address_space 資料結構,提供一組方法從後備儲存器讀取資料。例如,從檔案系統讀取。因此address_space形成了乙個輔助層,將對映的資料表示為連續的線性區域,提供給記憶體管理子系統。

按需分配和填充頁稱之為按需調頁法(demand paging)。一般步驟:

程序試圖訪問使用者位址空間中的乙個記憶體位址,但使用頁表無法確定實體地址(物理記憶體中

沒有關聯頁)。

處理器接下來觸發乙個缺頁異常,傳送到核心。

核心會檢查負責缺頁區域的程序位址空間資料結構,找到適當的後備儲存器,或者確認該訪

問實際上是不正確的。

分配物理記憶體頁,並從後備儲存器讀取所需資料填充。

借助於頁表將物理記憶體頁併入到使用者程序的位址空間,應用程式恢復執行

前面我們知道,struct mm_struct 很重要,該結構提供了程序在記憶體布局的所有必要資訊。另外,它還包括下列成員,用於管理使用者程序在虛擬位址空間中的所有記憶體區域。

struct mm_struct
每個區域都通過乙個 vm_area_struct 例項描述,程序的各區域按兩種方法排序。

(1) 在乙個單鏈表上(開始於 mm_struct->mmap )。

(2) 在乙個紅黑樹中,根結點位於 mm_rb

紅黑樹用於掃瞄特定節點很高效。通過紅黑樹管理,就可以加快掃瞄速度。

增加新區域時,核心首先搜尋紅黑樹,找到剛好在新區域之前的區域。因此,核心可以向樹和線性表增加新的區域,而無需掃瞄鍊錶。

檔案的記憶體對映可以認為是兩個不同的位址空間之間的對映,用來簡化系統的工作。乙個位址空間是使用者程序的虛擬位址空間,另乙個就是檔案系統所在的位址空間。

核心建立乙個對映時,必須建立兩個位址空間之間的關聯,以支援二者以請求讀寫的形式通訊。

vm_operations_struct 結構用於完成該工作。它提供了乙個操作,來讀取已經對映到虛擬位址空間,但是其內容尚未進入物理記憶體的頁。

各種不同檔案型別(普通檔案,裝置檔案等),以及對映型別和性質相關的資訊,還會用到另外乙個結構 address_space 。

建立對映時核心和應用程式之間的互動,c標準庫提供了mmap函式建立對映。

在核心這端,提供了2個系統函式mmap和mmap2。mmap 和 mmap2 之間的差別在於偏移量的語義( off )。在這兩個呼叫中,它都表示對映在檔案中開始的位置。對於 mmap ,位置的單位是位元組,而 mmap2 使用的單位則是頁( page_size )。因此即使檔案比可用位址空間大,也可以對映檔案的一部分

堆是程序中用於動態分配變數和資料的記憶體區域。它的實現依賴標準庫提供的輔助函式(比如malloc)來分配任意長度記憶體區域。堆是乙個連續的記憶體區域,在擴充套件時自下向上增長。前面提到的mm_struct 結構,包含了堆在虛擬位址空間的起始位置和當前結束位址(start_brk和brk)。

struct mm_struct

;

brk 系統呼叫只需要乙個引數,用於指定堆在虛擬位址空間中新的結束位址(如果堆將要收縮,

當然可以小於當前值)。brk 系統呼叫實現的入口是 sys_brk 函式。

Linux程序虛擬記憶體簡介

使用者態和核心態 程序在執行時一般存在兩種狀態 使用者態 核心態。使用者態是指程序在執行使用者 核心態時指程序在執行核心 所以在linux中每個程序都存在兩個棧分別使用者使用者態和核心態的執行。使用者空間和核心空間 在32位系統中linux程序的虛擬記憶體為4gb,linux核心將這4g位元組的空間...

程序的虛擬記憶體

程序屬性資訊的task struct結構體,其中包含程序使用的記憶體資訊。在32位的作業系統中,當程序建立的時候 程式執行時 系統會為每乙個程序分配大小為4gb的虛擬記憶體空間,用於儲存程序屬性資訊。c語言中的變數,通常使用 運算子來獲得其位址,那麼,這個位址就是虛擬位址,在簡單的微控制器中,編寫的...

程序虛擬記憶體模型

以32位的作業系統為例,32位的作業系統每個程序對應的虛擬記憶體為4g 232 其中核心區1g,使用者區3g 程序控制塊pcb 1.pcb是程序存在的資料結構,系統通過pcb的存在而感知程序的存在 2.系統通過pcb對程序進行排程和管理 3.程序 pcb 與pid是一對一關係,而與程式檔案之間是多對...