1. 程式人生 > >[OS] 可執行文件的裝載

[OS] 可執行文件的裝載

時有 如果 設計 包含 vma aging 技術分享 分數 linux

http://www.jianshu.com/p/e1300e7a4c48

1. 虛擬內存

在早期的計算機中,程序是直接運行在物理內存上的,程序在運行時訪問的地址就是物理地址。可是,當計算機中同時運行多個程序時,就會有很多問題。

假設我們計算有128MB內存,程序A需要10MB,程序B需要100MB,程序C需要20MB。如果我們需要同時運行程序A和B,那麽比較直接的做法是將內存的前10MB分配給程序A,10MB~110MB分配給B。
但這樣做,地址空間不隔離,內存使用效率低,程序運行的地址不確定。

解決這個問題的辦法是增加中間層,使用虛擬地址。通過某些映射的方法,將虛擬地址轉換成實際的物理地址。

每個進程都有自己獨立的虛擬地址空間,且每個進程只能訪問自己的地址空間。

2. 分段

最開始人們使用的一種叫做分段的方法,把一段虛擬空間映射到某個物理地址空間。
比如程序A需要10MB內存,我們首先假設虛擬地址空間為0x00000000~0x00A00000,然後從實際物理內存中分配一個相同大小的物理空間0x00100000~0x00B00000,最後把這兩塊相同大小的地址空間一一映射。

技術分享

但是分段的方法換入換出內存的都是整個程序,會造成大量的磁盤操作,嚴重影響速度。

3. 分頁

程序的局部性原理:當一個程序在運行時,在某個時間段內,它只是頻繁的用到一小部分數據。

於是人們想到了分頁的方法。
基本思想是,把地址空間認為的等分成固定大小的頁,由硬件決定支持多種大小的頁,操作系統選擇一個。
例如,如果虛擬空間有8頁,每頁大小由1KB,那麽虛擬地址空間就是8KB。假設計算機有13條地址線,即擁有2^13的物理尋址能力,那麽理論上物理空間可以多達8KB。假設,只配備了6KB的內存。

那麽,我們就可以把常用的數據和代碼頁裝載到內存中,把不常用的代碼和數據保存在磁盤裏,當需要的時候再把它從磁盤中讀取到內存中即可。
我們把虛擬空間的頁叫做虛擬頁(Virtual Page),把物理內存中的頁叫做物理頁(Physical Page),把磁盤中的頁叫做磁盤頁(Disk Page)。

如果進程需要的頁不在內存中時,就會觸發頁錯誤(Page Fault),硬件會捕捉到這個消息,由操作系統接管,把所需要的磁盤頁,裝入內存中,並建立虛擬內存與物理內存的對應關系。

4. 覆蓋裝入

程序執行時所需要的指令和數據必須在內存中才能正常運行。最簡單的辦法就是將程序運行所需要的指令和數據全都裝入內存中。但很多情況下,程序所需的內存數量大於物理內存數量,而且相對於磁盤來說,內存是昂貴的,所以人們想盡各種辦法,盡可能的有效利用內存。

後來研究發現,程序運行時有局部性原理,於是可以將程序最常用的部分駐留在內存中,而將一些不太常用的數據存放在磁盤裏,即動態裝入。

覆蓋裝入(Overlay)和頁映射(Paging)是兩種很典型的動態裝載方法。

覆蓋裝入在虛擬存儲發明之前使用比較廣泛,現在幾乎已經被淘汰了。覆蓋裝入的方法把挖掘內存潛力的任務交給了程序員,程序在編寫時必須手工分割成若幹塊,然後編寫一個小的輔助代碼來管理這些模塊何時應該駐留內存,何時應該被替換掉。這個小的輔助代碼就是所謂的覆蓋管理器(Overlay Manager)。
程序員需要手工將模塊按照它們之間的調用依賴關系組織成樹狀結構。覆蓋管理器,保證某個模塊被調用時,整個調用路徑上的模塊都在內存中。

覆蓋裝入的速度比較慢,是典型的用時間換空間的方法。

5. 頁映射

與覆蓋裝入類似,頁映射也不是一下子就把程序的所有數據和指令都裝入內存,而是將內存和所有磁盤中的數據和指令按照頁(Page)為單位裝載和操作。

由於頁映射包含操縱系統對頁錯誤的自動處理,可執行文件的裝載和執行就簡化了,
(1)創建一個具有獨立虛擬地址空間的進程
實際上並沒有分配空間,而是創建一個頁映射函數,將虛擬地址頁映射到物理地址頁。這些映射關系也可以等到後面程序發生頁錯誤的時候再進行設置。

(2)讀取可執行文件頭,建立虛擬地址空間與可執行文件的映射關系
這一步所作的是虛擬空間與可執行文件的映射關系。當程序執行發生頁錯誤時,操作系統將從物理內存中分配一個物理頁,然後將該“缺頁”從磁盤中讀取到內存中,再設置缺頁的虛擬頁和物理頁的映射關系,這樣程序才得以正常運行。
所以,當操作系統捕獲到缺頁錯誤時,它必須知道程序當前所需要的頁在可執行文件中的哪一個位置,這就是虛擬空間與可執行文件之間的映射關系。

與可執行文件各個段對應的,Linux中將虛擬空間劃分為了相應的段,成為虛擬內存區域(VMA),在Windows中叫做虛擬段(Virtual Section)。
例如:代碼VMA,數據VMA,堆VMA,棧VMA

(3)將CPU的指令寄存器設置成可執行文件的入口地址,啟動運行
操作系統通過設置CPU的指令寄存器將控制權轉交給進程,由此進程開始執行,這個入口地址一般是代碼段VMA的起始地址。

註:
當CPU打算執行這個地址的指令的時候,發現此頁面是一個空白頁,於是它就認為這是一個頁錯誤,CPU將控制權交給操作系統,操作系統有專門的頁錯誤處理例程來處理這種情況,操作系統查找虛擬頁與可執行文件頁之間的映射關系,計算出相應頁面在可執行文件中的偏移,然後在物理內存中分配一個物理頁面,將虛擬頁與分配的物理頁建立映射,再把控制權返還給進程,進程從剛才頁錯誤的位置重新開始執行。

[OS] 可執行文件的裝載