summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2021-07-21 21:31:52 +0200
committerdzwdz2021-07-21 21:31:52 +0200
commit36089d20ca1f7c57f36c4172759a5084bdf87a3a (patch)
treeac31e75f3379e0dcad6cb98f23cba6cbce236380 /src
parent46fb83d6eb44b5d52520783570dc40b7ef25260b (diff)
barebones syscall
Diffstat (limited to 'src')
-rw-r--r--src/init/linker.ld1
-rw-r--r--src/init/main.c4
-rw-r--r--src/init/syscall.s9
-rw-r--r--src/kernel/arch/generic.h1
-rw-r--r--src/kernel/arch/i386/sysenter.s28
-rw-r--r--src/kernel/syscalls.c6
6 files changed, 49 insertions, 0 deletions
diff --git a/src/init/linker.ld b/src/init/linker.ld
index 9f3f4b5..a59308d 100644
--- a/src/init/linker.ld
+++ b/src/init/linker.ld
@@ -6,6 +6,7 @@ SECTIONS
. = 2M;
.text BLOCK(4K) : ALIGN(4K)
{
+ *(.text.startup)
*(.text)
}
.rodata BLOCK(4K) : ALIGN(4K)
diff --git a/src/init/main.c b/src/init/main.c
index ce1600c..cb3fa1d 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -1,6 +1,10 @@
#include <stdint.h>
+void _syscall();
+
int main() {
+ _syscall();
+
// change the colors of VGA text
// doesn't require a lot of code, but still shows that it's working
uint8_t *vga = (void*) 0xB8000;
diff --git a/src/init/syscall.s b/src/init/syscall.s
new file mode 100644
index 0000000..ebd9d0e
--- /dev/null
+++ b/src/init/syscall.s
@@ -0,0 +1,9 @@
+.section .text
+.global _syscall
+.type _syscall, @function
+_syscall:
+ mov %esp, %ecx
+ mov $_syscall_ret, %edx
+ sysenter
+_syscall_ret:
+ ret
diff --git a/src/kernel/arch/generic.h b/src/kernel/arch/generic.h
index a535514..08f26a7 100644
--- a/src/kernel/arch/generic.h
+++ b/src/kernel/arch/generic.h
@@ -17,6 +17,7 @@ void halt_cpu();
// src/arch/i386/sysenter.s
void sysexit(void (*fun)(), void *stack_top);
void sysenter_setup();
+void syscall_handler();
// all of those can allocate memory
struct pagedir *pagedir_new();
diff --git a/src/kernel/arch/i386/sysenter.s b/src/kernel/arch/i386/sysenter.s
index 0cfeb10..3fcd4c3 100644
--- a/src/kernel/arch/i386/sysenter.s
+++ b/src/kernel/arch/i386/sysenter.s
@@ -4,6 +4,8 @@
.set SEG_r3data, 4
.set IA32_SYSENTER_CS, 0x174
+.set IA32_SYSENTER_ESP, 0x175
+.set IA32_SYSENTER_EIP, 0x176
.section .text
.global sysexit
@@ -30,7 +32,33 @@ sysexit:
.type sysenter_setup, @function
sysenter_setup:
xor %edx, %edx
+
mov $(SEG_r0code << 3), %eax
mov $IA32_SYSENTER_CS, %ecx
wrmsr
+
+ mov $IA32_SYSENTER_ESP, %ecx
+ mov $_bss_end, %eax
+ wrmsr
+
+ mov $IA32_SYSENTER_EIP, %ecx
+ mov $sysenter_handler, %eax
+ wrmsr
+
ret
+
+sysenter_handler:
+ pushal
+
+ mov %cr0, %eax
+ and $0x7FFFFFFF, %eax // disable paging
+ mov %eax, %cr0
+
+ call syscall_handler
+
+ mov %cr0, %eax
+ or $0x80000000, %eax // enable paging
+ mov %eax, %cr0
+
+ popal
+ sysexit
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
new file mode 100644
index 0000000..25b8eb5
--- /dev/null
+++ b/src/kernel/syscalls.c
@@ -0,0 +1,6 @@
+#include <kernel/arch/generic.h>
+#include <kernel/panic.h>
+
+void syscall_handler() {
+ log_const("in a syscall!");
+}