system calls

This commit is contained in:
Matheus
2022-08-15 21:52:57 -03:00
parent 21e6a0ad1a
commit 432e85b837
17 changed files with 187 additions and 26 deletions
BIN
View File
Binary file not shown.
+5 -1
View File
@@ -1,4 +1,4 @@
objects := $(patsubst %.c,%.o,$(wildcard *.c)) israsm.o context.o
objects := $(patsubst %.c,%.o,$(wildcard *.c)) israsm.o context.o syscall.o
subdirs=boot
OBJPATH=$(OBJDIR)/arch/${TARGET}/
export
@@ -19,3 +19,7 @@ context.o: context.asm
nasm -f elf64 -o $@ $<
mkdir -p $(OBJPATH)
cp $@ $(OBJPATH)/$@
syscall.o: syscall.asm
nasm -f elf64 -o $@ $<
mkdir -p $(OBJPATH)
cp $@ $(OBJPATH)/$@
+13 -9
View File
@@ -1,15 +1,21 @@
global arch_switchcontext
arch_switchcontext:
mov rsp,rdi
add rsp, 8 ; cr2
pop rax
mov gs,rax
pop rax
mov fs,rax
pop rax
add rsp, 24 ; cr2 gs fs
mov rbx,es
pop rax
cmp rax,rbx
jne .segswap
add rsp,8 ; ds
jmp .genreg
.segswap:
swapgs
mov es,rax
pop rax
pop rax
mov ds,rax
.genreg:
pop rax
pop rbx
pop rcx
@@ -27,6 +33,4 @@ arch_switchcontext:
pop rbp
add rsp,8 ; remove error code
swapgs
iretq
+3 -1
View File
@@ -8,6 +8,8 @@
// syscall, sse, etc
// for the current cpu
extern void asm_syscall_entry();
void cpu_state_init(){
// syscall
@@ -28,7 +30,7 @@ void cpu_state_init(){
star |= (uint64_t)0x28 << 32;
wrmsr(MSR_STAR, star);
wrmsr(MSR_LSTAR, 0xDEADBEEF); // FIXME add 64 bit handler here
wrmsr(MSR_LSTAR, asm_syscall_entry);
wrmsr(MSR_CSTAR, 0); // no compat mode syscall handler
wrmsr(MSR_FMASK, 0x200); // disable interrupts on syscall
}
+4 -2
View File
@@ -34,8 +34,10 @@ static void reloadgdtr(){
gdtr.offset = &arch_getcls()->gdt;
gdtr.size = sizeof(gdt_t) - 1;
asm("lgdt (%%rax)" : : "a"(&gdtr) : "memory");
asm("ltr %%ax" : : "a"(0x48));
asm volatile("lgdt (%%rax)" : : "a"(&gdtr) : "memory");
asm volatile("ltr %%ax" : : "a"(0x48));
asm volatile("swapgs;mov $0, %%ax;mov %%ax, %%gs;mov %%ax, %%fs;swapgs;" : : : "ax");
}
void gdt_init(){
+1
View File
@@ -13,6 +13,7 @@
// this will be pointed to by GS and will contain per cpu info
typedef struct{
void* kstack;
gdt_t gdt;
ist_t ist;
int lapicid;
+6 -1
View File
@@ -4,10 +4,15 @@
#include <stdint.h>
#include <stdbool.h>
typedef struct{
uint64_t gsbase, fsbase;
} arch_extraregs;
typedef struct{
uint64_t cr2,gs,fs,es,ds,rax,rbx,rcx,rdx,r8,r9,r10,r11,r12,r13,r14,r15,rdi,rsi,rbp,error,rip,cs,rflags,rsp,ss;
} arch_regs;
void arch_regs_saveextra(arch_extraregs* regs);
void arch_regs_setupextra(arch_extraregs* regs);
void arch_regs_setupkernel(arch_regs* regs, void* ip, void* stack, bool interrupts);
void arch_regs_setupuser(arch_regs* regs, void* ip, void* stack, bool interrupts);
+5 -9
View File
@@ -29,7 +29,7 @@ section .text
mov rax, gs
push rax
cmp rax,0x30
cmp rax,0x43
jmp .noswapgs
swapgs
.noswapgs:
@@ -42,22 +42,18 @@ section .text
%macro popregs 0
add rsp, 8 ; cr2
add rsp, 24 ; cr2 gs fs
pop rax
cmp rax,0x30
cmp rax,0x43
je .dontpopsegs
mov gs,rax
pop rax
mov fs,rax
pop rax
mov es,rax
pop rax
mov ds,rax
swapgs
jmp .poprest
.dontpopsegs:
add rsp,24
add rsp,8 ; ds
.poprest:
pop rax
+1
View File
@@ -5,4 +5,5 @@
void arch_setkernelstack(void* stack){
arch_getcls()->ist.rsp0 = (uint64_t)stack;
arch_getcls()->kstack = stack;
}
+13
View File
@@ -1,4 +1,17 @@
#include <arch/regs.h>
#include <arch/msr.h>
void arch_regs_saveextra(arch_extraregs* regs){
// user gs was swapped
regs->gsbase = rdmsr(MSR_KERNELGSBASE);
regs->fsbase = rdmsr(MSR_FSBASE);
}
void arch_regs_setupextra(arch_extraregs* regs){
// gs will be swapped later
wrmsr(MSR_KERNELGSBASE, regs->gsbase);
wrmsr(MSR_FSBASE, regs->fsbase);
}
void arch_regs_setupkernel(arch_regs* regs, void* ip, void* stack, bool interrupts){
regs->rip = ip;
+76
View File
@@ -0,0 +1,76 @@
section .rodata
extern syscall_libc_log
func_count equ 1
func_table:
dq syscall_libc_log
section .text
global asm_syscall_entry
; the registers for the system call are:
; RETURN:
; rax -> ret value
; rdx -> errno
; PARAM:
; rax -> func
; rdi, rsi, rdx, r10, r8, r9 -> parameters
; clobbers: rax, rdx, rcx, r11
asm_syscall_entry:
swapgs
xchg rsp, [gs:0] ; get new stack
push qword [gs:0] ; save old stack
mov [gs:0], rsp ; return back the kernel stack
add qword [gs:0], 8 ; fix it
push rcx ; old rip
push r11 ; old rflags
mov r11, 0x30 ; kernel data
mov ds, r11
mov es, r11
; save C scratch registers
; rax is not saved because it will be the return value
; rdx is not saved because it will be the errno value
push rdi
push rsi
push rcx
push r8
push r9
push r10
; system V C abi expects the third param to be in rcx
; but the param is in rdx because of the syscall instruction
mov rcx, rdx
call [func_table + rax * 8]
; now restore the scratch registers
pop r10
pop r9
pop r8
pop rcx
pop rsi
pop rdi
; restore entry state
mov r11, 0x40 ; user data
mov es,r11
mov ds,r11
pop r11
pop rcx
pop rsp
swapgs
o64 sysret
+1
View File
@@ -23,6 +23,7 @@ typedef struct _thread_t{
struct _thread_t* prev;
struct _proc_t* proc;
arch_regs* regs;
arch_extraregs extraregs;
state_t state;
void* kernelstack;
void* kernelstackbase;
+11
View File
@@ -0,0 +1,11 @@
#ifndef _SYSCALLS_H_INCLUDE
#define _SYSCALLS_H_INCLUDE
typedef struct {
long ret;
long errno;
} syscallret;
syscallret syscall_libc_log(char* str);
#endif
+1 -1
View File
@@ -1,5 +1,5 @@
objects := $(patsubst %.c,%.o,$(wildcard *.c))
subdirs := mm sched
subdirs := mm sched syscalls
OBJPATH=$(OBJDIR)
export
+6 -2
View File
@@ -162,9 +162,9 @@ void sched_timerhook(arch_regs* regs){
spinlock_release(&running.lock);
memcpy(current->regs, regs, sizeof(arch_regs));
arch_regs_saveextra(&current->extraregs);
spinlock_acquire(&currentqueue->lock);
@@ -198,6 +198,8 @@ static void switch_thread(thread_t* thread){
arch_setkernelstack(thread->kernelstack);
arch_regs_setupextra(&thread->extraregs);
arch_switchcontext(thread->regs);
__builtin_unreachable();
@@ -291,6 +293,8 @@ void sched_runinit(){
printf("ELF load error: %s\n", strerror(ret));
_panic("Could not load init", 0);
}
thread->extraregs.gsbase = 0xFFFFFFFFDEADBEEF;
switch_thread(thread);
+12
View File
@@ -0,0 +1,12 @@
objects := $(patsubst %.c,%.o,$(wildcard *.c))
subdirs :=
OBJPATH=$(OBJDIR)
export
all: $(subdirs) $(objects)
for subdir in $(subdirs) ; do $(MAKE) -C $${subdir} ; done
%.o: %.c
$(CC) $(CFLAGS) -o $@ $<
mkdir -p $(OBJPATH)
cp $@ $(OBJPATH)/$@
+29
View File
@@ -0,0 +1,29 @@
#include <kernel/syscalls.h>
#include <kernel/alloc.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
syscallret syscall_libc_log(char* str){
syscallret ret;
char* buf = alloc(strlen(str) + 1);
if(!buf){
ret.errno = ENOMEM;
ret.ret = -1;
return ret;
}
strcpy(buf, str);
printf("%s", str);
ret.errno = 0;
ret.ret = 0;
free(buf);
return ret;
}