linux使用者空間和核心空間之細說

來源:互聯網
上載者:User
從以上幾講我們知道,Linux簡化了分段機制,使得虛擬位址與線性地址總是一致,因此,Linux的虛擬位址空間也為0~4G。Linux核心將這4G位元組的空間分為兩部分。將最高的1G位元組(從虛擬位址0xC0000000到0xFFFFFFFF),供核心使用,稱為"核心空間"。而將較低的3G位元組(從虛擬位址0x00000000到0xBFFFFFFF),供各個進程使用,稱為"使用者空間)。因為每個進程可以通過系統調用進入核心,因此,Linux核心由系統內的所有進程共用。於是,從具體進程的角度來看,每個進程可以擁有4G位元組的虛擬空間。
Linux使用兩級保護機制:0級供核心使用,3級供使用者程式使用。可以看出(這裡無法表示圖),每個進程有各自的私人使用者空間(0~3G),這個空間對系統中的其他進程是不可見的。最高的1GB位元組虛擬核心空間則為所有進程以及核心所共用。
1.虛擬核心空間到物理空間的映射
核心空間中存放的是核心代碼和資料,而進程的使用者空間中存放的是使用者程式的代碼和資料。不管是核心空間還是使用者空間,它們都處於虛擬空間中。讀者會問,系統啟動時,核心的代碼和資料不是被裝入到實體記憶體嗎?它們為什麼也處於虛擬記憶體中呢?這和編譯器有關,後面我們通過具體討論就會明白這一點。
雖然核心空間佔據了每個虛擬空間中的最高1GB位元組,但映射到實體記憶體卻總是從最低地址(0x00000000)開始。對核心空間來說,其地址映射是很簡單的線性映射,0xC0000000就是物理地址與線性地址之間的位移量,在Linux代碼中就叫做PAGE_OFFSET。

我們來看一下在include/asm/i386/page.h中對核心空間中地址映射的說明及定義:
/*
* This handles the memory map.. We could make this a config
* option, but too many people screw it up, and too few need
* it.
*
* A __PAGE_OFFSET of 0xC0000000 means that the kernel has
* a virtual address space of one gigabyte, which limits the
* amount of physical memory you can use to about 950MB.
*
* If you want more physical memory than this then see the CONFIG_HIGHMEM4G
* and CONFIG_HIGHMEM64G options in the kernel configuration.
*/

#define __PAGE_OFFSET (0xC0000000)
……
#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
原始碼的注釋中說明,如果你的實體記憶體大於950MB,那麼在編譯核心時就需要加CONFIG_HIGHMEM4G和CONFIG_HIGHMEM64G選項,這種情況我們暫不考慮。如果實體記憶體小於950MB,則對於核心空間而言,給定一個虛地址x,其物理地址為"x-
PAGE_OFFSET",給定一個物理地址x,其虛地址為"x+ PAGE_OFFSET"。
這裡再次說明,宏__pa()僅僅把一個核心空間的虛地址映射到物理地址,而決不適用於使用者空間,使用者空間的地址映射要複雜得多。
2.核心映像
在下面的描述中,我們把核心的代碼和資料就叫核心映像(kernel
image)。當系統啟動時,Linux核心映像被安裝在物理地址0x00100000開始的地方,即1MB開始的區間(第1M留作它用)。然而,在正常運行時,
整個核心映像應該在虛擬核心空間中,因此,串連程式在串連核心映像時,在所有的符號地址上加一個位移量PAGE_OFFSET,這樣,核心映像在核心空間的起始地址就為0xC0100000。
例如,進程的頁目錄PGD(屬於核心資料結構)就處於核心空間中。在進程切換時,要將寄存器CR3設定成指向新進程的頁目錄PGD,而該目錄的起始地址在核心空間中是虛地址,但CR3所需要的是物理地址,這時候就要用__pa()進行地址轉換。在mm_context.h中就有這麼一行語句:
asm volatile("movl %0,%%cr3": :"r" (__pa(next->pgd));
這是一行嵌入式彙編代碼,其含義是將下一個進程的頁目錄起始地址next_pgd,通過__pa()轉換成物理地址,存放在某個寄存器中,然後用mov指令將其寫入CR3寄存器中。經過這行語句的處理,CR3就指向新進程next的頁目錄表PGD了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.