paging in linux,Linux Operating System
8種機(jī)械鍵盤軸體對比
本人程序員,要買一個(gè)寫代碼的鍵盤,請問紅軸和茶軸怎么選?
Paging in Linux
由於x86在32bit下有兩層的page table(PAE沒開情況下),而在64bit下有更多層,因此linux為了要在兩種處理器底下都能跑選擇了較高層的paging level。在2.6.10版本linux paging level有三層,從2.6.11版本之後增加到了四層page table。
如果四層都會(huì)用到的話,依照virtual address轉(zhuǎn)換到physical address的順序依序?yàn)?#xff1a;Page Global Directory、Page Upper Directory、Page Middle Directory、Page Table。如下圖所示:
會(huì)用到這四層主要是x86_64的處理器需要用到,那對於32bit PAE沒有開啟情況以及Pentium這些只有兩層就夠的該如何處理呢?Linux這邊直接將中間兩層的大小設(shè)為0,也就是Page Upper Directory跟Page Middle Directory這兩層table消失,讓Page Global Directory直接指向第四層的page table,如下圖:
而在32bit下PAE開啟的話有三層page table,此時(shí)對應(yīng)到的linux四層table如下:
每個(gè)process都有屬於他的Page Global Directory以及page tables,當(dāng)process switch發(fā)生時(shí)會(huì)將執(zhí)行到一半的process的cr3暫存器的值存到descriptor中,然後再從GDT中找出將要執(zhí)行的process的descriptor存到cr3,如此便能正確的指到page table。
Memory Addressing
接下來要講linux kernel的初始化,而實(shí)體記憶體當(dāng)中有些位置是被保留的,就算是kernel也不能放在那些保留的位置中,這些被保留的位置放置了BIOS以及一些I/O Port,如下圖所配置:
在主機(jī)板上的BIOS程式所放置的實(shí)體記憶體位置為0xF0000到0xFFFFF,而一些其他的硬體設(shè)備像是graphics cards的BIOS放置的位置則是在0xc0000到0xc7fff之間。而一些device的IO share memory則是會(huì)放置在0xa0000到0xfffff之間,這些程式是在OS起來之前所需要的,也就是剛開機(jī)時(shí)所執(zhí)行的程式,雖然OS起來後就不會(huì)用到BIOS,但是下一次開機(jī)還是會(huì)用到,因此這些程式無論如何都不能被動(dòng)到,不然你下次都開不了電腦了….而這些code都在0xfffff之前,也就是佔(zhàn)用了實(shí)體記憶體中的前16MB,因此這16MB的空間都不能動(dòng)到,linux kernel會(huì)從16MB後開始放置kernel的東西。
How Kernel Initializes Its Own page tables
kernel在初始page table會(huì)有兩個(gè)階段,在phase one時(shí)會(huì)初始化kernel code data segment,以及page table跟動(dòng)態(tài)資料結(jié)構(gòu)。kernel code+data總共有7MB,而在剛開機(jī)時(shí)是靠bootmen allocator來配置記憶體,bootmen allocator所佔(zhàn)的記憶體空間為1MB,所以phase one當(dāng)中會(huì)有24MB的virtual address需要mapping:
24MB的virtual address需要有6個(gè)entry來mapping到physical address,由於在paging機(jī)制開啟之前virtual address等於physical address,而在phase one當(dāng)中會(huì)遭遇到從沒有paging到paging開啟這段過程,因此為了讓physical address一致,這邊會(huì)希望在phase one時(shí)mapping後的address會(huì)跟沒有paging時(shí)直接轉(zhuǎn)換的address相等。下圖為physical address layout:
而在phase one中會(huì)呼叫到一些位置在0xc0000000之後的code,而我們希望mapping到physical時(shí)也會(huì)再前24MB的地方,因此我們的paging table有些特別,它會(huì)讓0x00000000與0xc0000000指到同一塊physical address:
相當(dāng)於在0xc0000000之後的virtual address只要減去0xc0000000就會(huì)變成physical address。那要如何做到呢?在linux kernel中Page Global Directory會(huì)存在initial_page_table,而第二層的Page Tables會(huì)存在 _brk_base,配合剛所講的24MB會(huì)需要6個(gè)entry,因此設(shè)定entry 0~5以及768 ~ 773以外的entry為0,而entry0跟entry 768所指向的_brk_base會(huì)是同一個(gè)entry,故相當(dāng)於768 entry以後的address都會(huì)減掉0xc0000000的offset了:
接下來看整個(gè)initial page table過程,首先在paging機(jī)制還沒開啟前,virtual address等於physical address,linux kernel程式都會(huì)在0x00000000到0x00800000:
在這個(gè)startup_32()中會(huì)把paging叫起來,它將initial_page_table load到cr3暫存器當(dāng)中,接著將cr0的PG flag enable,因此paging開始在處理器上運(yùn)行,此時(shí)virtual address轉(zhuǎn)換到physical address時(shí)會(huì)經(jīng)過paging unit:
而在initial過程中它乎叫了i386_start_kernel()程式,這是C程式,放置的位置是在0xc0000000之後,因此可以看到我們剛剛所設(shè)計(jì)的page table用意在此:
總結(jié)
以上是生活随笔為你收集整理的paging in linux,Linux Operating System的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 239元 荣耀手环7 NFC版开售:新增
- 下一篇: android o 跨进程广播,[And