windows - AMD64 页面条目基地址字段如何将 52 位地址编码为 40 位?

标签 windows kernel x86-64 paging page-tables

我正在尝试手动遍历分页结构,以便将虚拟地址转换为其物理地址。我对存储在 PML4E、PDPE、PDE 和 PTE 中的物理基址字段有疑问。我系统上的页面大小是 4KB。我在 Windows 上以内核模式执行此操作。

正如 amd64 手册所说,cr3 的第 51-12 位包含 PML4 的物理基地址。但是,它说第 11-0 位应该假定为 0。我想知道是否同样的事情适用于其他分页结构的基地址字段,因为描述转换过程的图表说 52,但实际大小是只有 40 个(位 51-12)。

enter image description here

我如何用 C 语言进行翻译的示例:

// clear out everything except base address field
ULONG_PTR pPml4 = __readcr3() & ~0xFFF0000000000FFF,
    dataEntry;

copyAddress.PhysicalAddress.QuadPart = pPml4 + (sourceAddress.Hard.PageMapLevel4Index * 8);

if (MmCopyMemory(&dataEntry, copyAddress, 8, MM_COPY_MEMORY_PHYSICAL, &trans) != STATUS_SUCCESS) {
    ...
}

// dataEntry now has correct PML4E

// clear out everything except base address field
dataEntry &= ~0xFFF0000000000FFF;

// do I skip this?
dataEntry >>= 12;

最佳答案

来自手册第 5.4 节:

Translation-Table Base Address Field. The translation-table base-address field points to the physical base address of the next-lower-level table in the page-translation hierarchy. Page datastructure tables are always aligned on 4-Kbyte boundaries, so only the address bits above bit 11 are stored in the translation-table base-address field. Bits 11:0 are assumed to be 0. The size of the field depends on the mode...

所以是的,低 12 位为 0 以构成 52 位物理地址。

关于windows - AMD64 页面条目基地址字段如何将 52 位地址编码为 40 位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67167482/

相关文章:

linux - RT 修补的 Linux 内核的循环测试

assembly - 该跳转指令在 Intel64 中如何编码?

x86 - 下面的汇编指令addsd -8(%rbp), %xmm0 的作用是什么?

c - UEFI 应用程序中的计时器回调仅在 AMI BIOS 中挂起

windows - 低于3.0计算能力的GPU上的Keras?

c++ - EnumProcesses - 奇怪的行为

无法创建僵尸进程

linux - 插入我的内核模块时,INSMOD 退出并出现错误 "bad address",警告 "Kernel mismatch"

Linux 内核设备驱动程序需要访问用户空间中的共享对象

c++ - 是否有内置机制,以便在缓冲区不足时写入管道的字节可以覆盖较早的字节?