欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
LINUX程序的虛擬內存映射機制
1)虛擬內存的解釋:

虛擬內存的核心概念是指代碼所用的內存地址與物理地址沒(méi)有關(guān)系.
在用戶(hù)空間中,一個(gè)進(jìn)程的虛擬地址A指向不同的物理內存,而不是另一個(gè)進(jìn)程的地址A.
任何時(shí)候CPU發(fā)送指令向內存存取數據時(shí),通過(guò)軟件將虛擬地址的數據變?yōu)槲锢淼刂?
將虛擬地址變?yōu)槲锢淼刂纷優(yōu)槲锢淼刂返墓ぷ魇怯蓛却婀芾韱卧?MMU)完成的.
虛擬內存地址也可以稱(chēng)為邏輯地址.

2)內存管理單元:

內存管理單元是CPU功能的一部份,如果CPU有cache,它將有一個(gè)內存管理單元,反之亦然.
內存管理單元可以將兩個(gè)進(jìn)程對同一內存邏輯地址的訪(fǎng)問(wèn)映射到不同的物理地址.
內存管理單元同高速緩存密切協(xié)作,在RAM和高速緩存之間按要求傳遞內存.
內存管理單元將內存分成許多頁(yè),它是可利用物理內存的最小單位,每頁(yè)包含4KB字節的地址空間.

3)虛擬內存到物理內存的映射:


3.1)映射的過(guò)程:

虛擬地址到物理地址的轉化是與體系結構相關(guān)的,在X86 CPU上是以分段,分頁(yè)兩種方式轉化的.

虛擬地址(邏輯地址)---段式映射---線(xiàn)性地址---頁(yè)式映射---物理地址

Linux采用段頁(yè)式管理方式是由于intel的X86 CPU的硬件體系結構決定的.這樣的雙重映射本身毫無(wú)必要,在Linux中段式映射不起什么作用.
可以理解為虛擬地址就是線(xiàn)性地址.
通過(guò)以下的程序來(lái)分析虛擬內存到線(xiàn)性地址再到物理內存的映射,我們還以X86為例:


vi hello.c

#include <stdio.h>

int greeting(){
        printf("Hello world!\n");
        return 0;
}

int
main (){
        greeting();
        return 0;
}

編寫(xiě)一個(gè)HELLO WORLD程序,用gcc hello.c -o hello編譯


objdump -xd hello

這里我們主要看main和greeting的調用:
08048354 <greeting>:
 8048354:       55                      push   %ebp
 8048355:       89 e5                   mov    %esp,%ebp
 8048357:       83 ec 08                sub    $0x8,%esp
 804835a:       c7 04 24 70 84 04 08    movl   $0x8048470,(%esp)
 8048361:       e8 2e ff ff ff          call   8048294 <puts@plt>
 8048366:       b8 00 00 00 00          mov    $0x0,%eax
 804836b:       c9                      leave  
 804836c:       c3                      ret    

0804836d <main>:
 804836d:       8d 4c 24 04             lea    0x4(%esp),%ecx
 8048371:       83 e4 f0                and    $0xfffffff0,%esp
 8048374:       ff 71 fc                pushl  0xfffffffc(%ecx)
 8048377:       55                      push   %ebp
 8048378:       89 e5                   mov    %esp,%ebp
 804837a:       51                      push   %ecx
 804837b:       83 ec 04                sub    $0x4,%esp
 804837e:       e8 d1 ff ff ff          call   8048354 <greeting>
 8048383:       b8 00 00 00 00          mov    $0x0,%eax
 8048388:       83 c4 04                add    $0x4,%esp
 804838b:       59                      pop    %ecx
 804838c:       5d                      pop    %ebp
 804838d:       8d 61 fc                lea    0xfffffffc(%ecx),%esp
 8048390:       c3                      ret    
 
 函數main()通過(guò)call   8048354 <greeting>調用了greeting函數.
 
