WIP: GDT is now right. Have to debug iretq GPF

This commit is contained in:
Adrien Bourmault 2021-02-28 14:06:29 +01:00
parent b57ed861ff
commit 7621babbd1
Signed by: neox
GPG Key ID: 6EB408FE0ACEC664
6 changed files with 61 additions and 46 deletions

View File

@ -70,11 +70,6 @@ extern void KeSendEOItoPIC(uchar isr);
extern void KeEnableNMI(void);
extern void KeDisableNMI(void);
//
// System Call
//
extern error_t KeSyscall(ulong code);
//
// Restore IRQ flag to its state before KePauseIRQs
//

View File

@ -31,6 +31,8 @@
//----------------------------------------------------------------------------//
extern error_t KeSyscall(ulong code);
extern void KeJumpToUserspace(ulong args, void *entryPoint, void *stackAddr);
error_t _KeSyscallHandler(ulong code);

View File

@ -26,7 +26,6 @@
global divideByZero
global KeActivateSSE
global KeSyscall
%include "kaleid/kernel/ke/cpuf.inc"
@ -50,10 +49,3 @@ KeActivateSSE:
mov cr4, rax
pop rax
ret
;;
;;
;;
KeSyscall:
int 0x80
ret

View File

@ -27,24 +27,35 @@
%include "kaleid/kernel/ke/cpuf.inc"
global KeJumpToUserspace
global KeSyscall
extern KernLog
;;
;; To get ring3 code running
;;
KeJumpToUserspace:
; rdi = user args
; rsi = entry point in user space
; rdx = user space stack
mov rax, 0x10 ; Selector 0x10 (User Data) + RPL 3
mov ds, ax
mov es, ax
mov rax, 0x18 ; Selector 0x18 (User Data) + RPL 3
mov ds, rax
mov es, rax
; Build a fake iret frame
push rax ; Selector 0x10 (User Data) + RPL 3
push rax ; Selector 0x18 (User Data) + RPL 3
push rdx ; User space stack
push 0x202 ; rflags = interrupt enable + reserved bit
push 0x10 ; Selector 0x10 (User Code) + RPL 3
push QWORD 0x202 ; rflags = interrupt enable + reserved bit
push QWORD 0x20 ; Selector 0x20 (User Code) + RPL 3
push rsi ; Entry point in user space
xor rax, rax
iretq
;;
;; Syscall trigger
;;
KeSyscall:
int 0x80
ret

View File

@ -27,13 +27,13 @@
#include <init/boot.h>
GdtPtr_t gdtPtr;
GdtEntry_t gdt[5] __attribute__((__aligned__(KPAGESIZE)));
GdtEntry_t gdt[7] __attribute__((__aligned__(KPAGESIZE)));
TssDescriptor_t tssDesc __attribute__((__aligned__(KPAGESIZE)));
Tss_t tss __attribute__((__aligned__(KPAGESIZE)));
void MmInitGdt(void)
{
ushort tssOffset = (ushort)((ulong)(&gdt[3]) - (ulong)(&gdt[0]));
ushort tssOffset = (ushort)((ulong)(&gdt[5]) - (ulong)(&gdt[0]));
gdtPtr.base = (ulong)&gdt[0];
gdtPtr.limit = sizeof(gdt) - 1;
@ -43,14 +43,24 @@ void MmInitGdt(void)
memzero((void *)&tss, sizeof(tss));
// Kernel codeseg
gdt[1].lowLimit = 0xFFFF;
gdt[1].access = 0x98;
gdt[1].lowLimit = 0x0;
gdt[1].access = 0x9A;
gdt[1].flags = 0x20;
// Kernel dataseg
gdt[2].lowLimit = 0x0;
gdt[2].access = 0x92;
gdt[2].flags = 0x00;
// User dataseg
gdt[3].lowLimit = 0x0;
gdt[3].access = 0xF2;
gdt[3].flags = 0x20;
// User codeseg
gdt[2].lowLimit = 0xFFFF;
gdt[2].access = 0xF8;
gdt[2].flags = 0x20;
gdt[4].lowLimit = 0x0;
gdt[4].access = 0xFA;
gdt[4].flags = 0x20;
tssDesc.access = 0x89;
tssDesc.flags = 0x40;
@ -66,22 +76,19 @@ void MmInitGdt(void)
tss.rsp0 = (ulong)memalign(4*MB, 4*KB) + 4*MB; // Another Stack
tss.iomap_base = sizeof(tss);
DebugLog("ISR Stacks initialized : Rescue %p, Normal %p, %p\n",
tss.ist1,
tss.ist2,
tss.ist3);
memmove(&gdt[3], &tssDesc, sizeof(TssDescriptor_t));
memmove(&gdt[5], &tssDesc, sizeof(TssDescriptor_t));
DebugLog("GDT & TSS initialized\n");
DebugLog("gdt[0] : %#b\n", gdt[0]);
DebugLog("gdt[1] : %#b\n", gdt[1]);
DebugLog("gdt[2] : %#b\n", gdt[2]);
DebugLog("tss : %#b\n", gdt[3]);
DebugLog("ist1 : %#p\n", tss.ist1);
DebugLog("ist2 : %#p\n", tss.ist2);
DebugLog("ist3 : %#p\n", tss.ist3);
DebugLog("rsp0 : %#p\n", tss.ist1);
DebugLog("Null descriptor : %#p\n", &gdt[0]);
DebugLog("Kernel code descriptor : %#p\n", &gdt[1]);
DebugLog("Kernel data descriptor : %#p\n", &gdt[2]);
DebugLog("User data descriptor : %#p\n", &gdt[3]);
DebugLog("User code descriptor : %#p\n", &gdt[4]);
DebugLog("tss : %#p\n", &gdt[5]);
DebugLog("ist1 : %#p\n", tss.ist1);
DebugLog("ist2 : %#p\n", tss.ist2);
DebugLog("ist3 : %#p\n", tss.ist3);
DebugLog("rsp0 : %#p\n", tss.ist1);
MmLoadGdt(&gdtPtr, tssOffset);
}

View File

@ -331,8 +331,8 @@ error_t CmdSyscallTest(int argc, char **argv, char *cmdline)
error_t CmdRing3Test(int argc, char **argv, char *cmdline)
{
size_t size = 50*MB;
void *entryPoint = (void*)USERSPACE + 51*KB;
size_t size = 1*KB;
void *entryPoint = (void*)USERSPACE;
ulong flags = PRESENT | READWRITE | USERMODE;
KernLog("Allocating %u o...\n", size);
@ -348,8 +348,8 @@ error_t CmdRing3Test(int argc, char **argv, char *cmdline)
return ENOMEM;
}
size = 50*KB;
void *stackAddr = (void*)USERSPACE;
size = 1*KB;
void *stackAddr = (void*)USERSPACE + 4*KPAGESIZE;
flags = PRESENT | READWRITE | USERMODE;
KernLog("Allocating %u o...\n", size);
@ -365,6 +365,14 @@ error_t CmdRing3Test(int argc, char **argv, char *cmdline)
return ENOMEM;
}
KernLog("Entrypoint : %p, stack address : %p\n", entryPoint, stackAddr);
uchar *code = (uchar*)entryPoint;
/* *code = 0x90; // nop*/
/* *(code+1) = 0xEB; // jmp*/
/* *(code+2) = 0xFD; // short 0x0*/
KeJumpToUserspace(0, entryPoint, stackAddr);
return EOK;