gpt4 book ai didi

x86 - 初始加载后如何更新 GDT 条目?

转载 作者:行者123 更新时间:2023-12-03 08:39:07 29 4
gpt4 key购买 nike

使用 lgdt 初始化 GDT 并将其加载到 GDTR 后,稍后如何更新 GDT?
如果我使用 sgdt 命令获取基地址,然后更新或添加条目,然后使用 lgdt 再次重新加载,我是否正确?还有其他方法吗?
或者我是否遗漏了一些东西,并且 GDT 永远不会“意味着”在初始化和加载后进行更新?

最佳答案

我知道这个问题已经很老了,但是我想强调一些评论中没有提到的事情,那就是 CPU 缓存的内容和不缓存的内容。

  1. 一些术语:
    • GDT 的条目称为描述符,对于这个答案,我们只对段描述符感兴趣
    • 段寄存器(csdsesfsgsssldtrtr)被分配指定段描述符的段选择器。段选择器始终为 16 位,由以下部分组成:
      1. 13位:描述符条目索引
      2. 1 位:0 表示 GDT,1 表示 LDT
      3. 2 位:请求的权限级别 (RPL)
  2. CPU 不会缓存 GDT,将值加载到 gdtr 只不过是加载一个值到 gdtr(由 GDT 的基地址及其大小组成) )
  3. 当每个段寄存器使用新的段选择器加载该段时,CPU 会缓存每个段寄存器使用的 GDT 描述符:
    • 每个段寄存器都有两部分:
      • “可见部分”,包含段选择器
      • “隐藏部分”包含段描述符的缓存副本
    • 当您执行 mov es, ax 时,ax 的值为 0x0010,例如:
      1. “可见部分”的值为 0x0010
      2. “隐藏部分”接收存储在 GDT 第 3 个条目中的信息的副本(因为 0x0010 表示第 3 个条目)
    • 使用段寄存器时,只有“隐藏部分”规定了其特征(基址、限制、访问信息)。
      • 用于加载段寄存器的 GDT 段描述符可能会被修改或根本不存在
      • gdtr 可能指向不同的位置,甚至是无效的位置,并且可能具有任意大小,同样,即使是无效的位置 - CPU 也不关心。
    • “可见部分”除了保存用于加载段寄存器的段选择器之外绝对不执行任何操作,然后可以通过 mov ax, es 检索该值。 (ax 变为 0x0010,即使认为 GDT 段描述符可能包含任何内容,甚至可能目前不存在)
    • 因此,为了将新的段描述符加载到段寄存器,您需要加载另一个(甚至相同的)选择器,这将更新重新加载“隐藏部分” - 缓存
  4. 话虽这么说,有很多原因需要保持 GDT 中已使用的条目固定,一个简单的原因是,当从内核模式移动到用户模式(反之亦然)时,您会更改段;因此,这些描述符必须存在于 GDT 中。 (CPU 还会在其他情况下自动加载新段,例如远调用、中断、任务门、调用门等)。简而言之,仅当您的操作系统不再使用描述符时才删除它。搞砸一些事情也更难
  5. 最后,为了回答您的问题,如果您想添加段描述符(或任何其他描述符),请将其添加到当前的 GDT 中,只需将适当的值放入空闲描述符条目中,然后加载新的选择器到段(如果此时需要,您可以更改 GDT 的大小)。如果你想更新一个段描述符,你可以在 GDT 中更新它,然后重新加载所有使用它的段,如果你不这样做,段将只使用旧的缓存值.

来源:英特尔® 64 和 IA-32 架构软件开发人员手册第 3 卷:系统编程指南第 3 章:保护模式内存管理

我建议您也看看 wiki.osdev.org,特别是:

请询问任何澄清

关于x86 - 初始加载后如何更新 GDT 条目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63092564/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com