成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux 保護(hù)模式下的內(nèi)存管理

系統(tǒng) Linux
每個(gè)任務(wù)會(huì)單獨(dú)的放在自己的虛擬地址空間中,再經(jīng)過硬件映射成為物理地址,不同的虛擬地址會(huì)變換成為不同的物理地址,不會(huì)存在 A 的虛擬地址會(huì)映射到 B 所在的物理地址的范圍內(nèi),這樣就會(huì)把所有的任務(wù)都隔絕開,且不同任務(wù)之間不會(huì)相互干擾。

我們知道,內(nèi)存可以看做一個(gè)非常大的數(shù)組,我們想要查找內(nèi)存中某個(gè)元素的話,會(huì)通過數(shù)組的下標(biāo)來指定,內(nèi)存也是如此,不過這有一個(gè)前提是這個(gè)數(shù)組是由一組有序的字節(jié)組成的,在這個(gè)有序的字節(jié)數(shù)組中,每個(gè)字節(jié)都有一個(gè)唯一的地址,這個(gè)地址也叫做內(nèi)存地址。

內(nèi)存中存儲(chǔ)著很多對(duì)象,每個(gè)對(duì)象是由不同字節(jié)組成的,比如一個(gè) char 對(duì)象,一個(gè) byte 對(duì)象,一個(gè) int 對(duì)象等等,它們都分部在內(nèi)存的各個(gè)位置中,CPU 對(duì)內(nèi)存中這些對(duì)象的地址進(jìn)行定位的操作就叫做內(nèi)存尋址。內(nèi)存從 0 地址處開始編址,總共能查找到多少位的內(nèi)存地址呢?答:是根據(jù)總線寬度來定位的。由于 80X86 是 32 位的,所以總線寬度也是 32 位,因此一共有 2 ^ 32 個(gè)內(nèi)存地址,所以總共可以存放 4GB 的內(nèi)存地址。由于內(nèi)存地址是連續(xù)的,于是可以連續(xù)的取出多個(gè)字節(jié)的數(shù)據(jù)類型,例如 int、long、double。

雖然能夠?qū)ぶ返綄?duì)象,但是這些對(duì)象存放的字節(jié)順序是不同的,這里分為兩種存放方式,即大端法和小端法。

比如現(xiàn)在有一個(gè) int 類型的對(duì)象,位于地址 0x100 處,它的十六進(jìn)制數(shù)值是 0x01234567,我給你畫一幅圖你就明白這兩個(gè)存放順序的區(qū)別了。

這個(gè)其實(shí)很好理解,0x01234567 的 int 數(shù)據(jù)類型可以拆分為 01 23 45 67 個(gè)字節(jié),并且 01 是高位,67 是低位,于是可以解釋小端法和大端法的存儲(chǔ)順序:即小端法是低位在前,而大端法是高位在前。大端法和小端法只是存儲(chǔ)順序的區(qū)別,和對(duì)象的位數(shù)、數(shù)值無關(guān)。大多數(shù) Intel 機(jī)器都采用的是小端模式,所以 80X86 也是小端存儲(chǔ),而一些 IBM 和 Oracle 的大多數(shù)機(jī)器都是使用的大端存儲(chǔ)方式。

由于計(jì)算機(jī)是無法直接將內(nèi)存中的數(shù)據(jù)一次性全部尋址完畢,因?yàn)樗鄬?duì)實(shí)在太過龐大,所以內(nèi)存一般會(huì)進(jìn)行分段,這里就涉及一個(gè)疑問:即內(nèi)存為什么要分段。我上面只是籠統(tǒng)的介紹了下。

內(nèi)存為什么要分段?

https://t.zsxq.com/0cweMndpM

分段機(jī)制把內(nèi)存空間分成一個(gè)或多個(gè)段的線性區(qū)域,這部分線性區(qū)域可以使用段基址 + 段內(nèi)偏移來確定。段基址部分由 16 位的段選擇符來指定,其中 14 位是可以選擇 2 ^ 14 次方即 16384 個(gè)段,段內(nèi)偏移地址部分使用 32 位的值來指定,因此段內(nèi)地址可以是 0 - 4G ,一個(gè)段的最大長度是 4 GB,這也就和上面所說的 4 GB 的內(nèi)存地址相呼應(yīng)。由 16 位段和 32 位段內(nèi)偏移構(gòu)成的 48 位地址或長指針稱為一個(gè)邏輯地址,邏輯地址就是虛擬地址。

