MTRR Physical Base Register:
- 基址:高位部分(位12及以上)存储内存范围的起始地址。
- 内存类型:低位部分(位0-7)存储内存类型。
MTRR Physical Mask Register:
- 掩码:高位部分(位12及以上)存储内存范围掩码,用于定义内存范围的大小。
- 有效位(Enable Bit):位11,表示MTRR是否有效。
MTRR(Memory Type Range Registers)掩码寄存器用于定义内存范围的大小。掩码寄存器的高位部分存储内存范围的掩码,这些掩码位的设置决定了内存范围的大小。
掩码的含义
掩码寄存器中为1的位表示对应的地址位不参与内存范围的计算,而为0的位表示对应的地址位参与内存范围的计算。因此,掩码寄存器的掩码决定了内存范围的大小。
计算内存范围大小的步骤
-
读取掩码寄存器的值:
- 掩码寄存器的值包括高位的掩码和低位的有效位(Enable Bit)。
-
取反掩码:
- 对掩码取反(按位取反),这样原本为0的位变为1,表示参与内存范围计算的位数。
-
仅保留高位部分:
- 使用掩码
0xFFFFFF000
,仅保留高位部分(从第12位开始的部分),忽略低12位。
- 使用掩码
-
加1得到实际大小:
- 加1得到实际内存范围大小。
示例计算
-
计算物理内存的结束地址 假设基址是 0x00C00000: 基址:0x00C00000 内存范围大小:0x000000800000 计算结束地址: end_addr = base_addr + size - 1; end_addr = 0x00C00000 + 0x000000800000 - 1; end_addr = 0x00FFFFFF; 代码示例 以下是示例代码,演示如何读取MTRR寄存器并计算物理内存结束地址: #include <stdint.h> #include <stdio.h> #define MSR_MTRRphysBase0 0x200 // 第一个MTRR基址寄存器的MSR地址 #define MSR_MTRRphysMask0 0x201 // 第一个MTRR掩码寄存器的MSR地址 static inline uint64_t read_msr(uint32_t msr) { uint64_t value; __asm__ __volatile__ ( "rdmsr" : "=A"(value) : "c"(msr) ); return value; } int main() { // 读取MTRR物理基址寄存器 uint64_t base = read_msr(MSR_MTRRphysBase0); // 读取MTRR物理掩码寄存器 uint64_t mask = read_msr(MSR_MTRRphysMask0); // 解析基址 uint64_t base_addr = base & 0xFFFFFF000; // 基地址位于位12到位35 // 解析掩码 uint64_t mask_value = mask & 0xFFFFFF000; // 掩码位于位12到位35 // 计算内存范围大小 uint64_t size = (~mask_value & 0xFFFFFF000) + 1; // 计算物理内存结束地址 uint64_t end_addr = base_addr + size - 1; printf("MTRR Base Address: 0x%llx\n", base_addr); printf("MTRR Mask: 0x%llx\n", mask_value); printf("Physical Memory End Address: 0x%llx\n", end_addr); return 0; }