Linux內核剖析 之 內存尋址(二)
//接前一篇博客:
本節主要介紹硬件中分頁機製。
4、線性地址->物理地址(分頁:硬件部分)
為了效率,線性地址被分成以固定長度為單位的組,稱為頁(Page),頁內部連續的線性地址被映射到連續的物理地址中。
分頁單元把所有的內存分成固定長度的頁框(page frame)。每個頁框包含一個頁(page),也就是說一個頁框的長度與一個頁的長度一致。頁框是主存的一部分,因此是一個存儲區域。頁和頁框是不同的,也隻是一個數據塊,可以存放在任何頁框或磁盤中。
4.1、分頁
從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位線性地址按下列方式解釋:
Cr3:指向一個PDPT;
位31-30:指向PDPT中4個項的一個;
位29-21:指向頁目錄表中512個項中的一個;
位20-0:2MB頁中的偏移量。
4.2 加快線性地址轉換
為了縮小CPU和RAM之間的速度不匹配,引入了硬件高速緩存。基於局部性原理。
#cache line :高速緩存與內存間一次傳輸數據的長度。
#PCD 當訪問該頁框中數據時,高速緩存功能被啟用還是禁用。
#PWT:當數據被寫到頁框時,采用通寫策略還是回寫策略。
Linux對所有頁框都啟用高速緩存,對寫操作都采用回寫策略。
TLB(Translation Lookaside Buffer):轉換後援緩衝器。
在多處理器係統中,每個CPU都有自己的TLB,稱為本地TLB。
機製:當一個線性地址第一次使用時,通過慢速訪問RAM的頁表計算出相應的物理地址,同時,該物理地址被存放在一個TLB表項(TLB Entry)中,以便以後對同一線性地址的引用可以快速地轉換。
最後更新:2017-04-03 05:39:30