先回憶一下elf檔案的組織結構,可以看這篇文章:linux 鏈結與elf檔案。程式執行後程序位址空間布局則和作業系統密切相關。在將應用程式載入到記憶體空間執行時,作業系統負責**段與資料段的載入,並在記憶體中為這些段分配空間。linux的程序位址空間大致如下:
核心虛擬儲存器包含了核心的**和資料結構。核心虛擬儲存器的一些區域被對映到所有程序共享的記憶體頁面,比如每個程序共享核心的**和全域性資料結構。linux也將一組連續的虛擬頁面(大小等於同種dram的總量)對映到相應的一組連續的物理頁面。這使得核心可以遍歷的訪問物理儲存的任何特定位置。核心虛擬位址儲存器的其他區域包含了每個程序都不同的資料,如頁表、核心在程序上下文執行時所使用的棧,以及記錄虛擬位址空間當前組織的各種資料結構。
虛擬位址不合法。缺頁處理程式搜尋程序區域結構鍊錶,把a和每個區域的vm_start和vm_end比較,不合法,觸發段錯誤,kill程序。
訪問不合法。主要看程序是否有讀寫或執行這個區域內頁面的許可權,不合法則觸發保護異常,linux也會報段錯誤,終止程序。
正常缺頁。核心判斷位址和訪問都是合法的,那麼選擇犧牲乙個頁面,如果被修改過交換出去,換入新頁面更新頁表。
如下圖:
通過下面的圖可以一看一下linux核心資料結構組織乙個程序虛擬位址空間的方式。核心為系統中每個程序維護了乙個單獨的任務結構task_struct
, 結構中包含了核心執行該程序的所有資訊。
函式呼叫借助的就是棧。linux中ulimit -s
命令可檢視和設定棧最大值,調高棧容量可能會增加記憶體開銷和啟動時間。
核心將硬碟檔案的內容直接對映到記憶體,借助linux的mmap()系統呼叫。這裡也用來對映elf檔案用到的動態鏈結庫。
分配的堆記憶體是經過位元組對齊的空間,以適合原子操作。堆管理器通過鍊錶管理每個申請的記憶體,由於堆申請和釋放是無序的,最終會產生記憶體碎片。
堆的末端由break指標標識,當堆管理器需要更多記憶體時,可通過系統呼叫brk()和sbrk()來移動break指標以擴張堆,一般由系統自動呼叫。
主要用來放全域性變數和靜態區域性變數,位址編譯期確定。
放的函式指令,位址編譯期確定。
computer systems organization
xv6, a ****** unix-like teaching operating system
linux虛擬位址空間布局
Linux作業系統 程序位址空間
程序獲得線性區的情況 建立乙個新的程序,fork execve 正在執行的程序,裝入乙個不同的程式,pid不變,但是線性位址空間重新分配。execve mmap檔案對映,建立乙個線性區來對映這個檔案 使用者態堆疊的擴充套件 ipc共享記憶體,與其他程序共享資料,核心給該程序分配乙個線性區 系統中的所...
作業系統原理 虛擬位址
儲存系統是有層次的,從快到慢依次是 cpu暫存器 靜態sram 動態dram 磁碟。如下圖 如 inter core i7 儲存結構如下 i7的儲存架構支援48 bit虛擬位址,52 bit實體地址.page size啟動時可配置 4kb or 4mb,linux使用4kb,4 level page...
作業系統核心原理 3 程序原理(下) 程序通訊
程序作為人類的發明,自然也免不了脫離人類的習性,也有通訊的需求。如果程序之間不進行任何通訊,那麼程序所能完成的任務就要大打折扣。人類的通訊方式無外乎對白 通過聲音溝通 打手勢 寫信 發電報 擁抱等方法。同理,程序也可以通過同樣的方式來進行通訊。本篇我們就來看看程序的這些互動方式。人們最常用的通訊手段...