自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊一聊Linux虛擬內(nèi)存技術(shù)

云計算 虛擬化
以存儲單元為單位來管理顯然不現(xiàn)實,因此Linux把虛存空間分成若干個大小相等的存儲分區(qū),Linux把這樣的分區(qū)叫做 頁。為了換入、換出的方便,物理內(nèi)存也就按頁的大小分成若干個塊。由于物理內(nèi)存中的塊空間是用來容納虛存頁的容器,所以物理內(nèi)存中的塊叫做 頁框。頁與頁框是Linux實現(xiàn)虛擬內(nèi)存技術(shù)的基礎(chǔ)。

 以存儲單元為單位來管理顯然不現(xiàn)實,因此Linux把虛存空間分成若干個大小相等的存儲分區(qū),Linux把這樣的分區(qū)叫做 頁。為了換入、換出的方便,物理內(nèi)存也就按頁的大小分成若干個塊。由于物理內(nèi)存中的塊空間是用來容納虛存頁的容器,所以物理內(nèi)存中的塊叫做 頁框。頁與頁框是Linux實現(xiàn)虛擬內(nèi)存技術(shù)的基礎(chǔ)。

[[260030]]

虛擬內(nèi)存的頁、物理內(nèi)存的頁框及頁表

在Linux中,頁與頁框的大小一般為4KB。當(dāng)然,根據(jù)系統(tǒng)和應(yīng)用的不同,頁與頁框的大小也可有所變化。

物理內(nèi)存和虛擬內(nèi)存被分成了頁框與頁之后,其存儲單元原來的地址都被自然地分成了兩段,并且這兩段各自代表著不同的意義:高位段分別叫做頁框碼和頁碼,它們是識別頁框和頁的編碼;低位段分別叫做頁框偏移量和頁內(nèi)偏移量,它們是存儲單元在頁框和頁內(nèi)的地址編碼。下圖就是兩段虛擬內(nèi)存和物理內(nèi)存分頁之后的情況:

為了使系統(tǒng)可以正確的訪問虛存頁在對應(yīng)頁框中的映像,在把一個頁映射到某個頁框上的同時,就必須把頁碼和存放該頁映像的頁框碼填入一個叫做 頁表的表項中。這個頁表就是之前提到的映射記錄表。一個頁表的示意圖如下所示:

 

頁模式下,虛擬地址、物理地址轉(zhuǎn)換關(guān)系的示意圖如下所示:

也就是說:處理器遇到的地址都是虛擬地址。虛擬地址和物理地址都分成頁碼(頁框碼)和偏移值兩部分。在由虛擬地址轉(zhuǎn)化成物理地址的過程中,偏移值不變。而頁碼和頁框碼之間的映射就在一個映射記錄表——頁表中。

請頁與交換

虛存頁面到物理頁框的映射叫做頁面的 加載。

當(dāng)處理器試圖訪問一個虛存頁面時,首先到頁表中去查詢該頁是否已映射到物理頁框中,并記錄在頁表中。如果在,則MMU會把頁碼轉(zhuǎn)換成頁框碼,并加上虛擬地址提供的頁內(nèi)偏移量形成物理地址后去訪問物理內(nèi)存;如果不在,則意味著該虛存頁面還沒有被載入內(nèi)存,這時MMU就會通知操作系統(tǒng):發(fā)生了一個頁面訪問錯誤(頁面錯誤),接下來系統(tǒng)會啟動所謂的“請頁”機制,即調(diào)用相應(yīng)的系統(tǒng)操作函數(shù),判斷該虛擬地址是否為有效地址。

如果是 有效的地址,就從虛擬內(nèi)存中將該地址指向的頁面讀入到內(nèi)存中的一個空閑頁框中,并在頁表中添加上相對應(yīng)的表項,***處理器將從發(fā)生頁面錯誤的地方重新開始運行;如果是 無效的地址,則表明進(jìn)程在試圖訪問一個不存在的虛擬地址,此時操作系統(tǒng)將終止此次訪問。

當(dāng)然,也存在這樣的情況:在請頁成功之后,內(nèi)存中已沒有空閑物理頁框了。這是,系統(tǒng)必須啟動所謂地 交換機制,即調(diào)用相應(yīng)的內(nèi)核操作函數(shù),在物理頁框中尋找一個當(dāng)前不再使用或者近期可能不會用到的頁面所占據(jù)的頁框。找到后,就把其中的頁移出,以裝載新的頁面。對移出頁面根據(jù)兩種情況來處理:如果該頁未被修改過,則刪除它;如果該頁曾經(jīng)被修改過,則系統(tǒng)必須將該頁寫回輔存。

