//接前一篇部落格:
本節主要介紹硬體中分頁機制。
為了效率,線性位址被分成以固定長度為機關的組,稱為頁(page),頁内部連續的線性位址被映射到連續的實體位址中。
分頁單元把所有的記憶體分成固定長度的頁框(page frame)。每個頁框包含一個頁(page),也就是說一個頁框的長度與一個頁的長度一緻。頁框是主存的一部分,是以是一個存儲區域。頁和頁框是不同的,也隻是一個資料塊,可以存放在任何頁框或磁盤中。
從80386起,intel處理器的分頁單元處理4kb的頁。
32位線性位址被分成3個域:
*directory(目錄):最高10位
*table(頁表):中間10位
*offset(偏移量):最低12位
線性位址的轉換分兩步完成:
*頁目錄表轉換;
*頁表轉換。
使用二級模式的目的在于減少每個程序頁表所需記憶體的數量。
控制寄存器cr3中存放正在使用的頁目錄的實體位址。線性位址内的directory字段決定頁目錄中的目錄項,而目錄項指向适當的頁表。位址的table字段依次又決定頁表中的表項,而頁表含有頁所在頁框的實體位址。offset字段決定頁框内的相對位置。由于offset字段是12位長,故每一頁含有4096b的資料。
頁目錄項和頁表項具有相同的結構,每項包含下面的字段:
*present标志:
置1,所指頁或頁表在主存中;為0,不在主存中。如果當通路一個位址時,頁目錄項或頁表項的present标志為0,則分頁單元将該線性位址存放在寄存器cr2中,産生14号異常:缺頁異常。
*field 标志:
20位,頁目錄項中的field指向包含一個頁表的頁框。頁表項中的field指向包含一頁資料的頁框。
*pcd/pwt 标志:控制硬體高速緩存處理頁或頁表的方式。
*accessed 标志:每當分頁單元對相應頁框進行尋址時,設定這個标志。分頁單元從來不重置這個标志,而是必須由作業系統去做。
*dirty 标志:隻應用于頁表項中,每當對一個頁框寫操作時就設定。分頁單元從來不重置這個标志,而是必須由作業系統去做。
*read/write:頁或頁表的存取權限。與段的3種存取權限(讀、寫、執行)不同的是,頁的存取權限隻有兩種(讀、寫)。如果read/write标志為0,說明相應的頁表或頁是隻讀的,否則是可讀寫的。
*user/supervisor:通路頁或頁表所需的特權級。若此标志為0,隻有當cpl小于3(linux:cpu處于核心态)時才能對頁尋址,否則總能對頁尋址。
*page size:隻應用于頁目錄項。設定為1,則頁目錄項指向2m或4m的記憶體。(hugepage)
*global标志:隻應用于頁表項,用于防止常用頁(全局頁)從tlb中重新整理出去。(當cr4寄存器的pge(頁全局啟用)标志置位時,這個标志才有效)。
##擴充分頁:(頁框大小為4mb而不是4kb)
——通過設定cr4處理器寄存器的pse标志能使擴充分頁與正常分頁共存。
對于2m頁面,啟動時傳遞核心參數
hugepages=1024
對于1gb的頁面:
default_hugepagesz=1g hugepagesz=1g hugepages=4
cpu所支援的hugepage大小可以由cpu标志得知
if pse exists, 2m hugepages are supported; if pdpe1gb exists, 1g hugepages are supported.
for 2 mb pages, there is also the option of allocating hugepages after the system has booted.
echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kb/nr_hugepages
mkdir /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
隻要是在 /mnt/huge/ 目錄下建立的檔案,将其映射到記憶體中時都會使用 2mb 作為分頁的基本機關。值得一提的是,hugetlbfs 中的檔案是不支援讀 / 寫系統調用 ( 如read()或write()等 ) 的,一般對它的通路都是以記憶體映射的形式進行的。
在實際應用中,為了使用大頁面,還需要将應用程式與庫libhugetlb連結在一起。libhugetlb庫對malloc()/free()等常用的記憶體相關的庫函數進行了重載,以使得應用程式的資料可以放置在采用大頁面的記憶體區域中,以提高記憶體性能。
##實體位址擴充(pae)分頁機制:
實體位址擴充(physical address extension,pae)用于将32位線性位址轉換為36位實體位址。
通過設定cr4控制寄存器中的pae标志激活pae。
pae分頁機制:
*64gb的ram被分為2^24個頁框,頁表項的實體位址字段從20位擴充到了24位。一個4kb的頁表包含512個表項而不是1024個表項。
*引入頁目錄表指針表(page directory pointer table,pdpt)的頁表新級别,它由4個64為表項組成。
*cr3控制寄存器包含一個27為的頁目錄指針表(pdpt)基位址字段。
*當把線性位址映射到4kb的頁時,32位線性位址按下列方式解釋:
cr3:指向一個pdpt;
位31-30:指向pdpt中4個項的一個;
位29-21:指向頁目錄表中512個項中的一個;
位20-12:指向頁表中512項中的一個;
位11-0:4kb頁中的偏移量。
*當把線性位址映射到2mb的頁時,32位線性位址按下列方式解釋:
位20-0:2mb頁中的偏移量。
為了縮小cpu和ram之間的速度不比對,引入了硬體高速緩存。基于局部性原理。
#cache line :高速緩存與記憶體間一次傳輸資料的長度。
#pcd 當通路該頁框中資料時,高速緩存功能被啟用還是禁用。
#pwt:當資料被寫到頁框時,采用通寫政策還是回寫政策。
linux對所有頁框都啟用高速緩存,對寫操作都采用回寫政策。
tlb(translation lookaside buffer):轉換後援緩沖器。
在多處理器系統中,每個cpu都有自己的tlb,稱為本地tlb。
機制:當一個線性位址第一次使用時,通過慢速通路ram的頁表計算出相應的實體位址,同時,該實體位址被存放在一個tlb表項(tlb entry)中,以便以後對同一線性位址的引用可以快速地轉換。