這篇文章主要介紹Linux的用戶空間與內(nèi)核空間是什么意思,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)于2013年成立,先為波密等服務(wù)建站,波密等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為波密企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。當(dāng)內(nèi)核模塊代碼或線程訪問內(nèi)存時,代碼中的內(nèi)存地址都為邏輯地址,而對應(yīng)到真正的物理內(nèi)存地址,需要地址一對一的映射,如邏輯地址0xc0000003對應(yīng)的物理地址為0×3,0xc0000004對應(yīng)的物理地址為0×4,… …,邏輯地址與物理地址對應(yīng)的關(guān)系為
物理地址 = 邏輯地址 – 0xC0000000:這是內(nèi)核地址空間的地址轉(zhuǎn)換關(guān)系,注意內(nèi)核的虛擬地址在“高端”,但是ta映射的物理內(nèi)存地址在低端。
邏輯地址 | 物理內(nèi)存地址 |
0xc0000000 | 0×0 |
0xc0000001 | 0×1 |
0xc0000002 | 0×2 |
0xc0000003 | 0×3 |
… | … |
0xe0000000 | 0×20000000 |
… | … |
0xffffffff | 0×40000000 ?? |
假 設(shè)按照上述簡單的地址映射關(guān)系,那么內(nèi)核邏輯地址空間訪問為0xc0000000 ~ 0xffffffff,那么對應(yīng)的物理內(nèi)存范圍就為0×0 ~ 0×40000000,即只能訪問1G物理內(nèi)存。若機(jī)器中安裝8G物理內(nèi)存,那么內(nèi)核就只能訪問前1G物理內(nèi)存,后面7G物理內(nèi)存將會無法訪問,因?yàn)閮?nèi)核 的地址空間已經(jīng)全部映射到物理內(nèi)存地址范圍0×0 ~ 0×40000000。即使安裝了8G物理內(nèi)存,那么物理地址為0×40000001的內(nèi)存,內(nèi)核該怎么去訪問呢?代碼中必須要有內(nèi)存邏輯地址 的,0xc0000000 ~ 0xffffffff的地址空間已經(jīng)被用完了,所以無法訪問物理地址0×40000000以后的內(nèi)存。
顯 然不能將內(nèi)核地址空間0xc0000000 ~ 0xfffffff全部用來簡單的地址映射。因此x86架構(gòu)中將內(nèi)核地址空間劃分三部分:ZONE_DMA、ZONE_NORMAL和 ZONE_HIGHMEM。ZONE_HIGHMEM即為高端內(nèi)存,這就是內(nèi)存高端內(nèi)存概念的由來。
在x86結(jié)構(gòu)中,三種類型的區(qū)域(從3G開始計算)如下:
ZONE_DMA 內(nèi)存開始的16MB
ZONE_NORMAL 16MB~896MB
ZONE_HIGHMEM 896MB ~ 結(jié)束(1G)
前 面我們解釋了高端內(nèi)存的由來。 Linux將內(nèi)核地址空間劃分為三部分ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高端內(nèi)存HIGH_MEM地址空間范圍為 0xF8000000 ~ 0xFFFFFFFF(896MB~1024MB)。那么如內(nèi)核是如何借助128MB高端內(nèi)存地址空間是如何實(shí)現(xiàn)訪問可以所有物理內(nèi)存?
當(dāng)內(nèi)核想訪問高于896MB物理地址內(nèi)存時,從0xF8000000 ~ 0xFFFFFFFF地址空間范圍內(nèi)找一段相應(yīng)大小空閑的邏輯地址空間,借用一會。借用這段邏輯地址空間,建立映射到想訪問的那段物理內(nèi)存(即填充內(nèi)核PTE頁面表),臨時用一會,用完后歸還。這樣別人也可以借用這段地址空間訪問其他物理內(nèi)存,實(shí)現(xiàn)了使用有限的地址空間,訪問所有所有物理內(nèi)存。如下圖。
例 如內(nèi)核想訪問2G開始的一段大小為1MB的物理內(nèi)存,即物理地址范圍為0×80000000 ~ 0x800FFFFF。訪問之前先找到一段1MB大小的空閑地址空間,假設(shè)找到的空閑地址空間為0xF8700000 ~ 0xF87FFFFF,用這1MB的邏輯地址空間映射到物理地址空間0×80000000 ~ 0x800FFFFF的內(nèi)存。映射關(guān)系如下:
邏輯地址 | 物理內(nèi)存地址 |
0xF8700000 | 0×80000000 |
0xF8700001 | 0×80000001 |
0xF8700002 | 0×80000002 |
… | … |
0xF87FFFFF | 0x800FFFFF |
當(dāng)內(nèi)核訪問完0×80000000 ~ 0x800FFFFF物理內(nèi)存后,就將0xF8700000 ~ 0xF87FFFFF內(nèi)核線性空間釋放。這樣其他進(jìn)程或代碼也可以使用0xF8700000 ~ 0xF87FFFFF這段地址訪問其他物理內(nèi)存。
從上面的描述,我們可以知道高端內(nèi)存的最基本思想:借一段地址空間,建立臨時地址映射,用完后釋放,達(dá)到這段地址空間可以循環(huán)使用,訪問所有物理內(nèi)存。
看到這里,不禁有人會問:萬一有內(nèi)核進(jìn)程或模塊一直占用某段邏輯地址空間不釋放,怎么辦?若真的出現(xiàn)的這種情況,則內(nèi)核的高端內(nèi)存地址空間越來越緊張,若都被占用不釋放,則沒有建立映射到物理內(nèi)存都無法訪問了。
內(nèi)核將高端內(nèi)存劃分為3部分:VMALLOC_START~VMALLOC_END、KMAP_BASE~FIXADDR_START和FIXADDR_START~4G。
對 于高端內(nèi)存,可以通過 alloc_page() 或者其它函數(shù)獲得對應(yīng)的 page,但是要想訪問實(shí)際物理內(nèi)存,還得把 page 轉(zhuǎn)為線性地址才行(為什么?想想 MMU 是如何訪問物理內(nèi)存的),也就是說,我們需要為高端內(nèi)存對應(yīng)的 page 找一個線性空間,這個過程稱為高端內(nèi)存映射。
對應(yīng)高端內(nèi)存的3部分,高端內(nèi)存映射有三種方式:
映射到”內(nèi)核動態(tài)映射空間”(noncontiguous memory allocation)
這種方式很簡單,因?yàn)橥ㄟ^ vmalloc() ,在”內(nèi)核動態(tài)映射空間”申請內(nèi)存的時候,就可能從高端內(nèi)存獲得頁面(參看 vmalloc 的實(shí)現(xiàn)),因此說高端內(nèi)存有可能映射到”內(nèi)核動態(tài)映射空間”中。
持久內(nèi)核映射(permanent kernel mapping)
如果是通過 alloc_page() 獲得了高端內(nèi)存對應(yīng)的 page,如何給它找個線性空間?
內(nèi)核專門為此留出一塊線性空間,從 PKMAP_BASE 到 FIXADDR_START ,用于映射高端內(nèi)存。在 2.6內(nèi)核上,這個地址范圍是 4G-8M 到 4G-4M 之間。這個空間起叫”內(nèi)核永久映射空間”或者”永久內(nèi)核映射空間”。這個空間和其它空間使用同樣的頁目錄表,對于內(nèi)核來說,就是 swapper_pg_dir,對普通進(jìn)程來說,通過 CR3 寄存器指向。通常情況下,這個空間是 4M 大小,因此僅僅需要一個頁表即可,內(nèi)核通過來 pkmap_page_table 尋找這個頁表。通過 kmap(),可以把一個 page 映射到這個空間來。由于這個空間是 4M 大小,最多能同時映射 1024 個 page。因此,對于不使用的的 page,及應(yīng)該時從這個空間釋放掉(也就是解除映射關(guān)系),通過 kunmap() ,可以把一個 page 對應(yīng)的線性地址從這個空間釋放出來。
臨時映射(temporary kernel mapping)
內(nèi)核在 FIXADDR_START 到 FIXADDR_TOP 之間保留了一些線性空間用于特殊需求。這個空間稱為”固定映射空間”在這個空間中,有一部分用于高端內(nèi)存的臨時映射。
這塊空間具有如下特點(diǎn):
(1)每個 CPU 占用一塊空間
(2)在每個 CPU 占用的那塊空間中,又分為多個小空間,每個小空間大小是 1 個 page,每個小空間用于一個目的,這些目的定義在 kmap_types.h 中的 km_type 中。
當(dāng)要進(jìn)行一次臨時映射的時候,需要指定映射的目的,根據(jù)映射目的,可以找到對應(yīng)的小空間,然后把這個空間的地址作為映射地址。這意味著一次臨時映射會導(dǎo)致以前的映射被覆蓋。通過 kmap_atomic() 可實(shí)現(xiàn)臨時映射。
1、用戶空間(進(jìn)程)是否有高端內(nèi)存概念?
用戶進(jìn)程沒有高端內(nèi)存概念。只有在內(nèi)核空間才存在高端內(nèi)存。用戶進(jìn)程最多只可以訪問3G物理內(nèi)存,而內(nèi)核進(jìn)程可以訪問所有物理內(nèi)存。
2、64位內(nèi)核中有高端內(nèi)存嗎?
目前現(xiàn)實(shí)中,64位Linux內(nèi)核不存在高端內(nèi)存,因?yàn)?4位內(nèi)核可以支持超過512GB內(nèi)存。若機(jī)器安裝的物理內(nèi)存超過內(nèi)核地址空間范圍,就會存在高端內(nèi)存。
3、用戶進(jìn)程能訪問多少物理內(nèi)存?內(nèi)核代碼能訪問多少物理內(nèi)存?
32位系統(tǒng)用戶進(jìn)程較大可以訪問3GB,內(nèi)核代碼可以訪問所有物理內(nèi)存。
64位系統(tǒng)用戶進(jìn)程較大可以訪問超過512GB,內(nèi)核代碼可以訪問所有物理內(nèi)存。
4、高端內(nèi)存和物理地址、邏輯地址、線性地址的關(guān)系?
高端內(nèi)存只和邏輯地址有關(guān)系,和邏輯地址、物理地址沒有直接關(guān)系。
以上是“Linux的用戶空間與內(nèi)核空間是什么意思”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)站標(biāo)題:Linux的用戶空間與內(nèi)核空間是什么意思-創(chuàng)新互聯(lián)
文章網(wǎng)址:http://bm7419.com/article8/cdepip.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、網(wǎng)站收錄、響應(yīng)式網(wǎng)站、網(wǎng)站營銷、自適應(yīng)網(wǎng)站、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容