From cc4b85f8e6bab340baa80e7bf2d5848d1718ae57 Mon Sep 17 00:00:00 2001 From: Mathias Gottschlag Date: Tue, 23 Dec 2008 10:42:20 +0100 Subject: [PATCH] - Implemented first part of signal support. - Removed some magic numbers. --- programs/include/signal.h | 33 +------- programs/libc/bsdmalloc.c | 5 +- programs/libc/files.c | 20 ++--- programs/libc/signal.c | 8 +- programs/libc/socket.c | 3 +- programs/libc/stdlib.c | 5 +- programs/libc/unistd.c | 9 +- programs/libc/wait.c | 3 +- .../stdlib.c => shared/include/planlos/signals.h | 79 ++++++++---------- .../stdlib.c => shared/include/planlos/syscalls.h | 70 ++++++---------- system/include/ke/multiboot.h | 78 ++++++++++++++++++ system/include/ke/process.h | 11 +++ system/include/ke/thread.h | 6 ++ system/include/mm/memory.h | 1 + system/include/sys/syscall.h | 22 +---- system/kernel/CMakeLists.txt | 2 + system/kernel/ke/interrupts.c | 15 ++-- system/kernel/ke/process.c | 95 ++++++++++++++++++++++ system/kernel/ke/signal.S | 13 +++ system/kernel/ke/thread.c | 2 + system/kernel/mm/virt.c | 3 +- system/kernel/sys/syscall.c | 28 +++++++ 22 files changed, 344 insertions(+), 167 deletions(-) copy programs/libc/stdlib.c => shared/include/planlos/signals.h (63%) copy programs/libc/stdlib.c => shared/include/planlos/syscalls.h (67%) create mode 100644 system/kernel/ke/signal.S diff --git a/programs/include/signal.h b/programs/include/signal.h index 6c9aafd..7a474cd 100644 --- a/programs/include/signal.h +++ b/programs/include/signal.h @@ -23,6 +23,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SIGNAL_H_INCLUDED #include +#include #define SIG_DFL (void(*)(int))(1) #define SIG_ERR (void(*)(int))(2) @@ -44,38 +45,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define MINSIGSTKSZ 13 #define SIGSTKSZ 14 -#define SIGABRT 1 -#define SIGALRM 2 -#define SIGFPE 3 -#define SIGHUP 4 -#define SIGILL 5 -#define SIGINT 6 -#define SIGKILL 7 -#define SIGPIPE 8 -#define SIGQUIT 9 -#define SIGSEGV 10 -#define SIGTERM 11 -#define SIGUSR1 12 -#define SIGUSR2 13 -#define SIGCHLD 14 -#define SIGCONT 15 -#define SIGSTOP 16 -#define SIGTSTP 17 -#define SIGTTIN 18 -#define SIGTTOU 19 -#define SIGBUS 20 -#define SIGPOLL 21 -#define SIGPROF 22 -#define SIGSYS 23 -#define SIGTRAP 24 -#define SIGURG 25 -#define SIGVTALRM 26 -#define SIGXCPU 27 -#define SIGXFSZ 28 -#define SIGWINCH 29 - -#define NSIG 30 - #define BRKINT 1 #define ICRNL 2 #define IGNBRK 3 diff --git a/programs/libc/bsdmalloc.c b/programs/libc/bsdmalloc.c index 8637e5b..4adbbde 100644 --- a/programs/libc/bsdmalloc.c +++ b/programs/libc/bsdmalloc.c @@ -8,6 +8,7 @@ */ #include +#include /* * Defining MALLOC_EXTRA_SANITY will enable extra checks which are related @@ -50,12 +51,12 @@ void* mem_allocate(uint32_t size, uint32_t flags) { uintptr_t vaddr; - asm volatile("int $0x80" : "=b"(vaddr): "a"(10), "b"(size)); + asm volatile("int $0x80" : "=b"(vaddr): "a"(SYS_ALLOC), "b"(size)); return (void*)vaddr; } void mem_free(void *addr, uint32_t size) { - asm volatile("int $0x80" : : "a"(11), "b"(addr), "c"(size)); + asm volatile("int $0x80" : : "a"(SYS_FREE), "b"(addr), "c"(size)); } int errno; diff --git a/programs/libc/files.c b/programs/libc/files.c index a419f98..8036445 100644 --- a/programs/libc/files.c +++ b/programs/libc/files.c @@ -25,12 +25,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include - +#include int open(const char *path, int oflag, ...) { int status = -1; - asm volatile("int $0x80" : "=b"(status): "a"(2), "b"(path), "c"(oflag)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_OPEN), "b"(path), "c"(oflag)); return status; } @@ -42,35 +42,35 @@ int creat(const char *path, mode_t mode) ssize_t write(int fildes, const void *buf, size_t nbyte) { int status = -1; - asm volatile("int $0x80" : "=b"(status): "a"(5), "b"(fildes), "c"(buf), "d"(nbyte)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_WRITE), "b"(fildes), "c"(buf), "d"(nbyte)); return status; } ssize_t read(int fildes, void *buf, size_t nbyte) { int status = -1; - asm volatile("int $0x80" : "=b"(status): "a"(4), "b"(fildes), "c"(buf), "d"(nbyte)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_READ), "b"(fildes), "c"(buf), "d"(nbyte)); return status; } int close(int fildes) { int status = -1; - asm volatile("int $0x80" : "=b"(status): "a"(3), "b"(fildes)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_CLOSE), "b"(fildes)); return status; } off_t lseek(int fildes, off_t offset, int whence) { int position = -1; - asm volatile("int $0x80" : "=b"(position): "a"(13), "b"(fildes), "c"(offset), "d"(whence)); + asm volatile("int $0x80" : "=b"(position): "a"(SYS_SEEK), "b"(fildes), "c"(offset), "d"(whence)); return position; } int mknod(const char *path, mode_t mode, dev_t dev) { int status = -1; - asm volatile("int $0x80" : "=b"(status): "a"(14), "b"(path), "c"(mode)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_MKNOD), "b"(path), "c"(mode)); return status; } int mkdir(const char *path, mode_t mode) @@ -127,7 +127,7 @@ int ioctl(int fd, int request, ...) { int param = *(&request + 1); int status; - asm volatile("int $0x80" : "=b"(status): "a"(19), "b"(fd), "c"(request), "d"(param)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_IOCTL), "b"(fd), "c"(request), "d"(param)); return status; } @@ -140,7 +140,7 @@ int pipe(int fd[2]) { int in; int out; - asm volatile("int $0x80" : "=b"(in), "=c"(out): "a"(17)); + asm volatile("int $0x80" : "=b"(in), "=c"(out): "a"(SYS_PIPE)); if (in == -1) return -1; fd[1] = in; @@ -152,7 +152,7 @@ int fcntl(int fd, int cmd, ...) { uintptr_t param = *(uintptr_t*)(&cmd + 1); int status; - asm volatile("int $0x80" : "=b"(status): "a"(20), "b"(fd), "c"(cmd), "d"(param)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_FCNTL), "b"(fd), "c"(cmd), "d"(param)); return status; } diff --git a/programs/libc/signal.c b/programs/libc/signal.c index 82dd734..5bf67b1 100644 --- a/programs/libc/signal.c +++ b/programs/libc/signal.c @@ -20,6 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include +#include int kill(pid_t pid, int sig) { @@ -27,10 +28,15 @@ int kill(pid_t pid, int sig) } int raise(int sig) { - return -1; + int status; + asm volatile("int $0x80" : "=b"(status): "a"(SYS_RAISE), "b"(sig)); + return status; } void (*signal(int sig, void (*func)(int)))(int) { + int status; + asm volatile("int $0x80" : "=b"(status): "a"(SYS_SIGNAL), "b"(sig), "c"(func)); + return 0; } int sigdelset(sigset_t *set, int signo) diff --git a/programs/libc/socket.c b/programs/libc/socket.c index 824cb90..476edf8 100644 --- a/programs/libc/socket.c +++ b/programs/libc/socket.c @@ -24,6 +24,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include #define SOCKET_IOCTL_SETSOCKOPT 1 #define SOCKET_IOCTL_BIND 2 @@ -105,7 +106,7 @@ int shutdown(int socket, int how) int socket(int domain, int type, int protocol) { int fd; - asm volatile("int $0x80" : "=b"(fd): "a"(18)); + asm volatile("int $0x80" : "=b"(fd): "a"(SYS_SOCKET)); return fd; } int socketpair(int domain, int type, int protocol, int socket_vector[2]) diff --git a/programs/libc/stdlib.c b/programs/libc/stdlib.c index e37d441..075beff 100644 --- a/programs/libc/stdlib.c +++ b/programs/libc/stdlib.c @@ -20,12 +20,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include +#include unsigned int errno; void abort(void) { - asm volatile("int $0x80" : : "a"(1), "b"(-1)); + asm volatile("int $0x80" : : "a"(SYS_EXIT), "b"(-1)); } void *sbrk(int increment) @@ -36,7 +37,7 @@ void *sbrk(int increment) void exit(int value) { // TODO: Close files - asm volatile("int $0x80" : : "a"(1), "b"(value)); + asm volatile("int $0x80" : : "a"(SYS_EXIT), "b"(value)); } int atoi(const char *str) diff --git a/programs/libc/unistd.c b/programs/libc/unistd.c index 28e1892..4b76dce 100644 --- a/programs/libc/unistd.c +++ b/programs/libc/unistd.c @@ -21,18 +21,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include pid_t fork(void) { int status = -1; - asm volatile("int $0x80" : "=b"(status): "a"(6)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_FORK)); return status; } int execl(const char *path, const char *arg0, ...) { int status = -1; - asm volatile("int $0x80" : "=b"(status): "a"(9), "b"(path)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_EXEC), "b"(path)); return status; } int execle(const char *path, const char *arg0, ...) @@ -59,14 +60,14 @@ int execvp(const char *path, char *const argv[]) char *getcwd(char *buf, size_t size) { int status = -1; - asm volatile("int $0x80" : "=b"(status): "a"(15), "b"(buf), "c"(size)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_GETWD), "b"(buf), "c"(size)); if (status == -1) return 0; return buf; } int chdir(const char *path) { int status = -1; - asm volatile("int $0x80" : "=b"(status): "a"(16), "b"(path)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_CHDIR), "b"(path)); return status; } int dup(int fd) diff --git a/programs/libc/wait.c b/programs/libc/wait.c index a84a64a..78f394b 100644 --- a/programs/libc/wait.c +++ b/programs/libc/wait.c @@ -20,6 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include +#include pid_t wait(int *status) { @@ -28,7 +29,7 @@ pid_t wait(int *status) pid_t waitpid(pid_t pid, int *status, int flags) { int retval = -1; - asm volatile("int $0x80" : "=b"(retval): "a"(12), "b"(pid), "c"(status), "d"(flags)); + asm volatile("int $0x80" : "=b"(retval): "a"(SYS_WAIT), "b"(pid), "c"(status), "d"(flags)); return retval; } diff --git a/programs/libc/stdlib.c b/shared/include/planlos/signals.h similarity index 63% copy from programs/libc/stdlib.c copy to shared/include/planlos/signals.h index e37d441..6886b4a 100644 --- a/programs/libc/stdlib.c +++ b/shared/include/planlos/signals.h @@ -19,47 +19,40 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include - -unsigned int errno; - -void abort(void) -{ - asm volatile("int $0x80" : : "a"(1), "b"(-1)); -} - -void *sbrk(int increment) -{ - return 0; -} - -void exit(int value) -{ - // TODO: Close files - asm volatile("int $0x80" : : "a"(1), "b"(value)); -} - -int atoi(const char *str) -{ - int number = 0; - int negative = 0; - if (*str == '-') - { - str++; - negative = 1; - } - while (*str) - { - if ((*str >= '0') && (*str <= '9')) - { - number = number * 10 + (*str - '0'); - str++; - } - else - { - break; - } - } - return number; -} +#ifndef PLANLOS_SIGNALS_INCLUDED +#define PLANLOS_SIGNALS_INCLUDED + +#define SIGABRT 1 +#define SIGALRM 2 +#define SIGFPE 3 +#define SIGHUP 4 +#define SIGILL 5 +#define SIGINT 6 +#define SIGKILL 7 +#define SIGPIPE 8 +#define SIGQUIT 9 +#define SIGSEGV 10 +#define SIGTERM 11 +#define SIGUSR1 12 +#define SIGUSR2 13 +#define SIGCHLD 14 +#define SIGCONT 15 +#define SIGSTOP 16 +#define SIGTSTP 17 +#define SIGTTIN 18 +#define SIGTTOU 19 +#define SIGBUS 20 +#define SIGPOLL 21 +#define SIGPROF 22 +#define SIGSYS 23 +#define SIGTRAP 24 +#define SIGURG 25 +#define SIGVTALRM 26 +#define SIGXCPU 27 +#define SIGXFSZ 28 +#define SIGWINCH 29 + +#define NSIG 30 + +#endif diff --git a/programs/libc/stdlib.c b/shared/include/planlos/syscalls.h similarity index 67% copy from programs/libc/stdlib.c copy to shared/include/planlos/syscalls.h index e37d441..2e12a5f 100644 --- a/programs/libc/stdlib.c +++ b/shared/include/planlos/syscalls.h @@ -19,47 +19,31 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include - -unsigned int errno; - -void abort(void) -{ - asm volatile("int $0x80" : : "a"(1), "b"(-1)); -} - -void *sbrk(int increment) -{ - return 0; -} - -void exit(int value) -{ - // TODO: Close files - asm volatile("int $0x80" : : "a"(1), "b"(value)); -} - -int atoi(const char *str) -{ - int number = 0; - int negative = 0; - if (*str == '-') - { - str++; - negative = 1; - } - while (*str) - { - if ((*str >= '0') && (*str <= '9')) - { - number = number * 10 + (*str - '0'); - str++; - } - else - { - break; - } - } - return number; -} +#ifndef PLANLOS_SYSCALLS_INCLUDED +#define PLANLOS_SYSCALLS_INCLUDED + +#define SYS_EXIT 1 +#define SYS_OPEN 2 +#define SYS_CLOSE 3 +#define SYS_READ 4 +#define SYS_WRITE 5 +#define SYS_FORK 6 +#define SYS_SLEEP 7 +#define SYS_WAITPID 8 +#define SYS_EXEC 9 +#define SYS_ALLOC 10 +#define SYS_FREE 11 +#define SYS_WAIT 12 +#define SYS_SEEK 13 +#define SYS_MKNOD 14 +#define SYS_GETWD 15 +#define SYS_CHDIR 16 +#define SYS_PIPE 17 +#define SYS_SOCKET 18 +#define SYS_IOCTL 19 +#define SYS_FCNTL 20 +#define SYS_SIGNAL 21 +#define SYS_RAISE 22 + +#endif diff --git a/system/include/ke/multiboot.h b/system/include/ke/multiboot.h index 42c45fd..62613b6 100644 --- a/system/include/ke/multiboot.h +++ b/system/include/ke/multiboot.h @@ -18,6 +18,10 @@ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTIO OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/** + * \file multiboot.h + * Multiboot information + */ #ifndef KE_MULTIBOOT_H_INCLUDED #define KE_MULTIBOOT_H_INCLUDED @@ -28,6 +32,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define MULTIBOOT_HEADER_FLAGS 0x00000003 #define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 +/** + * a.out symbol table. Not used anywhere. + */ typedef struct AoutSymbolTable { uint32_t tabsize; @@ -36,6 +43,9 @@ typedef struct AoutSymbolTable uint32_t reserved; } AoutSymbolTable; +/** + * ELF section header table holding the information about the kernel executable. + */ typedef struct ElfSectionHeaderTable { uint32_t num; @@ -44,39 +54,107 @@ typedef struct ElfSectionHeaderTable uint32_t shindex; } ElfSectionHeaderTable; +/** + * Multiboot module information. + */ typedef struct MbModule { + /** + * Start of the physical module memory. + */ uint32_t start; + /** + * End of the physical module memory. + */ uint32_t end; + /** + * File name of the module. + */ uint32_t string; uint32_t reserved; } MbModule; +/** + * Multiboot memory map. + */ typedef struct MbMemoryMap { + /** + * Size of the rest of the structure not including this member (can be more + * than 20 bytes). + */ uint32_t size; + /** + * Low 32 bits of the base address. + */ uint32_t baseaddrlow; + /** + * High 32 bits of the base address. + */ uint32_t baseaddrhigh; + /** + * Low 32 bits of the length of the memory range. + */ uint32_t lengthlow; + /** + * High 32 bits of the length of the memory range. + */ uint32_t lengthhigh; + /** + * Type of the memory range. + */ uint32_t type; } MbMemoryMap; +/** + * Multiboot information structure. + */ typedef struct MultibootInfo { + /** + * Flags telling what information is included in the struct. + */ uint32_t flags; + /** + * Amount of base memory. + */ uint32_t lowermem; + /** + * Approximated amount of upper memory. + */ uint32_t uppermem; + /** + * Device the operating system was booted from. The first byte contains the + * BIOS number of the device, the rest contains the partition information. + */ uint32_t bootdevice; + /** + * Kernel command line. + */ uint32_t cmdline; + /** + * Number of modules loaded by the boot loader. + */ uint32_t modcount; + /** + * Pointer to the module info block (array of MbModule). + */ uint32_t modaddr; + /** + * Kernel symbol information. + */ union { AoutSymbolTable aoutsym; ElfSectionHeaderTable elfsections; } u; + /** + * Length of the memory map. + */ uint32_t mmaplength; + /** + * Pointer to the first memory range information (MbMemoryMap). + */ uint32_t mmapaddr; } MultibootInfo; diff --git a/system/include/ke/process.h b/system/include/ke/process.h index 2e1a859..814d205 100644 --- a/system/include/ke/process.h +++ b/system/include/ke/process.h @@ -27,6 +27,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define KE_PROCESS_H_INCLUDED #include +#include #include "mm/memory.h" #include "fs/fs.h" @@ -76,6 +77,11 @@ typedef struct KeProcess */ char *cwd; + /** + * Signal handlers for the current process. + */ + uintptr_t signal_handlers[NSIG]; + struct KeThread *waitthread; } KeProcess; @@ -108,5 +114,10 @@ int keClearProcess(KeProcess *process, struct KeThread *current); */ KeProcess *keGetProcess(uint32_t pid); +/** + * Sends a signal to the process. + */ +void keSendSignal(KeProcess *process, struct KeThread *thread, int signal); + #endif diff --git a/system/include/ke/thread.h b/system/include/ke/thread.h index 07b01cb..3df0c43 100644 --- a/system/include/ke/thread.h +++ b/system/include/ke/thread.h @@ -33,6 +33,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define KE_THREAD_FSREQUEST 2 #define KE_THREAD_KILLED 3 #define KE_THREAD_WAIT 4 +#define KE_THREAD_INUSE 5 /** * Structure containing the information about a thread. @@ -58,6 +59,11 @@ typedef struct KeThread uintptr_t userstack_size; /** + * User stack frame on the kernel stack, 0, if this is a kernel thread. + */ + uintptr_t userframe; + + /** * Current status of the thread. */ uint32_t status; diff --git a/system/include/mm/memory.h b/system/include/mm/memory.h index 0d16bbe..3faa32c 100644 --- a/system/include/mm/memory.h +++ b/system/include/mm/memory.h @@ -68,6 +68,7 @@ void mmFreePhysicalMemory(uintptr_t addr, uint32_t size); #define MM_MAP_WRITE 0x2 #define MM_MAP_EXECUTE 0x4 #define MM_MAP_UNCACHEABLE 0x8 +#define MM_MAP_USER 0x10 int mmMapMemory(MmAddressSpace *addrspace, uintptr_t phys, uintptr_t virt, uint32_t mode); diff --git a/system/include/sys/syscall.h b/system/include/sys/syscall.h index 6a51081..7a53d97 100644 --- a/system/include/sys/syscall.h +++ b/system/include/sys/syscall.h @@ -27,27 +27,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SYS_SYSCALL_H_INCLUDED #include "ke/thread.h" - -#define SYS_EXIT 1 -#define SYS_OPEN 2 -#define SYS_CLOSE 3 -#define SYS_READ 4 -#define SYS_WRITE 5 -#define SYS_FORK 6 -#define SYS_SLEEP 7 -#define SYS_WAITPID 8 -#define SYS_EXEC 9 -#define SYS_ALLOC 10 -#define SYS_FREE 11 -#define SYS_WAIT 12 -#define SYS_SEEK 13 -#define SYS_MKNOD 14 -#define SYS_GETWD 15 -#define SYS_CHDIR 16 -#define SYS_PIPE 17 -#define SYS_SOCKET 18 -#define SYS_IOCTL 19 -#define SYS_FCNTL 20 +#include #define SYS_FCNTL_DUP 1 diff --git a/system/kernel/CMakeLists.txt b/system/kernel/CMakeLists.txt index 0c91dde..8f977a7 100644 --- a/system/kernel/CMakeLists.txt +++ b/system/kernel/CMakeLists.txt @@ -41,12 +41,14 @@ ke/stdlib.c ke/stdio.c ke/bsdmalloc.c ke/smpstart.o +ke/signal.o ) set(CMAKE_C_FLAGS "-fstrength-reduce -fno-builtin -m32 -Wall -Wextra -Wno-unused-parameter -nostdlib -nostdinc -Wno-long-long") set(CMAKE_ASM-ATT_FLAGS "--32") include_directories(../include ../include/lwip ../include/lwip/ipv4 ../../shared/include) add_custom_command(OUTPUT ke/smpstart.o COMMAND ${CMAKE_ASM-ATT_COMPILER} --32 -o smpstart2.o ke/smpstart.S && ld -o smpstart.o smpstart2.o -Ttext 0x1000 --oformat binary -m elf_i386 && objcopy -B i386 -I binary -O elf32-i386 smpstart.o ke/smpstart.o && rm smpstart.o smpstart2.o DEPENDS ke/smpstart.S) +add_custom_command(OUTPUT ke/signal.o COMMAND ${CMAKE_ASM-ATT_COMPILER} --32 -o signal2.o ke/signal.S && ld -o signal.o signal2.o -Ttext 0xFFFFF000 --oformat binary -m elf_i386 && objcopy -B i386 -I binary -O elf32-i386 signal.o ke/signal.o && rm signal.o signal2.o DEPENDS ke/signal.S) add_definitions(-DARCH_X86=1) set(EXECUTABLE_OUTPUT_PATH ../../build/boot) add_executable(planlOS ${SRC}) diff --git a/system/kernel/ke/interrupts.c b/system/kernel/ke/interrupts.c index 91d5fb3..ac83416 100644 --- a/system/kernel/ke/interrupts.c +++ b/system/kernel/ke/interrupts.c @@ -280,7 +280,15 @@ void *keIntHandler(IntStackFrame *isf) cpu->interrupt = 1; oldthread = cpu->currentthread; } - + if (oldthread) + { + oldthread->kernelstack = (uintptr_t)isf; + if (isf->cs == 0x1b) + { + oldthread->userframe = oldthread->kernelstack; + } + } + if (isf->intno < 0x20) { // Exception keExceptionHandler(isf); @@ -293,11 +301,6 @@ void *keIntHandler(IntStackFrame *isf) } }*/ } else { - KeThread *oldthread = cpu->currentthread; - if (cpu && cpu->currentthread) - { - cpu->currentthread->kernelstack = (uintptr_t)isf; - } // Call handler if (isf->intno == 0x80) { diff --git a/system/kernel/ke/process.c b/system/kernel/ke/process.c index 5b9b9a5..87f6470 100644 --- a/system/kernel/ke/process.c +++ b/system/kernel/ke/process.c @@ -22,8 +22,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "ke/process.h" #include "ke/thread.h" #include "ke/level.h" +#include "ke/cpu.h" +#include "ke/interrupts.h" +#include "ke/debug.h" +#include "sys/syscall.h" #include #include +#include static uint32_t lastpid = 0; @@ -33,6 +38,16 @@ uint32_t processcount = 0; int keInitProcessManager(void) { + // Create signal entry + uintptr_t paddr = mmAllocPhysicalMemory(0, 0, 0x1000); + mmMapKernelMemory(paddr, 0xFFFFF000, + MM_MAP_READ | MM_MAP_WRITE | MM_MAP_USER); + extern void *_binary_signal_o_start; + extern void *_binary_signal_o_end; + memcpy((void*)0xFFFFF000, &_binary_signal_o_start, + (uintptr_t)&_binary_signal_o_end - (uintptr_t)&_binary_signal_o_start); + + // Create process list processes = 0; processcount = 0; keInitSpinlock(&process_lock); @@ -151,3 +166,83 @@ KeProcess *keGetProcess(uint32_t pid) return 0; } +void keSendSignal(KeProcess *process, KeThread *thread, int signal) +{ + KeCPU *cpu = keGetCurrentCPU(); + if (signal == SIGKILL) + { + // Kill process + KeThread *currentthread = cpu->currentthread; + keTerminateProcess(thread->process); + if (currentthread->process == process) + asm volatile("int $0x32"); + return; + } + // TODO: SIGSTOP + // Find and lock target thread + if (!thread) + { + if (process->threadcount == 0) return; + thread = process->threads[0]; + } + if (thread) + { + if (thread != cpu->currentthread) + { + if (keTryLockSpinlock(&thread->active)) + { + // Someone uses the thread right now + thread->status = KE_THREAD_INUSE; + keLockSpinlock(&thread->active); + if (thread->status == KE_THREAD_INUSE) + { + thread->status = KE_THREAD_RUNNING; + } + } + } + } + // Send signal + uintptr_t handler = process->signal_handlers[signal]; + if (thread && handler && thread->userframe) + { + // Reset signal handler in case the handler is broken + process->signal_handlers[signal] = 0; + // Get user stack + IntStackFrame *userframe = (IntStackFrame*)thread->userframe; + uint32_t *stack = sysMapUserMemory(thread, userframe->esp - 16, 16, 1); + if (!stack) + { + // TODO + kePrint("User stack broken.\n"); + if (thread != cpu->currentthread) + { + keUnlockSpinlock(&thread->active); + } + keTerminateProcess(thread->process); + if (cpu->currentthread->process == process) + asm volatile("int $0x32"); + return; + } + else + { + // Push eip, ebp, signal and handler onto the stack + stack[3] = userframe->eip; + stack[2] = userframe->ebp; + userframe->ebp = userframe->esp - 8; + stack[1] = signal; + stack[0] = handler; + userframe->esp = userframe->esp - 16; + userframe->eip = 0xFFFFF000; + } + } + else + { + // TODO: Default actions + } + // Unlock thread again + if (thread != cpu->currentthread) + { + keUnlockSpinlock(&thread->active); + } +} + diff --git a/system/kernel/ke/signal.S b/system/kernel/ke/signal.S new file mode 100644 index 0000000..ee3fda7 --- /dev/null +++ b/system/kernel/ke/signal.S @@ -0,0 +1,13 @@ +.code32 +.org 0x0 +start: + pushal + push -4(%ebp) + mov -8(%ebp), %eax + call *%eax + add $4, %esp + popal + mov %ebp, %esp + pop %ebp + ret + diff --git a/system/kernel/ke/thread.c b/system/kernel/ke/thread.c index 5917f9e..80d9d33 100644 --- a/system/kernel/ke/thread.c +++ b/system/kernel/ke/thread.c @@ -102,6 +102,7 @@ KeThread *keCreateThread(KeProcess *process, uintptr_t entry, uint32_t paramcoun *(--stack) = 0x23; *(--stack) = 0x23; thread->kernelstack = (uintptr_t)stack; + thread->userframe = thread->kernelstack; // Add thread to thread list KeExecLevel oldlevel = keSetExecutionLevel(KE_LEVEL_HIGH); @@ -197,6 +198,7 @@ KeThread *keCloneThread(KeProcess *process, KeThread *thread, uintptr_t stack) newthread->kernelstack_bottom = kernelstack_virt; memcpy((void*)kernelstack_virt, (void*)thread->kernelstack_bottom, 0x1000); newthread->kernelstack = kernelstack_virt + (stack - thread->kernelstack_bottom); + newthread->userframe = newthread->kernelstack_bottom + thread->userframe - thread->kernelstack_bottom; // Add thread to thread list KeExecLevel oldlevel = keSetExecutionLevel(KE_LEVEL_HIGH); keLockSpinlock(&threadlock); diff --git a/system/kernel/mm/virt.c b/system/kernel/mm/virt.c index 62d9878..b25aaf6 100644 --- a/system/kernel/mm/virt.c +++ b/system/kernel/mm/virt.c @@ -68,7 +68,7 @@ int mmInitVirtualMemory(MultibootInfo *mbinfo, uintptr_t kernel_begin, { page_table_phys = mmAllocPhysicalMemory(MM_MEMORY_ALLOC_DMA, 0, 0x1000); memset((void*)(page_table_phys + MM_KERNEL_BASE), 0, 0x1000); - kernel_directory[i] = page_table_phys | 0x3; + kernel_directory[i] = page_table_phys | 0x7; } } kernel_directory[MM_KERNEL_PAGE_TABLES >> 22] = ((uintptr_t)kernel_directory - MM_KERNEL_BASE) | 0x3; @@ -263,6 +263,7 @@ int mmMapKernelMemory(uintptr_t phys, uintptr_t virt, uint32_t pgtab_index = (virt / 0x1000) % 1024; uint32_t *page_tables = (uint32_t*)MM_KERNEL_PAGE_TABLES; phys |= 0x1; // Present + if (mode & MM_MAP_USER) phys |= 0x4; if (mode & MM_MAP_WRITE) phys |= 0x2; if (mode & MM_MAP_UNCACHEABLE) phys |= 0x18; if (mode) diff --git a/system/kernel/sys/syscall.c b/system/kernel/sys/syscall.c index 9ac86a0..36508e4 100644 --- a/system/kernel/sys/syscall.c +++ b/system/kernel/sys/syscall.c @@ -420,6 +420,29 @@ void sysFcntl(KeThread *thread, uintptr_t *param1, uintptr_t *param2, break; } } +void sysSignal(KeThread *thread, uintptr_t *param1, uintptr_t *param2, + uintptr_t *param3, uintptr_t *param4, uintptr_t *param5) +{ + int signal = *param1; + uintptr_t handler = *param2; + if (signal >= NSIG) + { + *param1 = -1; + } + thread->process->signal_handlers[signal] = handler; + *param1 = 0; +} +void sysRaise(KeThread *thread, uintptr_t *param1, uintptr_t *param2, + uintptr_t *param3, uintptr_t *param4, uintptr_t *param5) +{ + int signal = *param1; + if (signal >= NSIG) + { + *param1 = -1; + } + *param1 = 0; + keSendSignal(thread->process, 0, signal); +} void sysSyscall(KeThread *thread, uintptr_t index, uintptr_t *param1, uintptr_t *param2, uintptr_t *param3, uintptr_t *param4, uintptr_t *param5) @@ -740,6 +763,11 @@ void sysSyscall(KeThread *thread, uintptr_t index, uintptr_t *param1, case SYS_FCNTL: sysFcntl(thread, param1, param2, param3, param4, param5); break; + case SYS_SIGNAL: + sysSignal(thread, param1, param2, param3, param4, param5); + break; + case SYS_RAISE: + sysRaise(thread, param1, param2, param3, param4, param5); break; default: *param1 = -1; -- 2.11.4.GIT