将SS寄存器设置为bootloader中的0时,CPU重置(CPU 0)和三重故障
我正在尝试创建一个自定义操作系统(用于教育目的),我也为此创建了引导加载程序(Multiboot 2)。我正在尝试创建一个64位系统。
输入长模式后,我想通过使用0
加载所有数据段寄存器来“清理”。为此,我有以下代码:
long_mode_start:
mov ax, 0
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
ret
执行时刻mov ss,ax
,启动过程失败并且CPU已重置(最终导致了三重失败)。我正在使用QEMU模拟X86_64系统。在日志中,我会得到以下(我不确定如何完全解释日志):cpu reset(CPU 0)
。有关完整日志文件,请参见: https://github.com/wjjjjjongkind/tictactos/tictactos/tictactos/blob/blob/blob/develovelvelvemplove/log/log。 txt
我真的不确定我在代码中做错了什么。可以在此处找到设置较长模式和分页的完整组件文件:“ noreflow noreferrer”> https://github.com/wjjjongkind/tictactos/blob/develop/bootloader/boot.asm.asm
注意:如果涉及汇编语言,我非常是初学者&操作系统编程,因此我在代码中的评论可能不是100%准确的。
是什么导致CPU设置SS寄存器值时重置?
I am attempting to create a custom operating system (for educational purposes) for which I am also creating the bootloader (multiboot 2). I am attempting to create a 64-bit system.
After entering long mode, I want to "clean up" by loading all data segment registers with 0
. To do this, I have the following code:
long_mode_start:
mov ax, 0
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
ret
The moment mov ss, ax
is executed, the boot process fails and the CPU is reset (eventually leading up to a triple-fault). I'm using QEMU to emulate a X86_64 system. In the logs I get the following (I'm not sure how to fully interpret the logs): CPU Reset (CPU 0)
. For full log file, see:
https://github.com/WJJongkind/TicTacTOS/blob/develop/log.txt
I'm really not sure what I am doing wrong in my code. The full assembly file that sets up long mode and paging can be found here: https://github.com/WJJongkind/TicTacTOS/blob/develop/Bootloader/boot.asm
Note: I'm very much a beginner if it comes to assembly language & OS programming, so my comments in the code are probably not 100% accurate.
What causes the CPU to reset when setting the SS register value?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
校正,此答案基于对手册的误读:它包含的伪代码仅适用于32位保护模式。请参阅链接的重复迈克尔·皮奇(Michael Petch)的答案更详细地涵盖了这一点。
如果以32位保护模式执行该代码,则该代码将错误,但在CPL = 0时不会以64位长模式执行。或者,如果您要在切换到长模式之前以32位模式执行此代码对于其他部分。
旧的答案,轻轻编辑以指出它正在回答错误的问题:64位用户空间或32位模式。
DS
和ES
可以是NULL选择器(0
),以64位模式(与32位PM不同),也可以是> fs
和gs
。这就是Linux所做的,因为我可以使用GDB确认用户空间过程。
但是 SS出于某种原因需要选择一个有效的描述符,也许将堆栈地址宽度设置为64,尽管当CS选择64位代码段时,这是唯一的有效选择。 (校正,NO,64位模式允许SS = 0当Cpl< 3,只要CPL == rpl。)
感到惊讶的QEMU不会为您提供更多关于触发重置的例外的日志。我认为Bochs可以做到这一点,至少如果您单一踏上了内置的调试器。
根据英特尔的手册(在受保护模式下移动到sreg的操作部分)假设您没有IDT条目,则应是
#GP(0)
,然后是双反故障。如果您有一个模拟器向您显示异常详细信息,那很好。有关在64位模式下可能导致例外的详细信息,请参见同一手动输入的后面部分: https://www.felixcloutier.com/x86/mov#64-bit-mode-exceptions
Correction, this answer was based on a misreading of the manual: the pseudo-code it contains only applies to 32-bit protected mode. See the linked duplicate where Michael Petch's answer covers this in much more detail.
This code will fault if executed in 32-bit protected mode, but not in 64-bit long mode at CPL=0. Or if you are executing this code in 32-bit mode before switching to long mode, then yes you should expect it to fault on the spot for SS, unlike later when a load or store tries to use it for the other segments.
Old answer, lightly edited to point out that it's answering the wrong question: 64-bit user space or 32-bit mode.
ds
andes
can be the null selector (0
) in 64-bit mode (unlike 32-bit PM), as canfs
andgs
.That's what Linux does, as I can confirm with GDB for a user-space process.
But SS needs to select a valid descriptor for some reason, maybe to set the stack address width to 64, even though that's the only valid choice when CS selects a 64-bit code segment. (Correction, no, 64-bit mode allows SS=0 when CPL<3, as long as CPL==RPL.)
Surprised QEMU doesn't give you more of a log about what exception triggered the reset. I think Bochs could do that, at least if you single-stepped with its built-in debugger.
According to Intel's manual (Operation section for mov-to-Sreg in protected mode) it should be a
#GP(0)
, and then double-fault and then triple-fault, assuming you don't have IDT entries for those. Which is fine if you have a simulator that shows you exception details.For details on what can cause exceptions in 64-bit mode, see that later section of the same manual entry: https://www.felixcloutier.com/x86/mov#64-bit-mode-exceptions