偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

從虛擬內(nèi)存看可執(zhí)行文件的裝載

云計(jì)算 虛擬化
當(dāng)雙擊打開一個(gè)可執(zhí)行文件的時(shí)候,計(jì)算機(jī)究竟干了什么?磁盤上的可執(zhí)行文件是怎么裝載到內(nèi)存當(dāng)中去的?對(duì)于眾多程序猿來說,這也仍然是一個(gè)不太容易回答的問題。

[[373936]]

本文轉(zhuǎn)載自微信公眾號(hào)「Linux澡堂子」,作者冷面不冷 。轉(zhuǎn)載本文請(qǐng)聯(lián)系Linux澡堂子公眾號(hào)。  

當(dāng)雙擊打開一個(gè)可執(zhí)行文件的時(shí)候,計(jì)算機(jī)究竟干了什么?磁盤上的可執(zhí)行文件是怎么裝載到內(nèi)存當(dāng)中去的?對(duì)于眾多程序猿來說,這也仍然是一個(gè)不太容易回答的問題。

這次讓我們從虛擬內(nèi)存的角度來看看可執(zhí)行文件的裝載過程,仔細(xì)分析從可執(zhí)行文件開始裝載到第一條指令執(zhí)行時(shí)發(fā)生了什么。

本文不再詳細(xì)解釋進(jìn)程的概念、ELF文件結(jié)構(gòu)、虛擬內(nèi)存的定義、分頁的概念、請(qǐng)求分頁的工作原理,之前的文章講過,感興趣的小伙伴自行搜索。

裝載大體上可以分為以下幾步:

  1. 創(chuàng)建進(jìn)程
  2. 創(chuàng)建虛擬地址空間
  3. 讀取可執(zhí)行文件頭,建立虛擬地址空間與可執(zhí)行文件的映射關(guān)系
  4. 設(shè)置CPU指令寄存器為可執(zhí)行文件入口地址
  5. 執(zhí)行,觸發(fā)缺頁中斷

創(chuàng)建進(jìn)程

創(chuàng)建進(jìn)程不必多說了,此時(shí)會(huì)創(chuàng)建如進(jìn)程標(biāo)識(shí)符、進(jìn)程優(yōu)先級(jí)之類的信息。注意此時(shí)還不涉及到可執(zhí)行文件。

創(chuàng)建虛擬地址空間

這一步其實(shí)應(yīng)該算在創(chuàng)建進(jìn)程里面,實(shí)際就是創(chuàng)建頁表(多級(jí)頁表),用來與物理內(nèi)存建立連接,此時(shí)這個(gè)頁表是空的。此時(shí)仍然不涉及到可執(zhí)行文件。

讀取可執(zhí)行文件頭

這個(gè)就是關(guān)鍵的一步了。進(jìn)程開始讀取可執(zhí)行文件頭,即ELF文件的頭部,此時(shí)進(jìn)程也僅僅讀取ELF文件頭部,不涉及到其他段。ELF文件頭中含有可執(zhí)行文件各段的起始地址和長度等信息,以及可執(zhí)行文件入口地址,注意這里"地址"即虛擬內(nèi)存地址。

這里需要強(qiáng)調(diào)的是:整個(gè)裝載過程也僅僅是讀取了ELF頭部,僅此而已。因?yàn)镋LF頭部記錄了整個(gè)可執(zhí)行文件的節(jié)奏,所以根據(jù)ELF頭部即可建立整個(gè)可執(zhí)行文件的框架。因此,這一步是在建立與磁盤的連接。舉個(gè)簡(jiǎn)單的例子,當(dāng)發(fā)生缺頁中斷時(shí),操作系統(tǒng)該去哪把缺的頁加載到物理內(nèi)存?這就是這一步的關(guān)鍵之處了。將虛擬內(nèi)存地址與磁盤地址建立聯(lián)系,當(dāng)缺頁時(shí)即可尋找到對(duì)應(yīng)的磁盤地址,從而加載到物理內(nèi)存。

還需要強(qiáng)調(diào)的一點(diǎn)是,此時(shí)在進(jìn)程中,實(shí)際相當(dāng)于是僅僅保存了一個(gè)函數(shù)映射關(guān)系。如下圖有更直觀的理解。

請(qǐng)記住這個(gè)圖,后續(xù)我們講到內(nèi)存管理的時(shí)候再把進(jìn)程和內(nèi)存結(jié)合起來看,到時(shí)候你就會(huì)站在上帝視角對(duì)內(nèi)核有了指點(diǎn)江山的感覺。

設(shè)置CPU指令寄存器

如上兩步建立了虛擬地址空間和物理內(nèi)存、磁盤的映射關(guān)系,現(xiàn)在就要準(zhǔn)備運(yùn)行此程序了。運(yùn)行的第一條指令地址在哪?在ELF頭部中。將CPU指令寄存器的值設(shè)置為第一條指令地址即可。

執(zhí)行,觸發(fā)缺頁中斷

想想CPU在從入口地址取指令時(shí)會(huì)發(fā)生什么。假設(shè)入口地址指向.text段首,如圖所示為0x8049000;CPU以此虛擬地址查找頁表發(fā)現(xiàn)該頁尚未裝載,觸發(fā)缺頁中斷。此時(shí)操作系統(tǒng)接管,從之前建立的虛擬地址空間與磁盤的映射關(guān)系中找到此頁在磁盤中的地址;再從此地址讀取頁,加載到物理內(nèi)存,缺頁中斷完畢。CPU重新從入口地址取指令,此時(shí)由頁表得到物理地址,從內(nèi)存中得到對(duì)應(yīng)的指令,交給CPU。

隨著進(jìn)程的執(zhí)行,缺頁中斷不斷出現(xiàn),磁盤中的可執(zhí)行文件也逐漸加載到內(nèi)存中。

總結(jié)

如上便是簡(jiǎn)單的可執(zhí)行文件的裝載過程,最需要強(qiáng)調(diào)的一點(diǎn)是,可執(zhí)行文件的數(shù)據(jù)是 按需 加載到物理內(nèi)存的,缺頁中斷驅(qū)動(dòng)著進(jìn)程的執(zhí)行。

 

責(zé)任編輯:武曉燕 來源: Linux澡堂子
相關(guān)推薦

2017-02-07 10:22:53

2023-03-31 23:31:06

.go文本文件

2015-02-02 11:03:12

2012-01-05 10:37:40

Java

2010-02-22 18:04:27

CentOS mpla

2011-08-09 10:24:19

可執(zhí)行文件病毒病毒

2021-01-12 10:10:41

shell腳本Linux命令

2022-05-11 14:50:34

Python解包執(zhí)行文件

2021-01-08 08:06:19

腳本Shell文件

2009-06-20 09:21:37

UNIXLINUX

2024-05-06 00:00:00

Go文件瘦身代碼

2024-08-12 16:42:50

二進(jìn)制工具系統(tǒng)

2009-04-16 10:37:17

Javaexejar

2024-05-21 12:01:39

.NET 6開發(fā)

2023-09-04 07:14:36

2022-03-07 07:57:04

Linux工具內(nèi)存

2023-12-18 09:21:22

開發(fā)靜態(tài)編譯Linux

2023-12-25 16:10:34

Linuxdconfig命令

2022-05-20 08:55:02

py文件exepython

2021-01-14 22:17:09

PythonLinux工具
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)