问题标签 [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.
c - 中断三重故障
我对这一切都很陌生,所以如果我错过了一些非常明显的事情,我提前道歉
所以,我试图在 x86 汇编和 C 中制作一个简单的内核。我试图让中断工作。我在汇编中定义 GDT、IDT。
我什至不确定是 GDT 还是 IDT 出了什么问题。问题是,在我真正触发中断之前,一切似乎都很好。
我查看了 OSDev、英特尔手册、James Molloy 的指南和随机的博客文章,但我就是想不通。
这是代码:
assembly - 设置 GDT 时 Qemu 无限重启
我主要用 C++ 制作操作系统,但对于引导加载程序,我使用的是 FASM。当我尝试设置 GDT 时,Qemu 清除屏幕并在顶部重新打印“SeaBIOS”。它继续像这样循环,直到我关闭它。这是它的 GIF:
我尝试使用 -nographic 运行它,但它在 Windows 控制台中执行相同的操作。
哦,是的,操作系统/版本信息。
Windows:20H2
FASM:1.73.25
Qemu:5.1.0
这是我的代码:
更新:完整代码:
operating-system - 为什么此代码中没有加载 gdt?
这是用 AT&T 语法编写的。我在这里问我的 gdt 是否有任何问题,因为我的中断不起作用。请指出我可能遇到的任何错误
我使用 GRUB 作为我的引导加载程序并为 i386 架构进行编译。我已经有我的交叉工具链设置 & 我似乎无法在这里找到任何错误
rust - 加载 GDT 时出现三重故障
我正在尝试在 rust 和 global asm 中设置 GDT,但是当我尝试加载 GDT 时,它似乎出现了三重故障。
根据 qemu 日志,它发生在mov ds, ax
指令中。我遵循了 osdev.org 的指令,我很确定我的程序集是完全有效的。
我也一直在尝试更改并尝试一些随机的 GDTEntries 以查看它们是否有效,但这里没有运气。
c - 启用分页导致三重故障(已解决)
如果这对将来的某人有帮助:
- 检查全局描述符表是否工作
- 检查页表条目结构的元素是否正确排序
这段代码对我有用:
gdt.s
分页.c
paging_asm.s
我的错误是我的结构在低位中有地址字段,在高位中有标志字段。这是一些非常奇怪的行为的原因。最后它没有在mov cr0, eax崩溃,而是在mov esp, ebp崩溃。感谢每一个评论的人。
segment - 要求澄清“段寄存器继续指向与实地址模式相同的线性地址”
问题是关于在英特尔 i386 上从实模式切换到保护模式时代码段选择器的持久有效性。切换代码如下(摘自bootasm.S
xv6 x86版本):
GDT 布局如下:
在执行第 9144 行之后,处理器切换到保护模式,其中仅启用段内存管理(但尚未启用分页)。我的理解是,既然已经启用了segment MM,那么接下来的指令的取指应该符合segment MM的规则。然而,此时(就在第 9153 行之前),代码选择器保持为 0,在我的理解中,这意味着代码段应该选择了 GDT 中的第零个描述符,即为空。但是我的问题自然而然地出现了,这样的空描述符如何加载假定的ljmp
指令?我试图通过谷歌搜索来回答我的问题,一份文件给出了如下解释:http ://www.logix.cz/michal/doc/i386/chp10-03.htm#10-03
段寄存器继续指向与实地址模式相同的线性地址
这句话似乎回答了我的问题:如果段寄存器继续指向同一个线性地址,那么下一条指令应该和实模式下一样,即ljmp
. 但是我马上有一系列新问题:为什么段选择器可以“继续指向相同的线性地址”?处理器不是改成保护模式了吗?0 in 的值不是%cs
指向第零个描述符,而不是第一个(在第 9184 行设置),它是假定的要获取ljmp
指令的描述符吗?x86 CPU 是如何神奇地知道ljmp
它应该执行的下一条指令是什么?任何描述这种魔法的手册中的描述在哪里?我试图说服自己ljmp
已在处理器的指令队列中预取,但同一网页的第二段告诉我预取的ljmp
(如果有的话)已失效,因此 CPU 应重新获取下一条指令。您能否解释一下“段寄存器如何继续指向与实地址模式相同的线性地址”?谢谢你。
PS,我正在使用的 CPU 与 intel i386 兼容。
assembly - Rust gnu-asm,实模式跳远
我正在尝试在 Rust 中编写一个引导加载程序,其中包含通过global_asm!("start.s")
. 这意味着我仅限于使用 GNU Asm。现在我想在加载 GDT 后从 16 位模式跳到保护模式。在 nasm 中,这jmp 0x08:mylabel
在 GNU Asm 中似乎不存在?
我也尝试过jmp far 0x08:protected_mode_setup
并jmp 0x08, protected_mode_setup
喜欢这里描述的,但没有成功。
重现该问题的最小来源:https ://github.com/Luis-Hebendanz/rust_asm_error
c++ - 在 64 位 UEFI 操作系统中实现用户模式和内核模式切换
我正在编写一个 64 位 UEFI 操作系统(GNU-EFI - Bootloader)。我想知道操作系统中的用户模式和内核模式,我必须在我的操作系统中实现用户模式和内核模式,我在互联网上找到了一些但它对我不起作用(我认为这是因为 64 位),那么我该怎么做呢?
我用这个:
OSDEV- Ring3
但是当我在我的 gdt 中实现它时,我的内核挂掉了!
我的内核代码:
评论不是我的普通代码,这些是从 OSDEV 复制的 - 这些挂在内核中,所以我评论了那些。
gdt.h
gdt.cpp
gdt.asm
如何在 64 位 UEFI 操作系统中进入 Ring3,然后如何将用户模式切换到内核模式?
assembly - 为什么在 xv6 中有 sizeof(gdt)-1 在 gdtdesc
在bootasm.S
这用于
gdtdesc 的第一个字不应该是 gdt 的大小(以字节为单位)吗?在这种情况下,它是3*8=24
,它等于gdtdesc - gdt
。为什么gdtdesc - gdt - 1
在这里?
c - GDT 段重新加载失败
我正在用 c 为 x86 平台编写一个小内核,但是我在加载 gdt 和重新加载段选择器时遇到了麻烦。
我正在使用 bochs 来测试我的内核。
问题是,当我加载 GDT 但不重新加载段选择器时,我可以停止我的程序,输入info gdt
并获得一个不错的结果: 当我不加载我的 GDT 时:
当我加载我的 GDT 时:
所以看来我的 GDT 已正确加载。
现在是棘手的部分。当我想重新加载段选择器时,我遇到了这个错误:
有了这个,当我info gdt
再次输入时,它给了我一个非常大的数组,甚至不适合我的终端回滚容量。这是最后几行:
它说我想访问我的 GDT 之外的数据。
这是我到目前为止编写的代码:
如果你们知道这是怎么回事。