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 subdirs=boot
OBJPATH=$(OBJDIR)/arch/${TARGET}/ OBJPATH=$(OBJDIR)/arch/${TARGET}/
export export
@@ -19,3 +19,7 @@ context.o: context.asm
nasm -f elf64 -o $@ $< nasm -f elf64 -o $@ $<
mkdir -p $(OBJPATH) mkdir -p $(OBJPATH)
cp $@ $(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 global arch_switchcontext
arch_switchcontext: arch_switchcontext:
mov rsp,rdi mov rsp,rdi
add rsp, 8 ; cr2 add rsp, 24 ; cr2 gs fs
pop rax
mov gs,rax mov rbx,es
pop rax pop rax
mov fs,rax cmp rax,rbx
pop rax jne .segswap
add rsp,8 ; ds
jmp .genreg
.segswap:
swapgs
mov es,rax mov es,rax
pop rax pop rax
mov ds,rax mov ds,rax
.genreg:
pop rax pop rax
pop rbx pop rbx
pop rcx pop rcx
@@ -27,6 +33,4 @@ arch_switchcontext:
pop rbp pop rbp
add rsp,8 ; remove error code add rsp,8 ; remove error code
swapgs
iretq iretq
+3 -1
View File
@@ -8,6 +8,8 @@
// syscall, sse, etc // syscall, sse, etc
// for the current cpu // for the current cpu
extern void asm_syscall_entry();
void cpu_state_init(){ void cpu_state_init(){
// syscall // syscall
@@ -28,7 +30,7 @@ void cpu_state_init(){
star |= (uint64_t)0x28 << 32; star |= (uint64_t)0x28 << 32;
wrmsr(MSR_STAR, star); 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_CSTAR, 0); // no compat mode syscall handler
wrmsr(MSR_FMASK, 0x200); // disable interrupts on syscall 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.offset = &arch_getcls()->gdt;
gdtr.size = sizeof(gdt_t) - 1; gdtr.size = sizeof(gdt_t) - 1;
asm("lgdt (%%rax)" : : "a"(&gdtr) : "memory"); asm volatile("lgdt (%%rax)" : : "a"(&gdtr) : "memory");
asm("ltr %%ax" : : "a"(0x48)); asm volatile("ltr %%ax" : : "a"(0x48));
asm volatile("swapgs;mov $0, %%ax;mov %%ax, %%gs;mov %%ax, %%fs;swapgs;" : : : "ax");
} }
void gdt_init(){ void gdt_init(){
+1
View File
@@ -13,6 +13,7 @@
// this will be pointed to by GS and will contain per cpu info // this will be pointed to by GS and will contain per cpu info
typedef struct{ typedef struct{
void* kstack;
gdt_t gdt; gdt_t gdt;
ist_t ist; ist_t ist;
int lapicid; int lapicid;
+6 -1
View File
@@ -4,10 +4,15 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
typedef struct{
uint64_t gsbase, fsbase;
} arch_extraregs;
typedef struct{ 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; 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; } 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_setupkernel(arch_regs* regs, void* ip, void* stack, bool interrupts);
void arch_regs_setupuser(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 mov rax, gs
push rax push rax
cmp rax,0x30 cmp rax,0x43
jmp .noswapgs jmp .noswapgs
swapgs swapgs
.noswapgs: .noswapgs:
@@ -42,22 +42,18 @@ section .text
%macro popregs 0 %macro popregs 0
add rsp, 8 ; cr2 add rsp, 24 ; cr2 gs fs
pop rax pop rax
cmp rax,0x30 cmp rax,0x43
je .dontpopsegs je .dontpopsegs
mov gs,rax
pop rax
mov fs,rax
pop rax
mov es,rax mov es,rax
pop rax pop rax
mov ds,rax mov ds,rax
swapgs swapgs
jmp .poprest jmp .poprest
.dontpopsegs: .dontpopsegs:
add rsp,24 add rsp,8 ; ds
.poprest: .poprest:
pop rax pop rax
+1
View File
@@ -5,4 +5,5 @@
void arch_setkernelstack(void* stack){ void arch_setkernelstack(void* stack){
arch_getcls()->ist.rsp0 = (uint64_t)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/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){ void arch_regs_setupkernel(arch_regs* regs, void* ip, void* stack, bool interrupts){
regs->rip = ip; 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 _thread_t* prev;
struct _proc_t* proc; struct _proc_t* proc;
arch_regs* regs; arch_regs* regs;
arch_extraregs extraregs;
state_t state; state_t state;
void* kernelstack; void* kernelstack;
void* kernelstackbase; 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)) objects := $(patsubst %.c,%.o,$(wildcard *.c))
subdirs := mm sched subdirs := mm sched syscalls
OBJPATH=$(OBJDIR) OBJPATH=$(OBJDIR)
export export
+6 -2
View File
@@ -162,9 +162,9 @@ void sched_timerhook(arch_regs* regs){
spinlock_release(&running.lock); spinlock_release(&running.lock);
memcpy(current->regs, regs, sizeof(arch_regs)); memcpy(current->regs, regs, sizeof(arch_regs));
arch_regs_saveextra(&current->extraregs);
spinlock_acquire(&currentqueue->lock); spinlock_acquire(&currentqueue->lock);
@@ -198,6 +198,8 @@ static void switch_thread(thread_t* thread){
arch_setkernelstack(thread->kernelstack); arch_setkernelstack(thread->kernelstack);
arch_regs_setupextra(&thread->extraregs);
arch_switchcontext(thread->regs); arch_switchcontext(thread->regs);
__builtin_unreachable(); __builtin_unreachable();
@@ -291,6 +293,8 @@ void sched_runinit(){
printf("ELF load error: %s\n", strerror(ret)); printf("ELF load error: %s\n", strerror(ret));
_panic("Could not load init", 0); _panic("Could not load init", 0);
} }
thread->extraregs.gsbase = 0xFFFFFFFFDEADBEEF;
switch_thread(thread); 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;
}