Linux虚拟内存与线性地址翻译
1. 虛擬內存
對于操作系統的使用者而言,內存就像是一個一排排按照從0到n被編好數字的收納柜,每個柜子可以存放8個bit,也就是一個字節,我們將需要存放的信息切成若干個字節,放到連續的柜子中。以后我們只需要知道所使用的第一個柜子的編號,以及所用的柜子的數目,就可以完整的取出我們所保存的數據。
知道地址就可以找到我們要的數據,然后從內存讀到處理器就可以進行操作了,整個流程如下所示
但問題真的這么簡單嗎?當然不可能,假設以下情況
-
情景1:假如我調用一個軟件為進程A,在內存0x11111111處開始存了若干個字節的字符串,表示的是我學習資料的種子鏈接,還沒來得及寫回到硬盤中,這時我打開了另一個軟件,設為進程B,不小心對內存0x11111111出的信息進行了修改,最后當內存中信息寫回硬盤時,我發現我的的學習資料已經無了。
-
情景2:我的電腦只有4G內存,其中2G運行著系統內核,如果一個應用程序占用1G內存,那么我一次只能使用2個程序,如果我想一邊打開瀏覽器一邊寫代碼一邊聽音樂就無法做到了。
為了更好的使用內存,人們引用了虛擬內存,虛擬內存的作用可以總結為3點:
- 虛擬內存可以利用物理內存起到緩存的作用,提高進程訪問磁盤的速度,虛擬內存=物理內存+磁盤;
- 虛擬內存可以為進程提供獨立的內存空間,讓每個進程都感覺自己在獨享物理內存,簡化程序的鏈接、加載過程并通過動態庫共享內存;
- 虛擬內存保證了每個進程的地址空間與其他進程相隔離,保證了安全性;
實際上的過程是這樣的:
處理器CPU發出的虛擬地址通過MMU的翻譯生成PTEA(頁表項地址),通過頁表查找獲取物理地址PA,通過物理地址再到高速緩存或者內存中獲取數據;如果如果PTE的有效位是0,則表示該頁已失效,系統會觸發缺頁中斷,主存將從磁盤中讀取新頁,最終將數據返回。
2. MMU虛擬內存翻譯
以Intel i7core內存系統在為例
現在來介紹一些名詞
- 物理內存(physical memory),主存RAM,實際能使用的物理空間。
- 物理頁(physical page),把物理內存按照頁表的大小進行劃分,一般大小為4k,aka.頁框。
- 物理地址(physical address,PA), 物理內存劃分了根據物理頁劃分為很多塊,通過物理地址進行定位。
- 物理頁號(physical page number,PPN) ,定位緩存中的數據字。
- 物理頁號偏移 (physical page offset, PPO),定位緩存中的數據塊。
- 物理地址 PA = PPN + PPO。
- 虛擬內存(virtual memory),每個程序獨有,由多個虛擬頁(VP, virtual page)組成。
- 虛擬內存的地址編碼稱虛擬地址空間(virtual address space VAS),跟物理內存一樣,但虛擬內存是每個進程獨有的,其大小是根據操作系統的指令集位有關,如32位,64位,32位,每個進程就有4G,64位有個百億的GB。
- 虛擬頁(virtual page,VP ),把虛擬內存按照頁表的大小進行劃分,虛擬頁的數目=物理頁的數目+磁盤中頁的數目。
- 虛擬地址(virtual address),通俗說是計算機進程加載地址的指令,進程給的虛擬地址通過MMU進行獲取地址計算物理地址空間,然后獲取物理地址對應的數據傳送到CPU上。
- 虛擬頁號(virtual page number ,VPN) ,用于定位頁表的PTE(頁表項)。
- 虛擬頁號偏移(virtual page offset VPO) ,跟PPO值一樣。
- 虛擬地址 VA = VPN + VPO。
- 虛擬頁號VPN = TLBT + TLBI。
- TLB索引(TLB index,TLBI),在TLB中作為組索引。
- TLBT標記(TLB tag,TLBT),在TLB中作為行匹配。
- 緩存標記(cache tag,CT),在高速緩存中作為行匹配。
- 緩存索引(cache index,CI),在高速緩存中作為組索引。
- 緩存偏移(cache offset,CO),在高速緩存中用作行內偏移來選擇目的數據塊。
- 頁表(page tables,PT),虛擬地址與物理地址的對應表集合,存放在主存中。
- 頁表條目(page table entry,PTE),虛擬地址與物理地址具體對應記錄。頁表是由多個頁表條目PTE組成的數組,PTE 由一個有效位 和 n位地址字段組成,如果設置了有效位,那么地址字段就標識DRAM中相應的物理頁的起始位置。
其地址翻譯流程圖如下所示:
按照從快到慢、從正常到異常的順序分別介紹幾種可能的通路
首先通過虛擬地址VA獲取物理地址PA:
處理器產生一個48位的虛擬地址VA,由36位VPN和12位VPO組成
VPN低4位作為快表索引(TLBI),高32位作為標記(TLBT),在TLB(快表,高速緩存)中進行查找
(1)若TLB命中,則可獲得PPN,PPN + PPO(PPO == VPO) = PA,即可的到物理地址,跳轉至步驟4
(2)若TLB未命中,跳轉至步驟3
在多級頁表中查詢最終物理地址的PPN,每一級頁表項PTE = PPN + Flages + 保留部分。控制寄存器CR3 用于保存第一級頁表的物理地址,因此被稱為PTBR,獲取到一級頁表的物理地址后,據VPN1做偏移量查找到對應的頁表項,根據該頁表項中的PPN到物理內存中獲取下一級頁表首地址,再根據VPN2查找到對于的頁表項,獲取更下一級頁表的物理地址,直到第四級頁表,通過VPN4獲取第四級頁表中的PTE,從而得到最終物理地址的PPN,PA = PPN + PPO(PPO == VPO) ,進而得到物理地址,多級頁表結構如下:
然后通過物理地址PA獲取數據:
根據PA = CT + CI + CO,在L1高速緩存中查找對應數據
(1)若緩存命中,直接返回數據
(2)若緩存不命中,則跳轉至步驟5
根據PA從主存中獲取物理頁
(1)該物理頁有效,直接根據PPO偏移獲取數據返回
(2)該物理頁無效,跳轉至步驟6
當操作系統發現是一個缺頁中斷時,查找出來發生頁面中斷的虛擬頁(進程地址空間中的頁面)。這個虛擬頁的信息通常會保存在一個硬件寄存器中,如果沒有的話,操作系統必須檢索程序計數器,取出這條指令,用軟件分析該指令,通過分析找出發生頁面中斷的虛擬頁面。
(1)檢查虛擬地址的有效性及安全保護位。如果發生保護錯誤,則殺死該進程。
(2)操作系統查找一個空閑的物理頁,如果沒有空閑的物理頁則需要通過頁面置換算法找到一個需要換出的物理頁。
(3)如果找的物理頁中的內容被修改了,則需要將修改的內容保存到磁盤上,此時會引起一個寫磁盤調用,發生上下文切換(在等待磁盤寫的過程中讓其它進程運行)。(注:此時需要將物理頁置為忙狀態,以防物理頁被其它進程搶占掉)
(4)物理頁干凈后,操作系統根據虛擬地址對應磁盤上的位置,將保持在磁盤上的頁面內容復制到“干凈”的物理頁中,此時會引起一個讀磁盤調用,發生上下文切換。
(5)當磁盤中的頁面內容全部裝入物理頁后,向操作系統發送一個中斷。操作系統更新內存中的頁表項,將虛擬頁面映射的物理頁號PPN更新為寫入的物理頁,并將物理頁標記為正常狀態。
(6)恢復缺頁中斷發生前的狀態,將程序指令器重新指向引起缺頁中斷的指令。
(7)調度引起頁面中斷的進程,操作系統返回匯編代碼例程。
(8)匯編代碼例程恢復現場,將之前保存在通用寄存器中的信息恢復。
將虛擬地址重新映射到新的物理地址,獲取物理頁,根據PPO偏移獲取并返回數據。
3. 虛擬內存實際分配
在32位的機器上,地址空間從0x00000000~ 0xFFFFFFFF,總大小為4GB。一般而言,低地址空間,從0x00000000~ 0x7FFFFFFF使用戶空間,高地址空間被分配給系統。
內存管理
每個進程都擁有自己的4G(32位機)虛擬內存地址,各個進程之間是相互獨立的,每個進程的數據可由其中線程共享。虛擬內存地址本身不對應任何物理地址,直接引用會引發錯誤,虛擬內存地址必須映射物理地址后才能儲存數據。內存分配其實指的是虛擬內存地址映射物理內存,內存回收就是指解除映射關系。
一個進程的內存分配
一個進程的虛擬內存如下所示:
本文參考 :
《深入理解計算機系統》
缺頁中斷處理過程
總結
以上是生活随笔為你收集整理的Linux虚拟内存与线性地址翻译的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [二分查找] 二:二分查找的经典例题
- 下一篇: 机器人运动学_不同D-H矩阵的对比