X86 有幾個(gè)專門存放段基址的寄存器:CS、DS、ES、SS、FS 和 GS。其中 CS 用于尋址代碼段,SS 用于尋址堆棧段,其他寄存器用于尋址數(shù)據(jù)段。在任何指定時(shí)刻由 CS 尋址的段稱為當(dāng)前代碼段。此時(shí) EIP 寄存器中就包含了當(dāng)前代碼段內(nèi)下一條需要執(zhí)行指令的偏移地址。此時(shí)的段基址:偏移地址就可以表示為 CS:EIP 了。

由段寄存器 SS 尋址的段稱為當(dāng)前堆棧段,棧頂由 ESP 寄存器給出,在任何時(shí)刻 SS:ESP 都指向棧頂,并且沒有例外情況,其他四個(gè)是通用數(shù)據(jù)段寄存器,當(dāng)指令中默認(rèn)沒有數(shù)據(jù)段時(shí),由 DS 給出。

地址轉(zhuǎn)換

一個(gè)完整的內(nèi)存管理系統(tǒng)一般都會(huì)包含兩部分:訪問保護(hù)和地址轉(zhuǎn)換。訪問保護(hù)是為了防止一個(gè)應(yīng)用程序訪問的內(nèi)存地址是另一塊程序所使用的;地址轉(zhuǎn)換就是給不同的應(yīng)用程序提供一個(gè)動(dòng)態(tài)的地址分配方式。訪問保護(hù)和地址轉(zhuǎn)換是相輔相成的。

地址轉(zhuǎn)換通常以內(nèi)存塊作為基本單位,這里解釋下什么是塊,大家知道在 Linux 中,一切都是文件,而文件就是由一個(gè)個(gè)的塊構(gòu)成的,塊(block)是用于描述文件系統(tǒng)的組成單位,也是數(shù)據(jù)處理的基本單位。雖說塊是基本單位,但是其本質(zhì)也是由一個(gè)個(gè)扇區(qū)構(gòu)成的,常見的塊有 512B、1KB、4KB 等。

地址轉(zhuǎn)換有兩種實(shí)現(xiàn)方式:分段機(jī)制和分頁機(jī)制。x86 在內(nèi)存管理的實(shí)現(xiàn)方式結(jié)合了分段和分頁機(jī)制,下面是虛擬地址經(jīng)過分段和分頁后轉(zhuǎn)換為物理地址的映射圖

針對(duì)這張圖,有必要解釋一下:

首先,這張圖包含三個(gè)地址和這三個(gè)地址的轉(zhuǎn)換過程,從大體上來看,邏輯地址會(huì)經(jīng)過分段基址轉(zhuǎn)換后變?yōu)榫€性地址,線性地址是保護(hù)模式下的段基址 + 段內(nèi)偏移,因此這張圖是保護(hù)模式下的地址轉(zhuǎn)換圖。線性地址會(huì)經(jīng)過分頁機(jī)制后轉(zhuǎn)換為物理地址,前提是需要開啟分頁機(jī)制;如果沒有開啟分頁機(jī)制,線性地址 = 物理地址。

需要再說一下邏輯地址,邏輯地址里面包含段選擇子和段內(nèi)偏移,段選擇子這個(gè)概念我剛開始接觸也比較模糊,簡單一點(diǎn)來說可以把它理解為是保護(hù)模式下的段基址,大家知道段基址是 16 位的,而段內(nèi)偏移是 32 位的。

很多書或者文章中都提到了段選擇符,其實(shí)段選擇子就是段選擇符,這完全是翻譯問題,英文都是 selector。

后面會(huì)提到段描述符,段描述符和段選擇子不是一回事,但段選擇子是一個(gè) 16 位的段描述符。

再和大家說一下這個(gè)圖上沒有寫出來的內(nèi)容,現(xiàn)在大家知道邏輯地址可以轉(zhuǎn)換為線性地址,線性地址可以轉(zhuǎn)換為物理地址,那么根源是如何轉(zhuǎn)換的呢?實(shí)際上這里使用的方式是 MMU(內(nèi)存管理單元)進(jìn)行轉(zhuǎn)換;而線性地址轉(zhuǎn)換為物理地址使用的是分頁單元的硬件電路。具體的轉(zhuǎn)換過程不是此篇文章討論的重點(diǎn),我們把重點(diǎn)還是放在分段和分頁這兩個(gè)機(jī)制上。

