文章出處

今天在思考一個可能由page table引發的Linux操作系統內存報警問題時發現基礎知識缺失的太多,因此找了幾本操作系統相關的書復習了一下,在這里記下來。

首先上一幅32位尋址空間的虛擬地址結構圖:(僅適用于一級頁表,頁面大小為4KB)

前12位表示頁內偏移量,后20位表示頁號,可尋址2^20=1M個頁,假如頁面大小為4KB,那么就能尋址4GB的虛擬地址。

那么這樣一個32位的虛擬地址是如何轉換為物理地址的呢?

下圖說明了一切:

圖1.分頁系統的地址變換機構 --摘自《計算機操作系統》湯小丹版

尋址步驟解析:

1.首先假設虛擬地址為A,頁面大小為L,則可以通過以下公式迅速計算出相應的頁號P和頁內偏移量d:

P=INT [A/L] --除法取整
d=A%L  --求余

2.得到P和d之后,使用P與頁表寄存器中的寄存的頁表始址(一個物理地址),進行邏輯運算得到頁表項的具體位置。(其實就是通過頁表始址找到頁表頁,再在里邊找到頁號)

3.在此頁表項中取到后半截的塊號--通過塊號得到塊的物理始址,通過這個物理始址與頁內偏移量相加得到真正的物理地址。

整個過程很簡單,就兩個加法,兩次尋址。

舉例說明:

一個頁表的結構如下所示:(這里省了標識頁表的始址,直接給了頁表的內容)

頁號    塊號
0        3
1        2
2        0
3        1

 

假設有一個虛擬地址0x000B,頁面大小為4KB(0x1000),那么:

1.P=0x000B/0x1000=0; d=0x000B%0x1000=0x000B;因此頁號為0,頁內偏移量為0x000B

2.通過與寄存器的邏輯運算找到如上頁面的0頁號,發現0號對應物理塊號是3

3.3*0x1000+0x000B=0x300B

因此真實的物理地址就是0x300B。

拓展知識:

由于頁表空間必須是連續的內存地址,這樣的開銷在32位分頁系統中幾乎是不可接受的,因此我們一般采用如下兩種辦法解決此問題:

1.多級頁表,即頁表的頁表,這樣頁表可以離散的分布于內存之中,不必是連續內存,64位尋址空間的分頁系統常見3級頁表,32位的常見兩級頁表。

2.只緩存一部分的頁表,其他頁表部分在外存中,根據需要調入,這樣解決了頁表空間占用的問題;對于多級頁表,其外部頁表必須調入內存,頁表則可以只緩存一部分。

現在常見的64位操作系統一般采用多級頁表的方式,大多數為3級頁表,其實就是頁表3級索引,因此CPU多出了2個頁表寄存器來記錄多級頁表的物理始址,但是本質與一級頁表尋址方式類似。

自2.6.11內核版本以來,Linux采用4級頁表的分頁方式(9+9+9+12)。

在64位分頁系統中,由于可尋址范圍已經大大擴展,因此所有的頁目錄和頁表都已被存入內存。

對于用戶空間和內核空間,以及高端內存、低端內存還有線性映射、非線性映射等概念,在64位分頁系統中應當全部舍棄,除非你是研究內核的。

最后再放一個段頁式邏輯地址-->線性地址(虛擬地址)-->物理地址的轉換圖:

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()