问题标签 [gdt]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
5584 浏览

assembly - 如何在 NASM 程序集中进入 32 位保护模式?

我正在学习 x86 汇编,我正在尝试在 NASM 中制作一个玩具操作系统,但我不明白一些东西。

我制作了一个成功启动内核的引导加载程序:

  1. 从包含内核文件的软盘加载 14 个扇区;
  2. kernel.feo在这些标记为;的扇区中搜索文件
  3. 将该文件加载到内存中的偏移量0x2000
  4. 使用远跳转执行内核jmp 0x2000:0x0000

所以我的内核代码位于0x2000:0内存中。CS由于使用了远跳,可能会正确设置。在这个内核代码中,我想进入 32 位保护模式,但我不确定 GDT 是如何工作的。当我在虚拟机上运行下面的代码时(QEMU),它什么也不做。

我想请你帮我进入 32 位保护模式!

也就是说,您有以下问题:

  1. 您假设代码是0x7c00:0由于 加载的org 0,但情况可能并非如此。唯一保证的是物理地址。您应该使用远跳转到您的入口点,以便CS正确设置。
  2. 您出于某种原因设置DS为,0x2000因此您的代码根本找不到任何数据。您应该设置DS为 match CS,或在任何地方使用CS覆盖(不推荐)。
  3. 保护模式代码假定从零开始的段,这反过来意味着它期望org 0x7c00这当然与您的设置冲突。您应该切换到org 0x7c00和 段0
  4. VGA 文本模式段为0xb8000not 0xb80000(减一)。
  5. 0x55 0xaa引导扇区末尾没有引导签名字节。

我在我的代码中更正了这些事情:

  1. [org 0x0]被更正为[org 0x2000],段被设置为0
  2. DS被更正为,0而不是0x2000,所以现在它匹配CS;
  3. VGA 文本模式段更正为0xb8000

但是代码无法使用这些更正,它应该打印两个字符串但它什么都不做!

请注意,此内核代码不应以引导签名结尾0x55 0xAA,因为它不是引导扇区。

这是更正的内核代码(不起作用):

0 投票
1 回答
746 浏览

assembly - NASM 如何在没有 org 的情况下设置相对于加载地址的标签地址

我正在尝试为内核编写引导加载程序。目前我正在用程序集加载 GDT,但我想编写一些 C 代码来生成 GDT(和 IDT)问题是引导扇区总是在地址 0x7c00 加载,所以我需要一种方法来抵消我的标签与那个地址。如果我组装成一个 bin 文件,我可以只使用 [org 0x7c00] 但我想将引导加载程序组装成一个目标文件(NASM 不支持这种格式的 org),以便我可以使用外部符号。如果没有 org,我的汇编代码中有这个:

组装后的样子:

什么时候应该

该表本身也是错误的,因为 gdt 起始位置没有考虑偏移量。

除了我自己手动添加偏移量(我必须有很多地方),有没有我可以用来设置起始地址的指令?

编辑:从 0xc700 更改为 0x7c00

0 投票
1 回答
505 浏览

x86 - 大实模式下的地址翻译

正如http://wiki.osdev.org/Unreal_Mode所说,我有一些关于地址转换如何在大实模式下发生的问题

虚幻模式包括打破实模式段的“64Kb”限制,但仍通过调整描述符缓存来保持 16 位指令和段*16+偏移地址的形成

但我的问题是如何在过程中使用 gdt,甚至在转换为线性地址时是否使用它。如果有人可以指出切换到大实模式的某些规范或其他参考,那将非常有帮助,如果有人可以提供有关如何切换回实模式的一些见解,那将非常好。

问候,

阿尔卡

0 投票
0 回答
141 浏览

linux - 当设置为 TLS 选择器时,为什么 ES 和 DS 最终会在 64 位内核上归零?

下面的 32 位程序调用set_thread_area(2)在 GDT 中创建一个条目,该条目旨在用于 TLS。通常,生成的选择器会被放入FSGS成功使用。但是,如果它被放入DSor ES,在 64 位内核上运行,最终(我猜是在上下文切换之后)这个选择器归零。

但是,如果我改为使用modify_ldt(2)并将生成的 LDT 条目的选择器放入这些段寄存器中,它们似乎保留了它们的值!

此外,如果我将 64 位代码段 ( 0x33) 或 32 位代码段 ( 0x23) 的选择器(它们都引用 GDT)放入DSor ES,它们不会被清零。

这是源代码(使用fasm编译),展示了奇怪的行为:

