我正在编写一个小内核来了解有关操作ystems的更多信息。 我最近决定开始实施用户模式,只是为了好玩。 为此,我遵循了以下指南:https://blog.llandsmeer.com/tech/2019/07/21/uefi-x64-userland.html 不幸的是,在过去的 24 小时内,我只看到了 gpfault、页面错误和重启。我尝试了又试,遵循许多不同的指南,从OSDev Wiki到随机博客,并检查了x86-64的AMD程序员手册第2卷,但什么都没有。似乎,sysretq 不是跳转到user_main
,而是重新跳转到kernel_main
(事实上,运行该函数两次会导致相同的奇怪页面错误 - 随机文本输出应该只在 [启动时] 中断一次)。如果我使用 sysret 或 o64 sysret 而不是 sysretq,QEMU 会直接重置。
我真的不知道如何处理这个问题。
链接和参考:
您可以在以下位置找到我的内核: https://github.com/Alessandro-Salerno/SalernOS-Kernel 进入用户模式的代码可以在src/User/Userspace/userspace.asm
找到,SCE(系统呼叫扩展)代码可以在src/Syscall/sce.asm
找到。入口点在src/kernel.c
我在kernel.c
中使用的代码跳转到用户空间。
...
#include "User/Userspace/userspace.h"
uint64_t user_stack[1024];
void user_main() {
while (TRUE);
}
void kernel_main(boot_t* __bootinfo) {
// init code (Up to line 74 in src/kernel.c)
kernel_userspace_enter(user_main, &user_stack[500]);
}
第 N 次编辑:我在 QEMU 中使用log cpu_reset
在系统崩溃时获取一些信息:
CPU Reset (CPU 0)
RAX=0000000000006297 RBX=000000000ff1c2b0 RCX=0000000000002d60 RDX=00000000ff000000
RSI=0000000000009ff8 RDI=0000000000002d60 RBP=0000000000000000 RSP=0000000000009ff8
R8 =0000000000000000 R9 =000000000000a1f0 R10=cccccccccccccccd R11=0000000000000202
R12=000000000ff1c176 R13=000000000ff1c177 R14=0000000000006296 R15=0000000000000000
RIP=0000000000002d60 RFL=00000202 [-------] CPL=3 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000fff 00a09300 DPL=0 DS [-WA]
CS =002b 0000000000000000 ffffffff 00a0fb00 DPL=3 CS64 [-RA]
SS =0023 0000000000000000 ffffffff 00c0f300 DPL=3 DS [-WA]
DS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS [-WA]
FS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS [-WA]
GS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0030 000000000000a000 00068fff 00a08900 DPL=0 TSS64-avl
GDT= 0000000000005000 00000fff
IDT= 000000000021f000 00000fff
CR0=80010033 CR2=fffffffffffffff8 CR3=0000000000100000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=000000000ff1c150 CCO=EFLAGS
EFER=0000000000000d01
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=ff000000ff000000 ff000000ff000000 XMM01=0000000000000000 3ff0000000000000
XMM02=0000000000000000 0000000000000000 XMM03=0015001600400003 0038004000000000
XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000
XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000
XMM08=0000000000000000 0000000000000000 XMM09=0000000000000000 0000000000000000
XMM10=0000000000000000 0000000000000000 XMM11=0000000000000000 0000000000000000
XMM12=0000000000000000 0000000000000000 XMM13=0000000000000000 0000000000000000
XMM14=0000000000000000 0000000000000000 XMM15=0000000000000000 0000000000000000
我解决了。 在Letast,我想是的。
请记住在设置 GDT 时获取 GDT 实例的大小,而不是 GDT 类型。如果我找到其他东西,我会更新这个答案。