Linux可执行文件如何装载进虚拟内存
開篇先拋出幾個問題,之后逐個擊破:
-
什么是進程的虛擬地址空間?為什么進程要有自己的虛擬地址空間,這樣做有什么好處?
-
我們都聽說過頁映射,什么是頁映射,操作系統為什么要以頁映射方式將程序映射到進程地址空間,這樣做有什么好處?程序運行過程中發生頁錯誤如何處理?
-
什么是進程?從操作系統的角度來看,進程是如何被建立的?
-
進程虛擬地址空間的分布是什么樣的?
-
Linux是如何裝載并運行ELF程序的?
虛擬地址空間
what:虛擬地址空間就是我們常說的虛擬內存,虛擬內存是計算機系統內存管理的一種技術。它使得應用程序認為它擁有連續可用的內存(一個連續完整的地址空間),而實際上,它通常是被分隔成多個物理內存碎片,還有部分暫時存儲在外部磁盤存儲器上,在需要時進行數據交換。與沒有使用虛擬內存技術的系統相比,使用這種技術的系統使得大型程序的編寫變得更容易,對真正的物理內存的使用也更有效率。當處理器讀取或寫入內存位置時,都會使用虛擬地址。在讀取或寫入操作過程中,處理器會將虛擬地址轉換為物理地址。
why:使用虛擬內存有如下好處:
程序員無需操心如何存儲數據或者程序等內容。
程序可以使用一系列連續的虛擬地址來訪問物理內存中不連續的大內存區域,用戶看到的是連續地址,而無需關心更底層物理地址的排布。
通過使用虛擬內存,程序可以使用大于實際可用物理內存的空間,當物理內存不夠用時,操作系統會將物理內存頁保存在磁盤文件,數據頁或者代碼頁會根據需要在物理內存和磁盤之間移動。
不同進程使用的虛擬地址彼此隔離,用戶無需擔心會影響到其它程序內存地址中的數據,操作系統的內存管理模塊會將虛擬地址映射到物理地址。
頁映射
background:程序運行時所需要的指令和數據必須放在內存中才可以正常執行,最簡單的辦法就是將運行所需要的指令和數據全部裝進內存,但是很多時候程序需要的內存可能大于實際可用的物理內存,為了解決這種不夠用的問題引入了動態裝入的概念,可以將程序最常用的部分駐留在內存中,而將一些不常用的數據存在磁盤中。
what:頁映射不是一次性將所有的程序和數據裝入內存,而是將內存和磁盤中的數據和指令按頁為單位分成若干份,以后所有的裝載和操作的單位就是頁。頁的大小不固定,但是一般都是4096字節。
how:如下圖,舉個例子,可執行程序所需要的指令和數據總和占8個頁,編號為VP0-VP7,而實際的物理內存只有4個頁,編號為PP0-PP3,4個頁的物理內存無法同時將8個頁的程序都裝載進去,所以需要動態裝入,假設程序入口地址在VP0,這時內核發現VP0不在內存中,所以將VP0分配給了PP0,將VP0的內容裝入了PP0,運行一段后程序需要用到VP2,內核又將VP2分配給了PP1,之后又用到VP4和VP6,內核又分別分配給了PP2和PP3。這時候程序只需要VP0、VP2、VP4和VP6這四個頁就可以一直運行下去,如果程序又需要VP5,那內核就必須會放棄正在使用的四個內存頁中的一個才可以把VP5裝載進去繼續執行,至于選擇哪個,操作系統內核會有多種換出算法來處理這種問題。
why:其實上面已經介紹了原因,如果一次性把所有指令和數據都加載到內存中,物理內存可能不夠用,所以需要使用動態裝入,所以引入了頁映射的方法。
進程如何被建立
這里首先需要弄清楚程序和進程的區別?程序(可執行文件)是一個靜態的概念,它就是預先編譯好的指令和數據集合的一個文件,進程則是一個動態的概念,它是程序運行的一個過程。
從操作系統角度看,一個進程最關鍵的特征是它擁有獨立的虛擬地址空間,很多時候一個程序被執行都伴隨著一個新的進程被創建,之后裝載相應的可執行文件并運行。上述經歷了什么步驟?
-
創建一個獨立的虛擬地址空間:這里的創建空間并不是真正的創建空間,而是創建映射函數所需要的數據結構,方便后面映射需要。
-
讀取可執行文件頭,建立虛擬空間和可執行文件的映射關系:上面的映射數據結構是為了建立虛擬空間到物理內存的映射關系,這一步是虛擬空間與可執行文件的映射關系。
-
將CPU的指令寄存器設置成可執行文件入口,啟動運行:這里可以簡單的理解為操作系統執行了一條跳轉指令,跳轉到可執行文件的入口地址。
頁錯誤:當程序執行一個地址的指令時,發現是個空頁面,所以就認為是個頁錯誤,這時候控制權交由操作系統,操作系統有專門的錯誤處理程序處理這種情況,查詢第二步驟建立的映射數據結構,找到空頁面所在的虛擬內存區域,計算出相應的頁面在可執行文件中的偏移,然后在物理內存中分配一個物理頁面,將進程中的該虛擬頁與物理頁建立映射關系,控制權返還給進程,進程從頁錯誤的位置繼續執行。
link
總結
以上是生活随笔為你收集整理的Linux可执行文件如何装载进虚拟内存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谈谈程序链接及分段那些事
- 下一篇: Linux 中的动态链接库和静态链接库是