【问题标题】:Detail about MSR_GS_BASE in linux x86 64linux x86 64 中 MSR_GS_BASE 的详细信息
【发布时间】:2012-07-14 21:39:39
【问题描述】:

我试图找出 Linux 内核中当前 MACRO 的详细信息。 current的最终汇编代码为:

movq %%gs:0xb000,%0

上面的代码可以工作!但是当我打印 %%gs 时,它的值为 0,所以 %%gs 指向 GDT NULL 的第一项!!??它是如何工作的?

mov %%gs, %0

相反,gs 的基数在 MSR_GS_BASE 中,当前可以替换为:

/*0xb000 is the offset of per_cpu__current_task*/
cur_task = (unsigned long*)(x86_rdmsr64(MSR_GS_BASE) + 0xb000);
println("cur_task:%p",*cur_task);

我的问题是:

%gs 指向 GDT NULL 的第一项!!??从 MSR_GS_BASE 读取它是如何工作的,它是 CPU 特性吗?我需要一些关于此的参考。

【问题讨论】:

    标签: assembly linux-kernel x86-64 memory-segmentation


    【解决方案1】:

    来自AMD Architecture Programmer's Manual Volume 2: System Programming,第 4.5.3 节:

    64 位模式下的 FS 和 GS 寄存器。 与 CS、DS、ES 和 SS 段不同,FS 和 GS 段覆盖可用于 64 位模式。在 64 位模式下使用 FS 和 GS 段覆盖时,它们各自的基地址用于有效地址 (EA) 计算。完整的 EA 计算则变为 (FS 或 GS​​).base + base + (scale * index) + 位移。 FS.base 和 GS.base 值也扩展为完整的 64 位虚拟地址大小,如图 4-5 所示。生成的 EA 计算允许包含正负地址。

    [...]

    有两种方法可以更新 FS.base 和 GS.base 隐藏描述符字段的内容。第一个专用于特权软件 (CPL = 0)。 FS.base 和 GS.base 隐藏描述符寄存器字段映射到 MSR。特权软件可以使用单个 WRMSR 指令将规范形式的 64 位基地址加载到 FS.base 或 GS​​.base 中。 FS.base MSR 地址为 C000_0100h,而 GS.base MSR 地址为 C000_0101h。

    更新 FS 和 GS 基本字段的第二种方法适用于以任何特权级别运行的软件(当实现支持并通过设置 CR4[FSGSBASE] 启用时)。 WRFSBASE 和 WRGSBASE 指令分别将 GPR 的内容复制到 FS.base 和 GS.base 字段。当操作数大小为 32 位时,基数的高位双字被清除。 WRFSBASE 和 WRGSBASE 仅在 64 位模式下受支持。

    【讨论】:

    猜你喜欢
    • 2014-01-04
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 2018-06-27
    • 2016-11-21
    • 1970-01-01
    相关资源
    最近更新 更多