下面來詳細(xì)聊一聊分段和分頁這兩個(gè)機(jī)制。

分段機(jī)制

這里推薦大家先看一下我寫的 "內(nèi)存為什么要分段" 的那段描述。

https://t.zsxq.com/0cweMndpM

分段提供了隔絕代碼、數(shù)據(jù)和堆棧區(qū)域的機(jī)制,這才使得多個(gè)程序能夠運(yùn)行在同一個(gè)內(nèi)存空間中不會(huì)相互干擾。如果 CPU 中有多個(gè)程序或者任務(wù)正在運(yùn)行,那么每個(gè)程序都可以分配各自的一套段(包含程序代碼、數(shù)據(jù)和堆棧),CPU 通過加強(qiáng)段之間的界限來達(dá)到防止應(yīng)用程序相互干擾的目的。

一個(gè)系統(tǒng)中所有使用的段都包含在 CPU 的線性地址空間中。為了定位指定段中的字節(jié),程序必須提供邏輯地址才能進(jìn)行轉(zhuǎn)換。邏輯地址包含段選擇子和段內(nèi)偏移,每個(gè)段都有一個(gè)段描述符,段描述符用于指出段的大小、訪問權(quán)限和段的特權(quán)級(jí)、段類型以及段第一個(gè)字節(jié)在線性地址空間中的位置(段基址)。邏輯地址的偏移量部分加到段基址上就可以定位段中某個(gè)字節(jié)的位置,因此段基址 + 偏移量形成了 CPU 線性地址空間中的地址。

線性地址空間與物理地址空間具有相同的結(jié)構(gòu),但是它們所能容納的段相差甚遠(yuǎn),虛擬地址也就是邏輯地址空間可包含最多 16 K 的段,而每個(gè)段可容納的大小為 4 GB ,所以虛擬地址總共能查找到 64TB(2 ^ 46) 的段,線性地址和物理地址的空間是 4GB (2 ^ 32)。所以,如果禁用了分頁機(jī)制,那么線性地址空間就是物理地址空間。

這幅圖就是邏輯地址 -> 線性地址 -> 物理地址的映射圖,GDT 表和 LDT 表各占一半的地址空間,各為 8192 個(gè)段,每個(gè)段最長為 4 G,從 GDT 表還是 LDT 表查詢,具體從哪個(gè)表查還是要看段選擇子的 TI 屬性,段選擇子的結(jié)構(gòu)如下所示

段選擇子總共分為三個(gè)部分:

  • RPL(Request Privilege Level):請(qǐng)求特權(quán)級(jí),表示進(jìn)程應(yīng)該以什么權(quán)限來訪問段,數(shù)值越大權(quán)限越小。
  • TI(Table Indicator):表示應(yīng)該查詢哪個(gè)表,TI = 0 查 GDT 表;TI = 1 查 LDT 表。
  • Index:CPU 會(huì)自動(dòng)將 Index * 8,在加上 GDT 和 LDT 中的段基址,就是要加載的段描述符。

這里沒有太細(xì)致的詳解一下段描述符,因?yàn)榇似€是偏向于內(nèi)存管理,沒有太執(zhí)著于某個(gè)細(xì)節(jié)。

邏輯地址由兩部分組成,段選擇子和偏移量,段選擇字可以合成段描述符,然后它們會(huì)直接保存在 GDTR 中。段選擇子和段內(nèi)偏移經(jīng)過 MMU 后可以轉(zhuǎn)換成為線性地址。

分頁機(jī)制

上面我們說到,線性地址是由邏輯地址轉(zhuǎn)換過來的,如果禁用了分頁機(jī)制,線性地址就是物理地址,如果開啟分頁機(jī)制,線性地址和邏輯地址空間的數(shù)量還是不同的。一般程序都是多任務(wù)的,而多任務(wù)通常定義的線性地址空間要比物理內(nèi)存容量大得多,為什么呢?地址轉(zhuǎn)換映射圖上畫著明明線性地址和物理地址都是 4G 的大小啊。那是因?yàn)椋€性地址被虛擬存儲(chǔ)技術(shù)所虛擬化了。

虛擬存儲(chǔ)是一種內(nèi)存管理技術(shù),使用這項(xiàng)技術(shù)可以讓我們產(chǎn)生內(nèi)存空間要比實(shí)際的物理內(nèi)存容量大的多的錯(cuò)覺,其本質(zhì)是把內(nèi)存虛擬化了,就是說內(nèi)存可能只有 4G,但是你以為內(nèi)存有 64 G,所以我為什么能開那么多應(yīng)用程序的原因。

