python網(wǎng)站開(kāi)發(fā) django桂平網(wǎng)絡(luò)推廣
認(rèn)真閱讀章節(jié)資料,掌握什么是分頁(yè)機(jī)制
調(diào)試代碼,掌握分頁(yè)機(jī)制基本方法與思路
- 代碼pmtest6.asm中,212行~237行,設(shè)置斷點(diǎn)調(diào)試這幾個(gè)循環(huán),分析究竟在這里做了什么
掌握PDE,PTE的計(jì)算方法
- 動(dòng)手畫(huà)一畫(huà)這個(gè)映射圖
- 為什么代碼3.22里面,PDE初始化添加了一個(gè)PageTblBase(Line 212),而PTE初始化時(shí)候沒(méi)有類(lèi)似的基地址呢(Line224)?
熟悉如何獲取當(dāng)前系統(tǒng)內(nèi)存布局的方法
掌握內(nèi)存地址映射關(guān)系的切換
- 畫(huà)出流程圖
基礎(chǔ)題:依據(jù)實(shí)驗(yàn)的代碼,
- 自定義一個(gè)函數(shù),給定一個(gè)虛擬地址,能夠返回該地址從虛擬地址到物理地址的計(jì)算過(guò)程,如果該地址不存在,則返回一個(gè)錯(cuò)誤提示。
- 完善分頁(yè)管理功能,補(bǔ)充alloc_pages, free_pages兩個(gè)函數(shù)功能,試試你能一次分配的最大空間有多大,如果超出了有什么辦法解決呢?
進(jìn)階題(選做)
- 設(shè)計(jì)一個(gè)內(nèi)存管理器,選擇其一實(shí)現(xiàn):首次適應(yīng)算法、最佳適應(yīng)算法、伙伴算法,要求實(shí)現(xiàn)內(nèi)存的分配與回收。(提示,均按照頁(yè)為最小單位進(jìn)行分配、對(duì)于空閑空間管理可采用位圖法或者雙向鏈表法管理)
什么是分頁(yè)機(jī)制
分頁(yè)機(jī)制就是通過(guò)頁(yè)目錄和頁(yè)表將物理地址與線(xiàn)性地址進(jìn)行映射
頁(yè)就是指一塊內(nèi)存,一般來(lái)說(shuō)大小在4 KB。
分頁(yè)機(jī)制使進(jìn)程運(yùn)行在線(xiàn)性地址上,不必關(guān)注物理地址的情況,提供了虛擬內(nèi)存和隔離機(jī)制,是內(nèi)存的調(diào)度完全由操作系統(tǒng)負(fù)責(zé)。
分頁(yè)機(jī)制實(shí)現(xiàn)的基本方法
分頁(yè)機(jī)制使用二級(jí)頁(yè)表實(shí)現(xiàn)
第一級(jí)叫頁(yè)目錄:大小4 KB,共1024表項(xiàng)(PDE),表項(xiàng)對(duì)應(yīng)一個(gè)二級(jí)頁(yè)表
第二級(jí)頁(yè)表:1024個(gè)表項(xiàng)(PTE),每個(gè)表項(xiàng)對(duì)應(yīng)一個(gè)物理頁(yè)
線(xiàn)性地址轉(zhuǎn)換時(shí),
- 寄存器cr3指定頁(yè)目錄
- 線(xiàn)性地址高十位為頁(yè)目錄索引
- 線(xiàn)性地址第二個(gè)十位為二級(jí)頁(yè)表索引
注:PDE,PTE,cr3寄存器都由高二十位進(jìn)行尋址,這是因?yàn)轫?yè)表地址都是4 KB對(duì)齊的。
分頁(yè)機(jī)制的標(biāo)志
cr0寄存器 的 最高位 PG位,PG位為1表示分頁(yè)機(jī)制生效
調(diào)試 pmtest6.asm
212行----237行
分析:
.1 部分是在初始化目錄頁(yè),大小為4096,將目錄頁(yè)首地址存在目錄頁(yè)的第一個(gè)表項(xiàng)中
.2部分實(shí)在初始化其他頁(yè)表,一共1024個(gè)頁(yè)表,需要1024 x 1024。
.3預(yù)備階段將目錄頁(yè)基地址賦給cr3,將cr0的PG位置1,啟動(dòng)分頁(yè)機(jī)制。
magic break斷點(diǎn)調(diào)試
PDE和PTE的計(jì)算方法
映射圖
為什么PDE添加了基地址,PTE不添加基地址
???不清楚,可能PDE是指向頁(yè)表的映射,而頁(yè)目錄本身也是一個(gè)頁(yè)表。PTE是指向物理頁(yè)的映射,所以不存自己頁(yè)表的地址。
也可能cr3不存頁(yè)目錄基地址,只能頁(yè)目錄自己來(lái)存,而PTE所在頁(yè)表的基地址在頁(yè)目錄中存放,不需要自己額外存。
如何獲取當(dāng)前系統(tǒng)內(nèi)存布局
使用中斷15 h
參數(shù):
eax:獲取內(nèi)存信息,ax賦值0E820h
ebx:放置著“后續(xù)值continuation value”第一次調(diào)用時(shí)ebx必須為0。
es : di :指向一個(gè)地址范圍描述符結(jié)構(gòu)ARDS (Address Range Descriptor Structure), BIOS將會(huì)填充此結(jié)構(gòu)。
ecx : es : di所指向的地址范圍描述符結(jié)構(gòu)的大小以字節(jié)為單位。無(wú)論es: di所指向的結(jié)構(gòu)如何設(shè)置BIOS最多將會(huì)填充ecx個(gè)字節(jié)。不過(guò)通常情況下無(wú)論ecx為多大BIOS只填充20字節(jié)有些BIOS忽略ecx的值總是填充20字節(jié)。
edx :0534D4150h('SMAP')──BIOS將會(huì)使用此標(biāo)志對(duì)調(diào)用者將要請(qǐng)求的系統(tǒng)映像信息進(jìn)行校驗(yàn)這些信息會(huì)被BIOS放置到es :di所指向的結(jié)構(gòu)中。
結(jié)果:
CF :CF = 0表示沒(méi)有錯(cuò)誤
eax :0534D4150h('SMAP')
es: di :返回的地址范圍描述符結(jié)構(gòu)指針,與輸入值相同
ecx :BIOS填充在地址范圍描述符中的字節(jié)數(shù)量,一般是20字節(jié)
ebx : 下次迭代時(shí)原封不動(dòng)放入ebx,就可以通過(guò)它獲取下一個(gè)地址范圍描述符,如果ebx值為0,且CF沒(méi)有進(jìn)位,表示是最后一個(gè)地址描述符
地址描述符結(jié)構(gòu)(ARDS)20個(gè)字節(jié)
注:調(diào)用int 15 h時(shí)返回的地址描述符需要存放在一個(gè)緩沖區(qū)中,我們要事先定義一個(gè)緩沖區(qū)
pmtest7.asm分析
定義256字節(jié)的緩沖區(qū),es: di指向緩沖區(qū)
CF被置位或ebx為0,循環(huán)結(jié)束。
di每次增20字節(jié),存一個(gè)描述符
內(nèi)存地址映射關(guān)系的切換
6.1 線(xiàn)性地址到物理地址
代碼如下:
; 顯示地址計(jì)算過(guò)程并進(jìn)行檢查 -----------------------------------------
AddressCheck:mov ax, SelectorFlatRWmov ss, axmov eax, LinearAddrDemoshr eax, 22mov ecx, eaxshl ecx, 2add ecx, PageDirBase1mov eax, ss:[ecx]mov ebx, eaxpush ecxcall DispIntpop ecxshr ebx, 12shl ebx, 12push ebxcall DispIntpop ebxmov eax, LinearAddrDemoshl eax, 10shr eax, 22mov ecx, eaxshl ecx, 2add ebx, ecxmov eax, ss:[ebx]shr eax, 12shl eax, 12push eaxcall DispIntpush ProcBarcall DispIntret
效果展示:
6.2 分頁(yè)管理功能完善
alloc_pages的實(shí)現(xiàn)
alloc_pages用于連續(xù)物理內(nèi)存的分配: struct?page *alloc_pages(gft_t gfp, unsigned?int?order) alloc_pages函數(shù)用于分配2^order個(gè)?連續(xù)?的物理頁(yè)。分配失敗返回NULL。
free_pages的實(shí)現(xiàn)
void free_pages(unsigned long addr, unsigned int order) 功能:釋放邏輯地址addr開(kāi)始的頁(yè)面2^order次方個(gè)
addr: 頁(yè)面開(kāi)始的邏輯地址
order: 釋放頁(yè)面的個(gè)數(shù)2^order個(gè)
實(shí)驗(yàn)結(jié)果總結(jié)
- 分頁(yè)和分段有何區(qū)別?在本次實(shí)驗(yàn)中,段頁(yè)機(jī)制是怎么搭配工作 的?
- PDE、PTE是什么?例程中如何進(jìn)行初始化?CPU是怎樣訪(fǎng)問(wèn) 到PDE、PTE,從而計(jì)算出物理地址的?
- 開(kāi)啟分頁(yè)機(jī)制之后,在GDT表中、在PDE、PTE中存的地址是物理地址、線(xiàn)性地址,還是邏輯地址,為什么?
- 為什么PageTblBase初始值為2M+4K?能不能比這個(gè)值小?
- 怎么讀取本機(jī)的實(shí)際物理內(nèi)存信息?
- 如何進(jìn)行地址映射與切換?
- 如何實(shí)現(xiàn)alloc_pages, free_pages
1.分頁(yè)和分段有何區(qū)別?在本次實(shí)驗(yàn)中,段頁(yè)機(jī)制是怎么搭配工作的?
區(qū)別在于:1、從功能上看,頁(yè)是信息的物理單位,分頁(yè)是為實(shí)現(xiàn)離散分配方式,以消減內(nèi)存的外碎片,提高內(nèi)存的利用率,即滿(mǎn)足系統(tǒng)管理的需要,而不是用戶(hù)的需要;而段是信息的邏輯單位,它含有一組其意義相對(duì)完整的信息,目的是為了能更好地滿(mǎn)足用戶(hù)的需要。2、頁(yè)的大小固定且由系統(tǒng)確定,而段的長(zhǎng)度卻不固定,決定于用戶(hù)所編寫(xiě)的程序。3、分頁(yè)的作業(yè)地址空間是一維的,而分段的作業(yè)地址空間是二維的。
在本次實(shí)驗(yàn)中,未打開(kāi)分頁(yè)機(jī)制時(shí),線(xiàn)性地址等同于物理地址,即邏輯地址通過(guò)分段機(jī)制直接轉(zhuǎn)化為物理地址(由SEG找到對(duì)應(yīng)Descriptor定義的段+OFFSET);啟動(dòng)了分頁(yè)機(jī)制后,要先通過(guò)分段機(jī)制將邏輯地址轉(zhuǎn)化為線(xiàn)性地址,在通過(guò)分頁(yè)機(jī)制將線(xiàn)性地址轉(zhuǎn)化為物理地址。首先,將頁(yè)目錄的段首地址設(shè)置為PageDirBase,再將頁(yè)表的段首地址設(shè)置為PageTblBase,在頁(yè)目錄中每個(gè)表項(xiàng)都指向一個(gè)頁(yè)表,而每個(gè)頁(yè)表的表項(xiàng)都指向一個(gè)物理地址,從而實(shí)現(xiàn)了從線(xiàn)性地址到物理地址的映射以及離散分配。
2. PDE、PTE,是什么?例程中如何進(jìn)行初始化?CPU是怎樣訪(fǎng)問(wèn)到PDE、PTE,從而計(jì)算出物理地址的?
PDE(Page Directory Entry)是頁(yè)目錄表的表項(xiàng),PTE(Page Table Entry)是頁(yè)表的表項(xiàng)。例程中初始化的方式是通過(guò)循環(huán)將每一個(gè)PDE初始化成存在的可讀可寫(xiě)可執(zhí)行的用戶(hù)級(jí)別頁(yè)表,其中第一個(gè)PDE對(duì)應(yīng)的頁(yè)表首地址是PageDirBase。類(lèi)似的,頁(yè)表中每個(gè)PTE都被初始化為可讀可寫(xiě)可執(zhí)行的用戶(hù)級(jí)別頁(yè)表,其中第一個(gè)頁(yè)表的首地址是PageTblBase。CPU首先根據(jù)分段機(jī)制,找到描述符所對(duì)應(yīng)的段并加上偏移得到線(xiàn)性地址,得到線(xiàn)性地址之后,CPU會(huì)借助cr3在指定的目錄頁(yè)中根據(jù)線(xiàn)性地址的高十位得到頁(yè)表地址,然后再根據(jù)線(xiàn)性地址的第二十一位到第十二位在頁(yè)表中得到物理頁(yè)首地址,最后加上第十二位偏移,從而計(jì)算出物理地址。
3. 開(kāi)啟分頁(yè)機(jī)制之后,在GDT表中、在PDE、PTE中存的地址是物理地址、線(xiàn)性地址,還是邏輯地址,為什么?
在查詢(xún)GDT表后得到線(xiàn)性地址,首先通過(guò)選擇子確定對(duì)應(yīng)描述符是GDT表中的第幾項(xiàng),然后取出段首地址加上邏輯地址的偏移,最終得到線(xiàn)性地址。PDE和PTE存放的都是物理地址,分別指向頁(yè)表和真實(shí)地址。
4. 為什么PageTblBase初始值為2M+4K?能不能比這個(gè)值小?
因?yàn)樵O(shè)置頁(yè)目錄表起始位置為2M,而頁(yè)目錄表占4K,且頁(yè)目錄表與頁(yè)表在內(nèi)存中相鄰,所以是2M+4K。在保證尋址大小為4G不變的情況下減小初始值,可以選擇前移頁(yè)目錄表的起始位置。
5. 怎么讀取本機(jī)的實(shí)際物理內(nèi)存信息
利用中斷15h,后循環(huán)讀取ARDS結(jié)構(gòu)。先填充如下寄存器:eax int 15h可完成許多工作,主要由ax的值決定,要獲取內(nèi)存信息,需要將ax賦值為0E820h,ebx寄存器放置著后續(xù)值,第一次調(diào)用時(shí)ebx必須為0。es: di 指向一個(gè)地址范圍描述符結(jié)構(gòu)ARDS,而B(niǎo)IOS將會(huì)填充此結(jié)構(gòu)。ecx,es:di所指向的地址范圍描述符結(jié)構(gòu)的大小,以字節(jié)為單位。無(wú)論es:di所指向的結(jié)構(gòu)如何設(shè)置,BIOS最多將會(huì)填充ecx個(gè)字節(jié)。edx 0534D4150h('SMAP')──BIOS將會(huì)使用此標(biāo)志,對(duì)調(diào)用者將要請(qǐng)求的系統(tǒng)映像信息進(jìn)行校驗(yàn),這些信息會(huì)被 BIOS放置到es:di所指向的結(jié)構(gòu)中。
中斷調(diào)用之后,結(jié)果存放于下列寄存器之中。CF CF=0表示沒(méi)有錯(cuò)誤,否則存在錯(cuò)誤。eax 0534D4150h('SMAP')。es: di 返回的地址范圍描述符結(jié)構(gòu)指針,和輸入值相同。ecx BIOS填充在地址范圍描述符中的字節(jié)數(shù)量,被BIOS所返回的最小值是20字節(jié)。ebx 這里放置著為等到下一個(gè)地址描述符所需要的后續(xù)值,如果 它的值為0,并且CF沒(méi)有進(jìn)位,表示它是最后一個(gè)地址范圍描述符。
6. 如何進(jìn)行地址映射與切換
通過(guò)改變cr3來(lái)轉(zhuǎn)換地址映射。改變cr3從而切換頁(yè)目錄表,從而切換頁(yè)表,從而使得同一個(gè)線(xiàn)性地址映射到不同的物理地址。
7. 如何實(shí)現(xiàn)alloc_pages,free_pages
alloc_pages的實(shí)現(xiàn)
alloc_pages用于連續(xù)物理內(nèi)存的分配: struct?page *alloc_pages(gft_t gfp, unsigned?int?order) alloc_pages函數(shù)用于分配2^order個(gè)?連續(xù)?的物理頁(yè)。分配失敗返回NULL。
free_pages的實(shí)現(xiàn)
void free_pages(unsigned long addr, unsigned int order) 功能:釋放邏輯地址addr開(kāi)始的頁(yè)面2^order次方個(gè)
addr: 頁(yè)面開(kāi)始的邏輯地址
order: 釋放頁(yè)面的個(gè)數(shù)2^order個(gè)