#ifndef __I386_H__
#define __I386_H__
ULONG
GetCR3(VOID);
ULONG
GetCR4(VOID);
/* Intel Architecture 3A - 2.5 */
#define CR4_VME 0x00000001 /* Virtual 8086 Mode Extension */
#define CR4_PVI 0x00000002 /* Protected Mode Virtual Interrupts */
#define CR4_TSD 0x00000004 /* Time Stamp Disabled */
#define CR4_DE 0x00000008 /* Debugging Extension */
#define CR4_PSE 0x00000010 /* Page Size Extension - 4MB */
#define CR4_PAE 0x00000020 /* Physical Address Extension */
#define CR4_MCE 0x00000040 /* Machine-Check Enable */
#define CR4_PGE 0x00000080 /* Page Global Enable */
#define CR4_PCE 0x00000100 /* Performance Monitoring Counter Enable */
/*
I) IA-32 Virtual Address:
3 2 2 1 1 0
1 2 1 2 1 0
+-----------------+------------+-------------+
| Directory | Table | Offset |
+-----------------+------------+-------------+
Mapping PDE, PTE to memory:
PDE:
1) VirtualAddress >> 22 - we get offset to an entry in Page Directory
2) Entry size is 4Bytes ( (*4) == (<<2)
3) Base Address in Windows is: 0xC030 0000
4) PDE_BASE = 0xC0300000
5) PDE_END = 0xC0300FFF (1024PDE * 4B = 4KB)
PDE_Address(VirtualAddress) = ((VirtualAddress>>22)<<2) + PDE_BASE;
PTE:
1) VirtualAddress >> 12 - we get offset to an entry in PageTable Directory
2) Entry size is 4Bytes ( (*4) == (<<2))
3) Base Address in Windows is: 0xC0000000
4) PTE_BASE = 0xC0000000
5) PTE_END = 0xC03FFFFF (1024PDE * 1024PTE *4B = 4MB)
PTE_Address(VirtualAddress) = ((VirtualAddress>>12)<<2) + PTE_BASE;
Page Size - 4KB, 4MB (no PTE)
II) IA-32 PAE Virtual Address:
3 3 2 2 2 1 1 0
1 0 9 1 0 2 1 0
+--------+--------------+----------+-----------+
| DirPtr | Directory | Table | Offset |
+--------+--------------+----------+-----------+
Mapping PDE, PTE to memory:
PDE:
0) CR0.PG == 1 - paging enabled
CR4.PAE == 1 - PAE enabled
CR3 - Page Directory Pointer Table Base Address
1) VirtualAddress >> 21 - we get offset to an entry in Page Directory
2) Entry size is 4Bytes ( (*8) == (<<3)
3) Base Address in Windows is: 0xC060 0000
4) PDE_BASE = 0xC0600000
5) PDE_END = 0xC0603FFF (4DPE * 512PDE * 8B = 16KB)
PDE_Address(VirtualAddress) = ((VirtualAddress>>21)<<3) + PDE_BASE;
PTE:
1) VirtualAddress >> 12 - we get offset to an entry in PageTable Directory
2) Entry size is 8Bytes ( (*8) == (<<3))
3) Base Address in Windows is: 0xC0000000
4) PTE_BASE = 0xC0000000
5) PTE_END = 0xC07FFFFF (4DPE * 512PDE * 512PTE * 8B = 8MB)
PTE_Address(VirtualAddress) = ((VirtualAddress>>12)<<3) + PTE_BASE;
Page Size - 4KB, 2MB (no PTE)
Test:
PTE_Address(PTE_BASE)== PDE_BASE
*/
#define PAE_NO_EXECUTE_BIT 0x8000000000000000
typedef struct _PTE_PAE
{
/* [0-11] - Flags */
ULONG Present :1; // [V] - Valid - point to physical memory
ULONG Writable :1; // [W|R] - W when set
ULONG Owner :1; // [K|U] - Kernel mode, User mode
ULONG WriteThrough :1; // [T] - when set
ULONG CacheDisable :1; // [N] - when set
ULONG Accessed :1; // [A] - when set Page has been read
ULONG Dirty :1; // [D] - when set Page has been written to
ULONG LargePage :1; // [L] - when set PDE maps 4MB
ULONG Global :1; // [G] - global when set
ULONG ForUse1 :1; // [C] - copy on write, when set
ULONG ForUse2 :1;
ULONG ForUse3 :1;
/* [12-31] */
ULONG PageBaseAddress :20;
/* [35-32] */
ULONG BaseAddress :4;
/* [36-62] */
ULONG Reserved :27;
/*
* Intel - 3A 4.13
* NX (No eXecute) bit
*/
ULONG NoExecute :1; // [E] - No execute bit
} PTE_PAE, *PPTE_PAE;
typedef struct _PTE
{
ULONG Present :1; // [V] - Valid - point to physical memory
ULONG Writable :1; // [W|R] - W when set
ULONG Owner :1; // [K|U] - Kernel mode, User mode
ULONG WriteThrough :1; // [T] - when set
ULONG CacheDisable :1; // [N] - when set
ULONG Accessed :1; // [A] - when set Page has been read
ULONG Dirty :1; // [D] - when set Page has been written to
ULONG LargePage :1; // [L] - when set PDE maps 4MB
ULONG Global :1; // [G] - global when set
ULONG ForUse1 :1; // [C] - copy on write, when set
ULONG ForUse2 :1;
ULONG ForUse3 :1;
ULONG PageFrameNumber :20;
} PTE, *PPTE;
/*
E - exacutable - always set on x86
CGLDANTKWEV
-------UREV
*/
#define PDE_OFFSET 0xC0300000
#define PTE_OFFSET 0xC0000000
#define PDE_OFFSET_PAE 0xC0600000
#define PTE_OFFSET_PAE 0xC0000000
#define PDEaddrPAE(VirtualAddress) ( (PPTE_PAE)(((((ULONG) VirtualAddress) >> 21)<<3) + PDE_OFFSET_PAE ))
#define PTEaddrPAE(VirtualAddress) ( (PPTE_PAE)(((((ULONG) VirtualAddress) >> 12)<<3) + PTE_OFFSET_PAE ))
#define PDEaddr(VirtualAddress) ( (PPTE) (( (((ULONG) VirtualAddress) >> 22) <<2) + PDE_OFFSET) )
#define PTEaddr(VirtualAddress) ( (PPTE) (( (((ULONG) VirtualAddress) >> 12) <<2)+ PTE_OFFSET) )
#endif /* __I386_H__ */