标签: gdt

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

我正在编写一个简单的自制64位OS,并通过UEFI进行引导。这意味着当我的代码开始执行时,它已经处于long模式,并且启用了分页。

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

成功更改CR3(分页结构)的内容后,我使用成功加载了新的GDT lgdt

问题在于,现在,要正确使用此新GDT,我需要将新值移至CS中。在网上,我找到了许多有关如何从32位切换到64位的方法的教程,但是从长模式到长模式几乎一无所获。

我想我应该跳个很远的距离,但是我没有用以下代码(AT&T语法)来做到这一点:

mov %rax, %cr3   # load paging structures (it works)
lgdt 6(%rcx)     # load gdt (it works)
mov $100, %rsp   # update stack pointer (it works)

# now what I tried unsuccessfully:
pushw $8         # new code segment selector
pushq fun        # function to execute next
retfq            # far return (pops address and code segment)
Run Code Online (Sandbox Code Playgroud)

没有适当的IDT,此代码使处的错误倍增retfq

编辑:我检查了我的分页结构,并且我很确定它们不是问题的原因。实际上,在没有最后三个指令的情况下,代码可以正常运行。问题是我需要一种更新CS的方法,在我的代码中仍然引用UEFI构建的旧段。是retfq正确的方法吗?还是我应该使用其他哪条指令?

提前致谢。

64-bit assembly x86-64 osdev gdt

2
推荐指数
1
解决办法
831
查看次数

如果 64 位架构中不存在 LDT,那么如何在 64 位架构上模拟使用它的 32 位系统?

我读到 LDT(本地描述符表)在 64 位体系结构中不存在,并且想知道如何模拟使用它的 32 位系统。

x86 assembly x86-64 instruction-set gdt

2
推荐指数
1
解决办法
131
查看次数

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

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

x86 operating-system osdev i386 gdt

2
推荐指数
1
解决办法
500
查看次数

386的“D位”中的“D”代表什么?

GDT 上的文章中, OSDev wiki 描述了用作 CS 描述符的 D 位的标志如下:

Sz:大小位。如果为0,则选择器定义 16 位保护模式。如果为1,则定义 32 位保护模式。您可以同时拥有 16 位和 32 位选择器。

另一个问题引用了 Intel 手册:代码段描述符中的 D 标志对 x86-64 指令有什么作用?它链接到Intel 64 和 IA-32 架构软件开发人员手册第 3 卷 [...]:系统编程指南中的“3.4.5 段描述符”部分 ,阅读:

D/B(默认操作大小/默认堆栈指针大小和/或上限)标志

根据段描述符是可执行代码段、向下扩展数据段还是堆栈段执行不同的功能。(对于 32 位代码和数据段,此标志应始终设置为 1,对于 16 位代码和数据段,应始终设置为 0。)

• 可执行代码段。该标志称为 D 标志,它表示段中指令引用的有效地址和操作数的默认长度。如果设置了标志,则假定为 32 位地址和 32 位或 8 位操作数;如果清楚,则假定为 16 位地址和 16 位或 8 位操作数。指令前缀 66H 可用于选择默认值以外的操作数大小,前缀 67H 可用于选择默认值以外的地址大小。

问题是,“D”代表什么?

x86 assembly terminology gdt memory-segmentation

2
推荐指数
1
解决办法
84
查看次数

为什么在 xv6 中有 sizeof(gdt)-1 的 gdtdesc

bootasm.S

.p2align 2                                # force 4 byte alignment
gdt:
  SEG_NULLASM                             # null seg
  SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)   # code seg
  SEG_ASM(STA_W, 0x0, 0xffffffff)         # data seg

gdtdesc:
  .word   (gdtdesc - gdt - 1)             # sizeof(gdt) - 1
  .long   gdt                             # address gdt
Run Code Online (Sandbox Code Playgroud)

这用于

lgdt gdtdesc
Run Code Online (Sandbox Code Playgroud)

gdtdesc 的第一个字不应该是 gdt 的字节大小吗?在这种情况下,它是3*8=24,它等于gdtdesc - gdt。为什么gdtdesc - gdt - 1在这里?

x86 assembly operating-system xv6 gdt

2
推荐指数
1
解决办法
66
查看次数

PM中Selector和GDT之间的关系是什么?

我浏览了网上有关全局描述符表的许多教程.但我找不到一个详细解释64位描述符中所有字段的站点.此外,我坚持使用GDT中的选择器概念.我知道选择器有一个索引,TI是GDT还是LDT字段.简单来说,选择器与GDT之间的关系是什么?如果可能请详细说明.

谢谢..

assembly operating-system kernel selector gdt

1
推荐指数
1
解决办法
353
查看次数

GDT是如何被调用的?

我知道GDT(全局描述符表)是如何实现的以及段寄存器和段描述符的使用。然而,如何/何时访问 GDT 条目呢?

是否可以通过基本 mov 指令访问,例如

mov [eax],ebx 
Run Code Online (Sandbox Code Playgroud)

这是否隐式调用 ds 段寄存器,然后访问 GDT 段描述符,或者是否有其他方式访问 GDT 条目?

memory x86 assembly osdev gdt

1
推荐指数
1
解决办法
463
查看次数