这似乎与 64 位进程默认在这两个段寄存器中具有 NULL 选择器这一事实有关。

这发生在 Linux 3.16.0 及更早版本上,但不会出现在 4.2.0 及更高版本上。

这里发生了什么?为什么在其中包含 TLS 选择器时会清零,但ESDS任何其他选择器无关?

0 投票
1 回答
5324 浏览

x86 - LDT 和 GDT 在 Intel x86 中的使用方式有何不同?

我知道这两个表都包含段描述符,这些描述符提供了每个段的访问详细信息,包括基地址、类型、长度、访问权限等。

看这篇博客描述的区别如下:
1. GDT 在系统中只有一个副本,而 LDT 可以有很多
2. GDT 在执行过程中可能不会更改,LDT 经常在任务切换时更改
3. LDT 的条目保存在 GDT 中。GDT 和 LDT 中的条目具有相同的结构。

系统在实际程序中如何以不同的方式使用这些结构?

0 投票
1 回答
2120 浏览

assembly - 在长模式下更改 GDT 并更新 CS

我正在编写一个简单的自制 64 位操作系统,通过 UEFI 启动它。这意味着当我的代码开始执行时,它已经处于长模式,并启用了分页。

现在,在退出 UEFI 引导服务后,我想用我自己的替换 UEFI 构建的所有控制结构。

成功更改 CR3(分页结构)的内容后,我使用lgdt.

问题是现在,为了正确使用这个新的 GDT,我需要将一个新值移动到 CS 中。在网上我找到了很多关于如何从 32 位切换到 64 位的教程,但几乎没有关于长模式到长模式的内容。

我认为我应该使用远跳,但我没有设法用这段代码(AT&T 语法)做到这一点:

没有任何 IDT,此代码在retfq.

编辑:我检查了我的分页结构,我很确定它们不是问题的原因。事实上,没有最后三个指令,代码运行良好。问题是我需要一种更新 CS 的方法,在我的代码中仍然指的是 UEFI 构建的旧段。这样做是retfq正确的方法吗?或者我应该使用哪个其他指令?

提前致谢。

0 投票
0 回答
515 浏览

x86 - 如何在 x86 中启用分页并在 UEFI 中显示 GDT

我的目标是在 UEFI 中启用 x86 中的分页。我的教授说,我可能会先尝试在 UEFI 中显示 GDT - 这样我也会查看分页是否有效。问题是,我不知道该怎么做。

我使用本教程在 Visual Studio 中启用 EDK2:http: //uefi.blogspot.com/2013/06/how-to-set-up-edk2s-windows-hosted-uefi.html

你能指点我任何教程或解释我该怎么做吗?

0 投票
0 回答
871 浏览

linux - 全局描述符表和本地描述符表的关系?

保护模式内存管理

我正在查看此链接的分段。

LDT 和 GDT 都是独立的还是相互依赖的?

(TI位(这是选择器的一部分)来决定应该使用哪个描述符表(GDT或当前活动的LDT)所以我认为它是独立的)

从图中 GDTR-LDTR

还有 GDT(全局描述符表),主要用于保存操作系统段的描述符条目。示例内核堆栈--code_section/data_section?

LDT 第二种类型称为 LDT(本地描述符表),包含普通应用程序段的条目(尽管不一定)用户堆栈 --code_section/data_section ?

它说 LDTR 寄存器包含内存中当前活动 LDT 的大小和位置。这是否意味着在上下文切换中我们将每个进程的 LDTR 值保存在该进程的 pcb 中?

0 投票
2 回答
7879 浏览

assembly - 定义全局描述符表有什么用?

我读了一篇关于 GDT(全局描述符表)的教程,它将 GDT 定义为“为内存的某些部分定义基本访问权限的那个”。这意味着 GDT 用于内存保护。

它是否执行上述以外的任何其他任务?

在操作系统中实现 GDT 是必须的吗?

简而言之,如果有人能以易于理解的方式详细说明 GDT,那就更好了。

谢谢

0 投票
0 回答
610 浏览

x86 - 为什么 x86 处理器在 GDT 中需要一个 NULL 描述符?

我在 i386 上编写自己的操作系统,然后是全局描述符表设置,我对 NULL 描述符感到困惑。

1986 年英特尔 80386 程序员参考手册中,

NULL_DES DESC <> ; 空描述符

是关于 NULL 描述符的唯一提及。

有没有人告诉我为什么 x86 处理器在 GDT 中需要一个 NULL 描述符?