首先可以看到ld給greeting分配的地址是0x08048354,在elf格式的可執行代碼中,ld總是從0x08000000開(kāi)始安排代碼段,對每個(gè)程序都這樣.
而程序在執行時(shí)在物理內存中的實(shí)際位置就要由內核在為其建立內存映射時(shí)臨時(shí)作出安排,具體地址則取決于當時(shí)所分配的物理內存頁(yè)面.這對于我們完全是透明的.
映射機制在程序運行時(shí)就已經(jīng)建立起來(lái)了.


3.2)段式映射

從上例中,調用greeting()函數時(shí),當前的地址是0x08048354,也就是EIP指針寄存器的值,那么CS的值是什么呢?
CS寄存器存放的是段式映射的選擇碼,可以理解為這是一個(gè)索引.
在LINUX中,選擇碼只有4個(gè),也就是說(shuō)只可能是以下4個(gè)其中1個(gè),這4個(gè)選擇碼分別是:
段寄存器類(lèi)型  數值  索引            TI  RPL   
__KERNEL_CS   0x10  0000 0000 00010 0   00
__KERNEL_DS   0x18  0000 0000 00011 0   00
__USER_CS     0x23  0000 0000 00100 0   11
__USER_DS     0x2B 0000 0000 00101 0   11

與上面的對照: 
__KERNEL_CS   index=2   TI=0   RPL=0
__KERNEL_DS   index=3   TI=0   RPL=0
__USER_CS     index=4   TI=0   RPL=3
__USER_DS     index=5   TI=0   RPL=3

對選擇碼進(jìn)行解釋說(shuō)明:
1)關(guān)于段寄存器的賦值,依據以下的原則:
CS=__USER_CS
DS=__USER_DS
ES=__USER_DS
SS=__USER_DS
因為我們的程序在用戶(hù)空間中運行,所以無(wú)論是代碼段還是數據段都是__USER_XX

2)關(guān)于TI的值,TI可以是GDT(全局段描述表),也可以是LDT(局部段描述表).
GDT對映的是0
LDT對映的是1
LINUX的TI幾乎都是0,LINUX內核中基本上不使用局部描述表LDT,LDT只是在vm86模式中運行wine以及其它在linux上模擬運行windows
或DOS軟件的程序中才使用.

3)關(guān)于RPL,LINUX只用了0,3兩種級別.
0代表內核進(jìn)程,3代表用戶(hù)進(jìn)程.

通過(guò)以上的分析,我們的程序顯然是用戶(hù)進(jìn)程,所以對映的就是__USER_CS,
最后CS寄存器的值就是0x23,而索引就是4.二進(jìn)制(100)=十進(jìn)制(4)

而在GDT全局描述表中4對映的是什么呢?
我們先來(lái)看看gdt全局描述表:

ENTRY(gdt_table)
 .quad  0x0000000000000000 /*NULL desccriptor*/
 .quad  0x0000000000000000 /*not used*/
 .quad  0x00cf9a000000ffff /*0x10 kernel 4GB code at 0x00000000*/
 .quad  0x00cf92000000ffff /*0x18 kernel 4GB code at 0x00000000*/
 .quad  0x00cffa000000ffff /*0x23 user 4GB code at 0x00000000*/
 .quad  0x00cff2000000ffff /*0x2b user 4GB code at 0x00000000*/
 .quad  0x0000000000000000 /*not used*/
 .quad  0x0000000000000000 /*not used*/

可以看到索引為4的GDT就是 
.quad  0x00cffa000000ffff /*0x23 user 4GB code at 0x00000000*/

現在把這4項描述符展開(kāi):
                                63-60 59-56 55-52 51-48 47-44 43-40 39-36 35-32 31-28 27-24 23-20 19-16 15-12 11-8 7-4  3-0
