Linux kernel High memory

來源:互聯網
上載者:User

在32bit機器上,由於32bit地址空間的限制,最大定址範圍為2^32 - 1也就是4G的線性地址空間,linux 會按照3G/1G, 2G/2G, 1G/3G的分配方式,把這個4G的地址空間劃分為兩個部分

所謂3G/1G就是3G應用空間 1G核心空間, 2G/2G就是2G的應用地址空間 2G的核心地址空間。

我們這裡只考慮3G/1G的情況,即只有1G的核心空間。linux 核心又對這1G的核心地址空間進行了劃分,

1. 從PAGE_OFFSET開始的第一段空間為物理RAM的線性映射空間,這段空間的大小在x86機器上固定為896MB,而對於2G/2G劃分的arm機器,這個線性映射空間就可能達到1G以上,能夠直接映射到這個線性空間的物理地址是DMA zone和Normal Zone,在這個範圍之外的實體記憶體則劃歸High memory Zone。

2. kernel在PAGE_OFFSET和VMALLOC_START之間保留了一段安全區,目的是為了捕獲記憶體越界

3. VMALLOC_START到VMALLOC_END這段空間是非連續記憶體區,被vmalloc和vfree使用,非連續記憶體區可以為核心提供邏輯地址連續但物理地址不一定連續的記憶體區。非連續記憶體區即可以映射Normal Zone也可以映射High memory Zone的實體記憶體。當核心線程需要一大塊記憶體,但是又不需要對應的實體記憶體是連續的時,可以使用vmalloc分配。由於vmalloc僅僅分配了一段地址空間,並未實際分配實體記憶體,因此可分配的空間大小可以大於實體記憶體大小。

當系統實體記憶體較大時,會有部分實體記憶體無法進行線性映射,這些無法映射的實體記憶體稱為High memory,相應的可以映射的低端實體記憶體稱為Low memory.

沒有線性地址的高端記憶體中的頁框無法被核心訪問。線性地址空間後面的一部分專門用於高端實體記憶體的映射,當然這種映射是暫時的,否則,會造成只有部分高端實體記憶體能夠被映射。

核心可以採用3種不同的機制映射高端實體記憶體,分別為: 永久核心映射,固定映射(臨時核心映射是固定映射的特殊形式)和非連續記憶體配置


非連續記憶體配置

非連續記憶體區即可以映射高端記憶體也可以映射低端記憶體。通過連續的線性地址來訪問非連續的頁框這樣一種分配模式很有意義,因為這種模式避免了外片段,外片段的存在會使系統沒有足夠大的連續頁框。

linux在幾個方面使用非連續記憶體配置:

1. 為活動的交換區分配資料結構

2. 為模組分配空間

3. 或者給某些I/O驅動程式分配緩衝區,這些驅動不要求連續的物理頁框。

永久核心映射 Persistent Kernel Map

允許核心建立高端頁框到核心地址空間的長期映射,他們使用主內和頁表中的一個專門的頁表,地址存放在pkmap_page_table中。頁表的大小為512或者1024,這取決於PAE是否被啟用,PAE未被啟用時 頁表項佔用4個位元組,這樣一個頁表可以存放1024個頁表項,如果PAE被啟用,那麼頁表項佔用8位元組,這個頁表只能存放512項。因此核心一次最多隻能訪問2M或者4M的高端記憶體。

固定核心映射

固定核心映射的線性地址類似於0xffffc000.  固定核心映射線性地址到物理地址轉換並不像核心線性映射空間直接減去0xc0000000, 而是可以任意方式建立. 也就是說固定映射的線性地址可以對應任意的物理地址.

每一個固定映射的線性地址都對應一個整形索引值,這個整形索引值的定義為

enum fixed_addresses {#ifdef CONFIG_X86_32    FIX_HOLE,    FIX_VDSO,#else    VSYSCALL_LAST_PAGE,    VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE                + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,    VSYSCALL_HPET,#endif#ifdef CONFIG_X86_32    FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */    FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,#endif    __end_of_fixed_addresses};

fix_to_virtFunction Compute從給定索引 對應的常量線性地址

static inline unsigned long fix_to_virt(const unsigned int idx){    if (idx >= FIX_KMAP_END)        __this_fixmap_does_not_exist();    return __fix_to_virt(idx);}

為了把一個固定地址和物理映射的線性地址關聯起來,核心使用set_fixmap(idx,phys) 和set_fixmap_nocache

臨時核心映射
臨時核心映射是固定地址核心映射的特殊形式,可以用在中斷處理常式和可延遲函數的內部,因為他們不阻塞當前進程。

在高端記憶體的任何一個頁框都可以通過一個視窗映射到核心地址空間.

每個CPU都有自己的一組視窗的集合,具體每個視窗定義參看km_type. 該資料結構中的每個符號,標識了一個視窗,對應著一個固定的核心地址,通過

fix_to_virt 從這個符號(索引)擷取核心線性地址。記住每個符號都有一個具體的含義,只能有一種核心成分使用,因此也就保證了臨時核心映射可以是非阻塞的

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.