系統(tǒng)請頁的處理過程如下所示:

為了公平地選擇將要從系統(tǒng)中拋棄的頁面,Linux系統(tǒng)使用 最近最少使用(LRU)頁面的衰老算法。這種策略根據(jù)系統(tǒng)中每個頁面被訪問的頻率,為物理頁框中的頁面設(shè)置了一個叫做 年齡的屬性。頁面被訪問的次數(shù)越多,則頁面的年齡最小;相反,則越大。而年齡較大的頁面就是待換出頁面的***候選者。

快表

在系統(tǒng)每次訪問虛存頁時,都要在內(nèi)存的所有頁表中尋找該頁的頁框,這是一個很費時間的工作。但是,人們發(fā)現(xiàn),系統(tǒng)一旦訪問了某一個頁,那么系統(tǒng)就會在一段時間內(nèi)穩(wěn)定地工作在這個頁上。所以,為了提高訪問頁表的速度,系統(tǒng)還配備了一組正好能容納一個頁表的 硬件寄存器,這樣當(dāng)系統(tǒng)再訪問虛存時,就首先到這組硬件寄存器中去訪問,系統(tǒng)速度就快多了。這組存放當(dāng)前頁表的寄存器叫做 快表。

總之,使用虛擬存儲技術(shù)時,處理器必須配備一些硬件來承擔(dān)內(nèi)存管理的一部分任務(wù)。承擔(dān)內(nèi)存管理任務(wù)的硬件部分叫做存儲管理單元MMU。存儲管理單元MMU的工作過程如下圖所示:

頁的共享

在多程序系統(tǒng)中,常常有多個程序需要共享同一段代碼或數(shù)據(jù)的情況。在分頁管理的存儲器中,這個事情很好辦:讓多個程序共享同一個頁面即可。

具體的方法是:使這些相關(guān)程序的虛擬空間的頁面在頁表中指向內(nèi)存中的同一個頁框。這樣,當(dāng)程序運行并訪問這些相關(guān)頁面時,就都是對同一個頁框中的頁面進(jìn)行訪問,而該頁框中的頁就被這些程序所共享。下圖是3個程序共享一個頁面的例子:

頁的保護(hù)

由上可知,頁表實際上是由虛擬空間轉(zhuǎn)到物理空間的入口。因此,為了保護(hù)頁面內(nèi)容不被沒有該頁面訪問權(quán)限的程序所破壞,就應(yīng)在頁表的表項中設(shè)置一些訪問控制字段,用于指明對應(yīng)頁面中的內(nèi)容允許何種操作,從而禁止非法訪問。

下圖是頁表項中存放控制信息的一種可能的形式:

注意:其中的PCD位表示著是否允許高速緩存(cache)。

如果程序?qū)σ粋€頁試圖進(jìn)行一個該頁控制字段所不允許的操作,則會引起操作系統(tǒng)的一次中斷——非法訪問中斷,并拒絕這種操作,從而保護(hù)該頁的內(nèi)容不被破壞。

多級頁表

需要注意的是,頁表是操作系統(tǒng)創(chuàng)建的用于內(nèi)存管理的表格。因此,一個程序在運行時,其頁表也要存放到內(nèi)存空間。如果一個程序只需要一個頁表,則不會有什么問題。但如果,程序的虛擬空間很大的話,就會出現(xiàn)一個比較大的問題。

比如:一個程序的虛擬空間為4GB,頁表以4KB為一頁,那么這個程序空間就是1M頁。為了存儲這1M頁的頁指針,那么這個頁表的長度就相當(dāng)大了,對內(nèi)存的負(fù)擔(dān)也很大了。所以,***對頁表也進(jìn)行分頁存儲,在程序運行時只把需要的頁復(fù)制到內(nèi)存,而暫時不需要的頁就讓它留在輔存中。為了管理這些頁表頁,還要建立一個 記錄頁表頁首地址的頁目錄表,于是單級頁表就變成了二級頁表。二級頁表的地址轉(zhuǎn)換如下圖所示:

當(dāng)然,如果程序的虛擬空間更大,那么也可以用三級頁表來管理。為了具有通用性,Linux系統(tǒng)使用了三級頁表結(jié)構(gòu):頁目錄(Page Directory,PGD)、中間頁目錄(Page Middle Directory,PMD)、頁表(Page Table,PTE)。

Linux的頁表結(jié)構(gòu)

為了通用,Linux系統(tǒng)使用了三級頁表結(jié)構(gòu):頁目錄、中間頁目錄和頁表。PGD為 ***頁表,是一個pgdt數(shù)據(jù)類型的數(shù)組,每個數(shù)組元素指向一個中間頁目錄;PMD為 二級頁表,是一個pmdt數(shù)據(jù)結(jié)構(gòu)的數(shù)組,每個數(shù)組元素指向一個頁表;PTE則是 頁表,是一個pte_t數(shù)據(jù)類型的數(shù)組,每個元素中含有物理地址。

為了應(yīng)用上的靈活,Linux使用一系列的宏來掩蓋各種平臺的細(xì)節(jié)。用戶可以在配置文件 config中根據(jù)自己的需要對頁表進(jìn)行配置,以決定是使用三級頁表還是使用二級頁表。

在系統(tǒng)編譯時,會根據(jù)配置文件 config中的配置,把目錄 include/asm符號連接到具體CPU專用的文件目錄中。例如,對于i386CPU,該目錄符號會連接到include/asm-i386,并在文件pgable-2level-defs.h中定義了二級頁表的基本結(jié)構(gòu),如下圖:

其中還定義了:

  1. #define PGDIR_SHIFT  22 //PGD在線性地址中的起始地址為bit22 
  2. #define PTRS_PER_PGD  1024  //PGD共有1024個表項 
  3.                       
  4. #define PTRS_PER_PTE  1024  //PTE共有1024個表項 
  5. #endif 

在文件include/asm-i386/pgtable.h中定義了頁目錄和頁表項的數(shù)據(jù)結(jié)構(gòu),如下:

  1. typedof struct { unsigned long pte_low; }  pte_t ;                     //頁表中的物理地址,頁框碼 
  2. typedof struct { unsigned long pgd; }  pgd_t ;                         //指向一個頁表 
  3. typedof struct { unsigned long pgprot; }  pgprot_t ;                   //頁表中的各個狀態(tài)信息和訪問權(quán)限 

從定義可知,它們都是只有一個 長整型類型(32位)的結(jié)構(gòu)體。

注意:如上文的“頁的保護(hù)”部分,頁框碼代表物理地址,只需要高20位就夠了(因為頁框的長度為4KB,因此頁內(nèi)偏移12位)。而后12位可以存放各個狀態(tài)信息和訪問權(quán)限。但是Linux并沒有這樣做,反而重新定義了一個結(jié)構(gòu)體來存放,通過“或”運算來將兩者結(jié)合。

 

責(zé)任編輯:武曉燕 來源: 永不停歇的碼農(nóng)
相關(guān)推薦

2020-06-28 09:30:37

Linux內(nèi)存操作系統(tǒng)

2018-04-04 14:43:27

虛擬機保護(hù)技術(shù)

2018-11-29 09:13:47

CPU中斷控制器

2024-03-08 09:51:12

Linux網(wǎng)絡(luò)性能

2021-04-20 08:40:11

內(nèi)存管理Lwip

2022-05-12 23:19:15

Redis內(nèi)存碎片處理

2023-03-06 21:23:23

Redis數(shù)據(jù)庫

2019-02-13 14:15:59

Linux版本Fedora

2022-05-18 16:35:43

Redis內(nèi)存運維

2017-12-26 14:56:44

虛擬化基礎(chǔ)知識

2021-01-04 08:09:07

Linux內(nèi)核Watchdog

2021-04-28 08:35:52

區(qū)塊鏈技術(shù)開發(fā)

2020-11-06 07:10:21

5G定位

2021-01-28 22:31:33

分組密碼算法

2023-09-22 17:36:37

2020-05-22 08:16:07

PONGPONXG-PON

2018-06-07 13:17:12

契約測試單元測試API測試

2023-03-03 12:37:50

JavaJVM內(nèi)存溢出

2021-08-02 07:57:02

內(nèi)存Go語言

2021-08-04 09:32:05

Typescript 技巧Partial
點贊
收藏

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