Kernel_CS:0x00cf9a000000ffff -->0000  0000  1100  1111  1001  1010  0000  0000  0000  0000  0000  0000  1111  1111 1111 1111
Kernel_DS:0x00cf92000000ffff -->0000  0000  1100  1111  1001  0010  0000  0000  0000  0000  0000  0000  1111  1111 1111 1111
User_CS: 0x00cffa000000ffff -->0000  0000  1100  1111  1111  1010  0000  0000  0000  0000  0000  0000  1111  1111 1111 1111
User_DS: 0x00cff2000000ffff -->0000  0000  1100  1111  1111  0010  0000  0000  0000  0000  0000  0000  1111  1111 1111 1111

以下對描述符各位進(jìn)行解析:
描述符格式如下:
63-56位存放的是基地址31-24位,基地址都為0
55位也叫G位,在LINUX中都為1,等于1時(shí)段長(cháng)以4k字節為單位,等于0時(shí)以字節為單位
54位也叫D位,在LINUX中都為1,等于1表示對該段的訪(fǎng)問(wèn)為32位指令,等于0為16位指令
53位等于0
52位,CPU忽略該位,可由軟件使用.
51-48位存放的是段地址上限19-16位,都是1
47位也叫P位,在LINUX中都是1,表示4個(gè)段都在內存中.
46-45位是DPL位,表示特權級別.分別有00(0級)和11(3級)兩種組合.
44位也叫S位,等于1時(shí)表示一般的代碼段或數據段,等于0時(shí)表示用于系統管理的系統段,如各類(lèi)描述表.
43-41位叫做type位,因為各位之間有著(zhù)緊密聯(lián)系:
 43位也叫E位,等于1時(shí)表示代碼段,這時(shí)第42位叫C位,C位等于0時(shí)會(huì )忽視特權級別,C位等于1時(shí)會(huì )依照特權級別.這時(shí)41位叫R位,等于1時(shí)為可讀,為0時(shí)不可讀.
  43位等于0時(shí)表示數據段,這時(shí)第42位叫ED位,ED位等于0時(shí)向上伸(數據段),ED位等于1時(shí)向下伸(堆棧段),這時(shí)41位叫W位,等于1時(shí)為可寫(xiě),為0時(shí)不可寫(xiě).
40位叫A位,在LINUX中都是1,表示以被訪(fǎng)問(wèn)過(guò).
39-16位存放的是基地址23到0位,基地址都為0.
15-0位存放的是段地址上限15-0位,都是1

結論:每個(gè)段都是從0地址開(kāi)始的整個(gè)4GB虛存空間,虛地址到線(xiàn)線(xiàn)地址的映射保持原值不變.
因此,LINUX內核的頁(yè)式映射,可以直接將線(xiàn)性地址當作虛擬地址.二者完全一致.


3.3)頁(yè)式映射

3.3.1)頁(yè)式映射的概念:

1)在I386 CPU中頁(yè)式存儲的基本思路是:通過(guò)頁(yè)面目錄和頁(yè)面表分兩個(gè)層次實(shí)現從線(xiàn)性地址到物理地址的映射.
2)在LINUX中要考慮到各種不同的CPU,它以一種假想的,虛擬的CPU和MMU為基礎,設計出一種通用的模型,再把它分別落實(shí)到各種具體的CPU上.
因此,LINUX內核的映射機制設計成三層,在頁(yè)面目錄和頁(yè)面表中間增設了一層"中間目錄".
邏輯上的三層映射對于i386 CPU和MMU就變成了二層映射,把中間目錄PMD這一層跳過(guò)了,但是軟件的結構卻還保持著(zhù)三層映射的框架.
3)頁(yè)面目錄稱(chēng)為PGD,中間目錄稱(chēng)為PMD,頁(yè)面表則稱(chēng)為PT.PT的表項則稱(chēng)為PTE.
頁(yè)面目錄,中間目錄,頁(yè)目表三者均為數組.
4)邏輯上把線(xiàn)性地址分成4個(gè)段位,分別用在頁(yè)面目錄PGD的偏移,中間目錄PMD中的偏移,頁(yè)表PT中的偏移以及物理頁(yè)面內的偏移,而如果是I386的CPU則沒(méi)有中間目錄.
也就是被分成3個(gè)段位,分別是頁(yè)面目錄PGD的偏移,頁(yè)表pt中的偏移以及物理頁(yè)內的偏移量.
5)每個(gè)進(jìn)程都有自己的頁(yè)目錄表和頁(yè)表,進(jìn)程的切換就是將當前進(jìn)程的頁(yè)目錄表起始地址保存到CR3寄存器.