分頁機(jī)制其實(shí)就是虛擬化的一種實(shí)現(xiàn),在虛擬化的環(huán)境中,大量的線性地址空間會(huì)映射到一小塊物理內(nèi)存(RAM 或者 ROM)中。當(dāng)使用分頁時(shí),每個(gè)段被劃分成頁面(一般為 4K),這個(gè)頁面會(huì)存儲(chǔ)在物理內(nèi)存或硬盤上。操作系統(tǒng)通過使用一個(gè)頁目錄和頁表來維護(hù)這些頁面。當(dāng)程序試圖訪問線性地址空間中的某一個(gè)地址位置時(shí),CPU 就會(huì)使用頁目錄和頁表把這個(gè)線性地址轉(zhuǎn)換成物理地址,再存儲(chǔ)在物理內(nèi)存上。

如果當(dāng)前訪問的頁面不在物理內(nèi)存中,CPU 就會(huì)執(zhí)行中斷,一般錯(cuò)誤就是頁面異常,然后操作系統(tǒng)會(huì)把這個(gè)頁面從硬盤上讀入物理內(nèi)存中,然后繼續(xù)從中斷處執(zhí)行程序。操作系統(tǒng)經(jīng)常會(huì)進(jìn)行頻繁的頁面換入換出操作,這也是一個(gè)性能瓶頸所在。

分段中的每個(gè)段長度是不固定的,最大位 4G,而分頁中的每個(gè)頁面大小是固定的。不論在物理內(nèi)存還是磁盤上,使用固定大小的頁面更適合管理物理內(nèi)存;而分段機(jī)制使用大小可變的塊更適合處理復(fù)雜系統(tǒng)的邏輯分區(qū)。

雖然分段和分頁是兩種不同的地址轉(zhuǎn)換機(jī)制,但是它們對(duì)整個(gè)地址變換是獨(dú)立處理的,每個(gè)過程都是獨(dú)立的。這兩種機(jī)制都使用了一種中間表來存儲(chǔ)表項(xiàng)映射,但是這個(gè)中間表的結(jié)構(gòu)是不同的。段表存在線性地址空間中,頁表則存儲(chǔ)在物理地址空間。

保護(hù)機(jī)制

80x86 包含兩種保護(hù)機(jī)制,第一種是為每個(gè)任務(wù)分配不同的虛擬地址空間來完全隔離各個(gè)任務(wù)。這是通過給每個(gè)任務(wù)邏輯地址到物理地址的不同變換得到的,每個(gè)應(yīng)用程序只能訪問自己虛擬空間內(nèi)的數(shù)據(jù)和指令,只能通過它自己的映射得到物理地址;第二種機(jī)制是保護(hù)任務(wù),保護(hù)操作系統(tǒng)的內(nèi)存段和一些特殊寄存器不會(huì)被應(yīng)用程序所訪問。下面我們就來具體探討一下這兩個(gè)任務(wù)。

任務(wù)之間的保護(hù)

每個(gè)任務(wù)會(huì)單獨(dú)的放在自己的虛擬地址空間中,再經(jīng)過硬件映射成為物理地址,不同的虛擬地址會(huì)變換成為不同的物理地址,不會(huì)存在 A 的虛擬地址會(huì)映射到 B 所在的物理地址的范圍內(nèi),這樣就會(huì)把所有的任務(wù)都隔絕開,且不同任務(wù)之間不會(huì)相互干擾。

每個(gè)任務(wù)都有各自的映射表、段表和頁表,當(dāng) CPU 切換不同的應(yīng)用程序或任務(wù)時(shí),這些表也會(huì)進(jìn)行切換。

虛擬地址是操作系統(tǒng)的抽象,也就是說虛擬地址完全是操作系統(tǒng)所抽象出來能夠更好管理應(yīng)用程序和任務(wù)的一個(gè)載體,每個(gè)任務(wù)都可以把邏輯地址映射成為虛擬地址,這也表明每個(gè)任務(wù)都可以訪問操作系統(tǒng),操作系統(tǒng)可以被所有的任務(wù)所共享。這個(gè)所有任務(wù)都具有相同虛擬地址空間的部分被稱為全局地址空間(Global address space),Linux 就使用到了全局地址空間。

全局地址空間中每個(gè)任務(wù)都有自己的唯一的虛擬地址空間,這個(gè)虛擬地址空間叫做局部地址空間(Local address space)。

