<em id="0a85b"><option id="0a85b"></option></em>

<abbr id="0a85b"></abbr>

      <nobr id="0a85b"></nobr>
        <tr id="0a85b"></tr>
        9久久伊人精品综合,亚洲一区精品视频在线,成 人免费va视频,国产一区二区三区黄网,99国产精品永久免费视频,亚洲毛片多多影院,精品久久久无码人妻中文字幕,无码国产欧美一区二区三区不卡
        學習啦 > 學習電腦 > 網絡知識 > 網絡基礎知識 > 線性地址轉物理地址

        線性地址轉物理地址

        時間: 春健736 分享

        線性地址轉物理地址

          邏輯地址,需要轉換成線性地址,再經過MMU(CPU中的內存管理單元)轉換成物理地址才能夠被訪問到。那么線性地址怎么轉物理地址?今天學習啦小編整理了線性地址轉物理地址的相關資料,希望對大家有幫助。

          線性地址轉物理地址

          線性地址(Linear Address) 是邏輯地址到物理地址變換之間的中間層。程式代碼會產生邏輯地址,或說是段中的偏移地址,加上相應段的基地址就生成了一個線性地址。如果啟用了分頁機制,那么線性地址能再經變換以產生一個物理地址。若沒有啟用分頁機制,那么線性地址直接就是物理地址。Intel 80386的線性地址空間容量為4G(2的32次方即32根地址總線尋址)。

          詳細說下虛擬地址的轉換。

          首先,來看下內核為一個進程建立頁目錄和頁表以及線性空間的函數。這個函數原型是:

          VOID

          MiInitMachineDependent (

          IN PLOADER_PARAMETER_BLOCK LoaderBlock

          )

          位于init386.c的762行,這個函數太長了,挑選部分如下:

          PointerPte = MiGetPdeAddress (PDE_BASE);

          PdePageNumber = MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);

          CurrentProcess = PsGetCurrentProcess ();

          #if defined(_X86PAE_)

          PrototypePte.u.Soft.PageFileHigh = MI_PTE_LOOKUP_NEEDED;

          _asm {

          mov eax, cr3

          mov DirBase, eax

          }

          //

          // Note cr3 must be 32-byte aligned.

          //

          ASSERT ((DirBase & 0x1f) == 0);

          //

          // Initialize the PaeTop for this process right away.

          //

          RtlCopyMemory ((PVOID) &MiSystemPaeVa,

          (PVOID) (KSEG0_BASE | DirBase),

          sizeof (MiSystemPaeVa));

          CurrentProcess->PaeTop = &MiSystemPaeVa;

          #else

          DirBase = MI_GET_PAGE_FRAME_FROM_PTE (PointerPte) << PAGE_SHIFT;

          #endif

          CurrentProcess->Pcb.DirectoryTableBase[0] = DirBase;

          KeSweepDcache (FALSE);

          //

          // Unmap the low 2Gb of memory.

          //

          PointerPde = MiGetPdeAddress (0);

          LastPte = MiGetPdeAddress (KSEG0_BASE);

          MiZeroMemoryPte (PointerPde, LastPte - PointerPde);

          第一句:PointerPte = MiGetPdeAddress (PDE_BASE);這句獲得一個頁表的指針。

          PDE_BASE是頁目錄的基址,這個宏的定義如下:(i386.h 1968行)

          #define PDE_BASE_X86 0xc0300000

          #define PDE_BASE_X86PAE 0xc0600000

          #define PTE_TOP_X86 0xC03FFFFF

          #define PDE_TOP_X86 0xC0300FFF

          #define PTE_TOP_X86PAE 0xC07FFFFF

          #define PDE_TOP_X86PAE 0xC0603FFF

          #if !defined (_X86PAE_)

          #define PDE_BASE PDE_BASE_X86

          #define PTE_TOP PTE_TOP_X86

          #define PDE_TOP PDE_TOP_X86

          #else

          #define PDE_BASE PDE_BASE_X86PAE

          #define PTE_TOP PTE_TOP_X86PAE

          #define PDE_TOP PDE_TOP_X86PAE

          #endif

          #define PTE_BASE 0xc0000000

          可以看出,如果CPU支持PAE或者開啟了PAE(奔騰往后都支持,默認開啟),那么一個進程頁目錄的基址為0xc0600000,這個在dbg調試的時候也可以看到,如

          kd> !pte 0000

          VA 00000000 (虛擬地址)

          PDE at C0600000 PTE at C0000000

          contains 0000000002B40067 contains 0000000000000000

          pfn 2b40 ---DA--UWEV not valid

          再來看這個MiGetPdeAddress ,他是個宏,定義如下:(mi386.h 1889行)

          #define MiGetPdeAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 22) << 2) + PDE_BASE))

          可以看出他是取線性地址的最高10位,再左移2位,加上頁目錄的基址,得到該線性地址在該進程的 頁目錄的索引,而該處存放的就是其對應的頁表索引,第二句:

          PdePageNumber = MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);

          MI_GET_PAGE_FRAME_FROM_PTE 這個宏(mi386.h 2542行)的定義如下:

          #define MI_GET_PAGE_FRAME_FROM_PTE(PTE) ((PTE)->u.Hard.PageFrameNumber)

          他是直接取該頁表對應的物理內存的地址。到這里,CPU就可以訪問到實際的物理內存了。

          剩下的工作就是把cr3寄存器的內容賦給dirbase,再把dirbase賦給進程pcb的DirectoryTableBase項,這個在windbg調試的時候我說過了。后面再把該進程的低2G的用戶空間清零。

          我舉個例子,咱來一步步轉換。(我關閉了PAE,關閉方法,網上找,xp sp3)

          假如線性地址為7c920000,這個地址一般加載的是進程的ntdll文件,首先把它轉換成二進制,我在windbg里做,如下:

          kd> .formats 7c920000

          Evaluate expression:

          Hex: 7c920000

          Decimal: 2089943040

          Octal: 17444400000

          Binary: 01111100 10010010 00000000 00000000

          Chars: |...

          Time: Mon Mar 24 11:44:00 2036

          Float: low 6.0646e+036 high 0

          Double: 1.03257e-314

          可以看到高10位為01111100 10十六進制為0x1f2,

          01111100 10 ->0x1F2按照上面的宏,0x1F2在左移2位,為0x7C8,加上PDE的基址C0300000,結果為C03007C8,我們在windbg里看下,如下:

          kd> !pte 7c920000

          VA 7c920000

          PDE at C03007C8 PTE at C01F2480

          contains 03793067 contains 03791025

          pfn 3793 ---DA--UWEV pfn 3791 ----A--UREV

          可以看到,結果是吻合的,下面我們來算頁表,按照上面的說法,一個進程的頁目錄可以達到1024項(2的10次方),而每項都是4字節,所以一個進程的頁目錄大小為4096bytes(4k),同理,一個頁表的大小也為4096bytes(4k),而每一個頁目錄項對應一個4k大小的頁表,所以,頁表項的地址可以這么算:

          PTE = 頁表基址+(頁目錄項索引 × 一個頁表的大小) + (頁表索引 × 每一個頁表項的大小)

          由上面的宏定義知道在關了PAE的情況下頁表的基址PTE_BASE為0xc0000000,一個頁表項的大小也為4字節。而該線性地址的中間10位為010010 0000十六進制為0x120,所以,該線性地址對應的頁表地址為:

          PTE = 0xC0000000 + (0x1F2 * 0x1000) + (0x120 * 0x4) = 0xC01F2480.和上面windbg顯示的數據是一樣的。

          在windbg里看下該處的內容為

          kd> dd C01F2480

          c01f2480 03791025 00000000 00000000 04157025

          該頁表處的內容為0x03791025 ,其中,如果了解頁表結構的話,其高20位為該頁表指向的物理內存,為0x3791,再加上線性地址的末12位偏移,所以該線性地址對應的實際物理地址為:0X37910000.

          到這里就算完了。

          補充:

          內核定義的頁表的數據結構如下:

          typedef struct _MMPTE {

          union {

          ULONG Long;

          HARDWARE_PTE Flush;

          MMPTE_HARDWARE Hard;

          MMPTE_PROTOTYPE Proto;

          MMPTE_SOFTWARE Soft;

          MMPTE_TRANSITION Trans;

          MMPTE_SUBSECTION Subsect;

          MMPTE_LIST List;

          } u;

          } MMPTE;

          typedef MMPTE *PMMPTE;

          typedef struct _MMPTE_HARDWARE {

          ULONG Valid : 1;

          #if defined(NT_UP)

          ULONG Write : 1; // UP version

          #else

          ULONG Writable : 1; // changed for MP version

          #endif

          ULONG Owner : 1;

          ULONG WriteThrough : 1;

          ULONG CacheDisable : 1;

          ULONG Accessed : 1;

          ULONG Dirty : 1;

          ULONG LargePage : 1;

          ULONG Global : 1;

          ULONG CopyOnWrite : 1; // software field

          ULONG Prototype : 1; // software field

          #if defined(NT_UP)

          ULONG reserved : 1; // software field

          #else

          ULONG Write : 1; // software field - MP change

          #endif

          ULONG PageFrameNumber : 20;

          } MMPTE_HARDWARE, *PMMPTE_HARDWARE;

          可以看出上面那個取物理地址的宏直接取的就是PageFrameNumber ,也就是該地址內容的高20位。

          而在!pte命令在還顯示了一些大些字母,如D,A,W,U之類的,也在該結構中有所顯示。

          看過“ 線性地址轉物理地址 ”的人還看了:

        1.物理地址與虛擬地址怎么轉換

        2.物理地址與虛擬地址映射

        3.物理地址和虛擬地址

        4.物理地址和邏輯地址的區別

        5.物理地址可以改嗎

        603816 主站蜘蛛池模板: 精品国产AV无码一区二区三区| 亚洲国产一区二区三区| 中文国产日韩欧美二视频| 97精品国产福利一区二区三区| 亚洲高清WWW色好看美女| 国精产品999国精产品视频| P尤物久久99国产综合精品| 日韩精品成人无码专区免费 | 精品人妻伦九区久久aaa片| 精品国产一区二区三区国产馆| 久久99精品久久久久久青青| 波多野结衣中文字幕久久| 69成人免费视频无码专区| 日本二区三区视频免费观看| 亚洲中文久久久久久精品国产| 国产成人精品性色av麻豆| 欧美交a欧美精品喷水| 国产精品福利自产拍久久| 成全高清在线播放电视剧| 公天天吃我奶躁我的在线观看| 国产成人高清精品免费软件| 久久99热成人精品国产| 亚洲精品宾馆在线精品酒店| 国产成人综合在线女婷五月99播放| 日韩不卡无码精品一区高清视频 | AV无码不卡一区二区三区| 亚洲综合久久精品国产高清| 国产中文字幕精品喷潮| 成人午夜激情在线观看| 日日摸夜夜添夜夜添国产三级| 亚洲精品有码在线观看| 老师破女学生处特级毛ooo片| 国产不卡一区二区在线视频| 超碰成人人人做人人爽| 亚洲国产成人无码AV在线影院L| 久久91精品牛牛| 久久波多野结衣av| 国产小嫩模无套中出| 亚洲av午夜成人片精品| 国产AV国片精品有毛| 国产乱码日韩亚洲精品成人|