3.3.2)線(xiàn)性地址到物理地址的映射:

1)將一個(gè)進(jìn)程的頁(yè)面目錄起始地址裝入寄存器CR3.
2)用線(xiàn)性地址的第1個(gè)段位即PGD的偏移,找到頁(yè)面表的物理地址.頁(yè)目錄表的大小為4k,剛好一個(gè)頁(yè)的大小,包含1024項,每項4個(gè)字節(32位)
3)用線(xiàn)性地址的第2個(gè)段位即PT的偏移,找到表項,頁(yè)面表的大小也是4k,同樣包含1024項,每項4個(gè)字節(32位)
4)得到表項的高20位+低12位0組成,這個(gè)高20就是物理地址的高20位,再加上線(xiàn)性地址的第3段位即12位的偏移就得到了最終的物理地址.


3.3.3)用實(shí)例來(lái)說(shuō)明映射的過(guò)程:

第一步:通過(guò)頁(yè)目錄表找到頁(yè)面表
還是以上面的程序為例:
hello程序執行后,調用函數grreeting,這里的虛擬地址也就是線(xiàn)性地址為0x08048354
call   08048354 <greeting>
分解后的結果是:
0000 1000 0000 0100 1000 0011 0101 0100
第1個(gè)段位(高10位):
0000 1000 00
對映十進(jìn)制的32,也就是在頁(yè)目錄表的偏移32找到其頁(yè)面表的物理地址,也就是頁(yè)面表的指針,它的低12位是0,因為頁(yè)面表是4KB大小,所以肯定是邊界對齊了.

第二步:通過(guò)頁(yè)面表找到頁(yè)的起始物理地址高
接下來(lái)是線(xiàn)性地址的第二個(gè)段位(中間10位):
00 0100 10 00
對映十進(jìn)制的72,也就是在剛才找到的頁(yè)面表的偏移72找到目標頁(yè)的起始物理地址,高20位有效的地址,低12位填充為0.

第三步:得到最終的物理地址
通過(guò)找到的頁(yè)起始物理地址,加上線(xiàn)性地址的第三個(gè)段位的偏移地址得到最終的物理地址.
例如:
第三個(gè)段位:0011 0101 0100
對映16進(jìn)制為0x354
如果目標頁(yè)的起始物理地址為:0x740000,那么最終的物理地址就是:
0x740000+0x354=0x740354

本文來(lái)自CSDN博客,轉載請標明出處:http://blog.csdn.net/wishfly/archive/2010/05/21/5613931.aspx



本文來(lái)自CSDN博客,轉載請標明出處:http://blog.csdn.net/hshl1214/archive/2010/08/09/5799690.aspx
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
網(wǎng)易科技頻道--基于i386體系結構的Linux實(shí)現特點(diǎn)剖析——內存與進(jìn)程
Linux內存管理圖解
[外掛學(xué)習]Jim's游戲外掛學(xué)習筆記3——繼續找當前地圖數據和所處坐標存放的地址(原創(chuàng ))...
匯編語(yǔ)言的準備知識
Linux動(dòng)態(tài)鏈接的實(shí)現方式
i386 Linux下 ELF 動(dòng)態(tài)鏈接分析 (一)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久