從操作系統角度看可執行文件的裝載和執行
進程的建立:
創建一個進程,然后裝載相應的可執行文件并執行。
1.創建一個獨立的虛擬地址空間。
2.讀取可執行文件頭,并且建立虛擬空間與可執行文件的映射關系。
3.將cpu的指令寄存器設置為可執行文件的入口地址,啟動運行。
1.創建虛擬地址空間
創建一個虛擬地址空間并不是真正地創建空間而是創建映射函數所需要的相應的數據結構,在i386的linux下,創建虛擬地址實際上只是分配一個頁目錄(Page Directory)就可以了。這一步的映射關系式虛擬空間到物理內存的映射關系。
2.讀取可執行文件頭,并且建立虛擬空間與可執行文件的映射關系
可執行文件與執行該可執行文件進程的虛擬空間的映射關系只是保存在操作系統內部的一個數據結構。windows中將進程虛擬空間中的一個段叫做虛擬段,在linux中叫虛擬內存區域(VMA)。操作系統創建進程后會在進程相應的數據結構中設置一個各個段的VMA。VMA是一個很重要的概念,它對于我們理解程序的執行很熱鬧操作系統如何管理進程虛擬空間有非常重要的幫助。操作系統在內部保存這種結構,很明顯是因為當程序執行發生頁錯誤時,它可以通過查找這樣的一個數據結構來定位錯誤頁在可執行文件中的位置。
3.將cpu指令寄存器設置成可執行文件入口,啟動運行。
上面的3個步驟執行完后,其他可執行文件的真正指令和數據都沒有被被裝入內存中。操作系統只是通過可執行文件的頭部信息建立起可執行文件和進程虛存之間的映射關系而已。假設程序的入口地址為0x08048000,即剛好是.text段的起始地址。當CPU開始打算執行這個地址的指令時,發現頁面0x08048000---0x08049000是一個空頁面,于是就認為這是一個頁錯誤(page fault)。CPU將控制權交給操作系統,操作系統有專門的頁錯誤處理機制例程來處理這種情況。這時候裝載過程的第二部建立的數據結構氣到了關鍵的作用,操作系統將查詢這個數據結構,然后找到空頁面所在的VMA,計算相應的頁面在可執行文件中的偏移,然后再物理內存中分配一個物理頁面,將進程中該虛擬頁與分配的物理頁之間建立映射關系,然后把控制權還給進程,進程從剛才頁錯誤的位置重新開始執行。