天天看點

Linux核心剖析 之 記憶體尋址(二) 4、線性位址->實體位址(分頁:硬體部分)

//接前一篇部落格:

本節主要介紹硬體中分頁機制。

       為了效率,線性位址被分成以固定長度為機關的組,稱為頁(page),頁内部連續的線性位址被映射到連續的實體位址中。

      分頁單元把所有的記憶體分成固定長度的頁框(page frame)。每個頁框包含一個頁(page),也就是說一個頁框的長度與一個頁的長度一緻。頁框是主存的一部分,是以是一個存儲區域。頁和頁框是不同的,也隻是一個資料塊,可以存放在任何頁框或磁盤中。

      從80386起,intel處理器的分頁單元處理4kb的頁。

      32位線性位址被分成3個域:

      *directory(目錄):最高10位

      *table(頁表):中間10位

      *offset(偏移量):最低12位

      線性位址的轉換分兩步完成:

      *頁目錄表轉換;

      *頁表轉換。

      使用二級模式的目的在于減少每個程序頁表所需記憶體的數量。

Linux核心剖析 之 記憶體尋址(二) 4、線性位址->實體位址(分頁:硬體部分)

      控制寄存器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标志能使擴充分頁與正常分頁共存。

Linux核心剖析 之 記憶體尋址(二) 4、線性位址->實體位址(分頁:硬體部分)

     對于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)中,以便以後對同一線性位址的引用可以快速地轉換。

繼續閱讀