From 8a6e24bcbc040e3bce26cf30d046d6a6a4e54d24 Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Thu, 16 Jan 2014 21:58:47 +0100 Subject: [PATCH] Prepare system calls --- kernel/Makefile | 2 +- kernel/include/interrupts.hpp | 14 ++++ kernel/include/syscalls.hpp | 26 ++++++ kernel/include/system_calls.hpp | 13 +++ kernel/src/interrupts.cpp | 22 ++++- kernel/src/syscalls.s | 137 ++++++++++++++++++++++++++++++++ kernel/src/system_calls.cpp | 0 7 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 kernel/include/syscalls.hpp create mode 100644 kernel/include/system_calls.hpp create mode 100644 kernel/src/syscalls.s create mode 100644 kernel/src/system_calls.cpp diff --git a/kernel/Makefile b/kernel/Makefile index c9c25aed..c94ea4f8 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -13,7 +13,7 @@ KERNEL_D_FILES=$(KERNEL_CPP_FILES:%.cpp=%.cpp.d) KERNEL_D_STL_FILES=$(KERNEL_CPP_STL_FILES:%.cpp=%.cpp.d) #TODO Generate also the o files coming from s files automatically, ignoring crti and crtn -KERNEL_O_FILES=boot_16_64.o boot_32_64.o $(KERNEL_CPP_FILES:%.cpp=%.cpp.o) $(KERNEL_CPP_STL_FILES:%.cpp=%.cpp.o) isrs.s.o irqs.s.o arch.s.o +KERNEL_O_FILES=boot_16_64.o boot_32_64.o $(KERNEL_CPP_FILES:%.cpp=%.cpp.o) $(KERNEL_CPP_STL_FILES:%.cpp=%.cpp.o) isrs.s.o irqs.s.o arch.s.o syscalls.s.o CRTBEGIN_OBJ:=$(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o) CRTEND_OBJ:=$(shell $(CC) $(CFLAGS) -print-file-name=crtend.o) diff --git a/kernel/include/interrupts.hpp b/kernel/include/interrupts.hpp index 55b86a9f..96a80dec 100644 --- a/kernel/include/interrupts.hpp +++ b/kernel/include/interrupts.hpp @@ -12,6 +12,9 @@ namespace interrupt { +constexpr const size_t SYSCALL_FIRST = 50; +constexpr const size_t SYSCALL_MAX = 10; + struct fault_regs { uint64_t error_no; uint64_t error_code; @@ -22,9 +25,20 @@ struct fault_regs { uint64_t ss; } __attribute__((packed)); +struct syscall_regs { + uint64_t rax; + uint64_t rbx; + uint64_t rcx; + uint64_t rdx; + uint64_t rsi; + uint64_t rdi; +} __attribute__((packed)); + void setup_interrupts(); void register_irq_handler(size_t irq, void (*handler)()); +void register_syscall_handler(size_t irq, void (*handler)(const syscall_regs&)); + } //end of interrupt namespace diff --git a/kernel/include/syscalls.hpp b/kernel/include/syscalls.hpp new file mode 100644 index 00000000..c0f27177 --- /dev/null +++ b/kernel/include/syscalls.hpp @@ -0,0 +1,26 @@ +//======================================================================= +// Copyright Baptiste Wicht 2013-2014. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef SYSCALLS_H +#define SYSCALLS_H + +extern "C" { + +void _syscall0(); +void _syscall1(); +void _syscall2(); +void _syscall3(); +void _syscall4(); +void _syscall5(); +void _syscall6(); +void _syscall7(); +void _syscall8(); +void _syscall9(); + +} //end of extern "C" + +#endif diff --git a/kernel/include/system_calls.hpp b/kernel/include/system_calls.hpp new file mode 100644 index 00000000..70cd0640 --- /dev/null +++ b/kernel/include/system_calls.hpp @@ -0,0 +1,13 @@ +//======================================================================= +// Copyright Baptiste Wicht 2013-2014. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef ATA_H +#define ATA_H + +void system_call_entry(); + +#endif diff --git a/kernel/src/interrupts.cpp b/kernel/src/interrupts.cpp index 6c9a1d90..4ab82ec9 100644 --- a/kernel/src/interrupts.cpp +++ b/kernel/src/interrupts.cpp @@ -12,6 +12,7 @@ #include "isrs.hpp" #include "irqs.hpp" +#include "syscalls.hpp" #include "stl/types.hpp" @@ -151,6 +152,20 @@ void install_irqs(){ idt_set_gate(47, _irq15, gdt::LONG_SELECTOR, 0x8E); } +void install_syscalls(){ + idt_set_gate(interrupt::SYSCALL_FIRST, _syscall0, gdt::LONG_SELECTOR, 0x8E); + idt_set_gate(interrupt::SYSCALL_FIRST+1, _syscall1, gdt::LONG_SELECTOR, 0x8E); + idt_set_gate(interrupt::SYSCALL_FIRST+2, _syscall2, gdt::LONG_SELECTOR, 0x8E); + idt_set_gate(interrupt::SYSCALL_FIRST+3, _syscall3, gdt::LONG_SELECTOR, 0x8E); + idt_set_gate(interrupt::SYSCALL_FIRST+4, _syscall4, gdt::LONG_SELECTOR, 0x8E); + idt_set_gate(interrupt::SYSCALL_FIRST+5, _syscall5, gdt::LONG_SELECTOR, 0x8E); + idt_set_gate(interrupt::SYSCALL_FIRST+6, _syscall6, gdt::LONG_SELECTOR, 0x8E); + idt_set_gate(interrupt::SYSCALL_FIRST+7, _syscall7, gdt::LONG_SELECTOR, 0x8E); + idt_set_gate(interrupt::SYSCALL_FIRST+8, _syscall8, gdt::LONG_SELECTOR, 0x8E); + idt_set_gate(interrupt::SYSCALL_FIRST+9, _syscall9, gdt::LONG_SELECTOR, 0x8E); + +} + void enable_interrupts(){ __asm__ __volatile__("sti" : : ); } @@ -205,7 +220,6 @@ void _fault_handler(interrupt::fault_regs regs){ k_printf("cr2=%h\n", get_cr2()); //TODO Improve that with kind of blue screen - //TODO Display the title of the exception __asm__ __volatile__("hlt" : : ); } @@ -225,6 +239,11 @@ void _irq_handler(size_t code){ out_byte(0x20, 0x20); } +void _syscall_handler(interrupt::syscall_regs regs){ + //TODO Call handler if any + //TODO Otherwise, display error +} + } //end of extern "C" void interrupt::register_irq_handler(size_t irq, void (*handler)()){ @@ -236,5 +255,6 @@ void interrupt::setup_interrupts(){ install_isrs(); remap_irqs(); install_irqs(); + install_syscalls(); enable_interrupts(); } diff --git a/kernel/src/syscalls.s b/kernel/src/syscalls.s new file mode 100644 index 00000000..731f1fbe --- /dev/null +++ b/kernel/src/syscalls.s @@ -0,0 +1,137 @@ +//======================================================================= +// Copyright Baptiste Wicht 2013-2014. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +.intel_syntax noprefix + +// Define the base ISRs + +.global _syscall0 +.global _syscall0 +.global _syscall1 +.global _syscall2 +.global _syscall3 +.global _syscall4 +.global _syscall5 +.global _syscall6 +.global _syscall7 +.global _syscall8 +.global _syscall9 + +_syscall0: + cli + + push rdi + mov rdi, 0 + + jmp syscall_common_handler + +_syscall1: + cli + + push rdi + mov rdi, 1 + + jmp syscall_common_handler + +_syscall2: + cli + + push rdi + mov rdi, 2 + + jmp syscall_common_handler + +_syscall3: + cli + + push rdi + mov rdi, 3 + + jmp syscall_common_handler + +_syscall4: + cli + + push rdi + mov rdi, 4 + + jmp syscall_common_handler + +_syscall5: + cli + + push rdi + mov rdi, 5 + + jmp syscall_common_handler + +_syscall6: + cli + + push rdi + mov rdi, 6 + + jmp syscall_common_handler + +_syscall7: + cli + + push rdi + mov rdi, 7 + + jmp syscall_common_handler + +_syscall8: + cli + + push rdi + mov rdi, 8 + + jmp syscall_common_handler + +_syscall9: + cli + + push rdi + mov rdi, 9 + + jmp syscall_common_handler + +// Common handler + +//TODO Check if really safe to trash r12 +syscall_common_handler: + push r8 + push r9 + push r10 + push r11 + push r12 + push rax + push rbx + push rcx + push rdx + push rsi + push rdi + + call _syscall_handler + + pop rdi + pop rsi + pop rdx + pop rcx + pop rbx + pop rax + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + + //Was pushed by the base handler code + pop rdi + + iretq // iret will clean the other automatically pushed stuff diff --git a/kernel/src/system_calls.cpp b/kernel/src/system_calls.cpp new file mode 100644 index 00000000..e69de29b