內(nèi)存段和寄存器的特殊保護(hù)

如果說操作系統(tǒng)在不同任務(wù)之間的保護(hù)是橫向的話,那么對(duì)內(nèi)存段和寄存器的等級(jí)保護(hù)就是縱向的。操作系統(tǒng)定義了 4 個(gè)特權(quán)級(jí)來對(duì)每個(gè)任務(wù)提供保護(hù),來限制對(duì)任務(wù)中各段的訪問。

優(yōu)先級(jí)分為 4 個(gè)等級(jí),0 最高,3 最低。一般最敏感的數(shù)據(jù)會(huì)被賦予最高優(yōu)先級(jí),它們只能被任務(wù)中最受信任的部分訪問,不太敏感的數(shù)據(jù)會(huì)賦予低優(yōu)先級(jí);內(nèi)核操作系統(tǒng)訪問一般是 0 級(jí),應(yīng)用程序數(shù)據(jù)一般是 3 級(jí)。每個(gè)內(nèi)存段都與一個(gè)特權(quán)級(jí)相關(guān)聯(lián)。

我們知道 CPU 通過 CS 從段中取得指令和數(shù)據(jù)執(zhí)行,從段中取得的指令和數(shù)據(jù)是具有特權(quán)級(jí)的,一般用當(dāng)前特權(quán)級(jí)(Current Privilege Level)來訪問,CPL 就是當(dāng)前活動(dòng)代碼的特權(quán)級(jí)。每當(dāng)有應(yīng)用程序試圖訪問段時(shí),就會(huì)與這個(gè)特權(quán)級(jí)進(jìn)行比較,只有比段的特權(quán)級(jí)低才能夠訪問。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2022-06-13 08:18:02

操作系統(tǒng)CPU保護(hù)模式

2022-07-28 09:44:04

內(nèi)存實(shí)模式保護(hù)模式

2011-09-06 09:47:21

WindowsVistIE7保護(hù)模式

2012-01-12 12:15:14

2009-02-19 16:57:51

IE8新特性保護(hù)模式

2021-08-30 06:59:07

x86處理器內(nèi)存

2013-11-13 16:02:41

IE11瀏覽器微軟

2025-03-26 00:00:05

2017-05-02 21:49:31

零丟失保護(hù)模式選擇

2022-08-08 08:31:00

Linux內(nèi)存管理

2013-10-11 17:32:18

Linux運(yùn)維內(nèi)存管理

2013-11-13 11:36:08

微軟補(bǔ)丁IE11

2010-05-20 10:06:47

云計(jì)算數(shù)據(jù)保護(hù)第三方

2021-03-04 20:11:09

Linux內(nèi)存編程

2014-08-01 15:38:37

Linux進(jìn)程管理

2021-05-27 05:28:18

Linux 內(nèi)存管理

2009-12-25 15:24:16

內(nèi)存管理

2020-07-28 08:10:33

Linux內(nèi)存虛擬

2021-03-17 21:34:44

Linux內(nèi)存管理

2023-10-10 20:46:00

谷歌YouTube
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 成人午夜在线视频 | 久久精品亚洲精品 | 欧美一区 | 国产你懂的在线观看 | 国产一区二区三区精品久久久 | 欧美精品一区二区三区一线天视频 | 久久国产精品一区二区 | 成人久久网 | 毛片黄片| 亚洲精品一区二区三区丝袜 | 国产三区精品 | av资源中文在线 | 久久99视频这里只有精品 | 91精品国产综合久久国产大片 | 国产精品毛片久久久久久久 | 资源首页二三区 | 亚洲精品久久久久久一区二区 | 日韩在线一区二区三区 | 亚洲性在线 | 欧美日韩在线一区二区 | 毛片日韩| 国产欧美日韩在线观看 | 羞羞视频在线观免费观看 | 艹逼网 | 精品久久久久久亚洲综合网站 | 日韩视频一区 | 欧美在线一区二区三区 | 91在线观看 | 日韩福利在线 | 91在线精品一区二区 | 国产精品中文字幕在线观看 | 91亚洲精品国偷拍自产在线观看 | 国产精品久久久久久久久久久久 | 免费观看羞羞视频网站 | 国产美女精品 | 久久久久成人精品 | 亚洲一区中文字幕 | 成年人在线观看视频 | 久久婷婷av | 欧美专区日韩专区 | 国产99久久久久 |