From 43e6623a42bcd5a033b02ddfd94118d606014170 Mon Sep 17 00:00:00 2001 From: Matheus Date: Mon, 8 May 2023 22:17:17 -0300 Subject: [PATCH] kernel: mmap syscall --- kernel-src/arch/x86-64/syscall.asm | 4 +- kernel-src/include/kernel/abi.h | 1 + kernel-src/sys/syscalls/mmap.c | 58 ++++++++++++++++++++++++++ patches/mlibc/jinx-working-patch.patch | 36 +++++++++------- 4 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 kernel-src/sys/syscalls/mmap.c diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index 08012ebd..fabfbfa5 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -1,9 +1,11 @@ section .rodata extern syscall_print +extern syscall_mmap syscalltab: dq syscall_print +dq syscall_mmap -syscallcount equ 1 +syscallcount equ 2 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/include/kernel/abi.h b/kernel-src/include/kernel/abi.h index b9eaec95..2a507a18 100644 --- a/kernel-src/include/kernel/abi.h +++ b/kernel-src/include/kernel/abi.h @@ -7,6 +7,7 @@ typedef int gid_t; typedef int uid_t; typedef unsigned int mode_t; typedef uint64_t ino_t; +typedef long off_t; #define POLLIN 0x1 #define POLLPRI 0x2 diff --git a/kernel-src/sys/syscalls/mmap.c b/kernel-src/sys/syscalls/mmap.c new file mode 100644 index 00000000..e3ddadaf --- /dev/null +++ b/kernel-src/sys/syscalls/mmap.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include + +#define PROT_READ 0x01 +#define PROT_WRITE 0x02 +#define PROT_EXEC 0x04 + +#define MAP_SHARED 0x01 +#define MAP_PRIVATE 0x02 +#define MAP_FIXED 0x10 +#define MAP_ANON 0x20 +#define MAP_ANONYMOUS MAP_ANON + +#define KNOWN_PROT (PROT_READ | PROT_WRITE | PROT_EXEC) +#define KNOWN_FLAGS (MAP_SHARED | MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS) + +syscallret_t syscall_mmap(context_t *context, void *hint, size_t len, int prot, int flags, int fd, off_t offset) { + syscallret_t ret = { + .errno = 0, + .ret = -1 + }; + + __assert((~KNOWN_FLAGS & flags) == 0); + __assert((~KNOWN_PROT & prot) == 0); + + // check alignment + if (len == 0 || (uintptr_t)hint % PAGE_SIZE || len % PAGE_SIZE) { + ret.errno = EINVAL; + return ret; + } + + mmuflags_t mmuflags = ARCH_MMU_FLAGS_USER; + if (prot & PROT_READ) + mmuflags |= ARCH_MMU_FLAGS_READ; + if (prot & PROT_WRITE) + mmuflags |= ARCH_MMU_FLAGS_WRITE; + if ((prot & PROT_EXEC) == 0) + mmuflags |= ARCH_MMU_FLAGS_NOEXEC; + + bool file = (flags & MAP_ANONYMOUS) == 0; + // TODO MAP_FIXED + __assert((flags & MAP_FIXED) == 0); + int vmmflags = 0; + vmmfiledesc_t vfd; + // TODO file mappings + __assert(file == false); + + if (hint < USERSPACE_START) + hint = USERSPACE_START; + + ret.ret = (uint64_t)vmm_map(hint, len, vmmflags, mmuflags, &vfd); + if (ret.ret == 0) + ret.errno = ENOMEM; + return ret; +} diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index 21c39988..9c820067 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -113,10 +113,10 @@ index 0000000..e5b087a + diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp new file mode 100644 -index 0000000..4486461 +index 0000000..4d9555e --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,133 @@ +@@ -0,0 +1,138 @@ +#include +#include +#include @@ -175,7 +175,7 @@ index 0000000..4486461 + + // stub + -+ int sys_getpgid(pid_t pid, pid_t* pgid) { ++ int sys_getpgid(pid_t pid, pid_t *pgid) { + *pgid = 1; + return 0; + } @@ -185,7 +185,7 @@ index 0000000..4486461 + syscall(SYSCALL_PRINT, &ret, (uint64_t)message); + } + -+ [[noreturn]] void sys_libc_panic(){ ++ [[noreturn]] void sys_libc_panic() { + sys_libc_log("mlibc: panic"); + for (;;) ; + } @@ -208,23 +208,25 @@ index 0000000..4486461 + } + + -+ int sys_anon_allocate(size_t size, void **pointer){ ++ int sys_anon_allocate(size_t size, void **pointer) { ++ size += 4096 - (size % 4096); + return sys_vm_map(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0, pointer); + } -+ int sys_anon_free(void* pointer, size_t size){ ++ int sys_anon_free(void *pointer, size_t size) { ++ size += 4096 - (size % 4096); + return sys_vm_unmap(pointer, size); + } + -+ int sys_open(const char* pathname, int flags, mode_t mode, int* fd) { ++ int sys_open(const char *pathname, int flags, mode_t mode, int *fd) { + return ENOSYS; + }; -+ int sys_read(int fd, void* buff, size_t count, ssize_t *bytes_read){ ++ int sys_read(int fd, void *buff, size_t count, ssize_t *bytes_read) { + return ENOSYS; + } -+ int sys_write(int fd, const void* buff, size_t count, ssize_t *bytes_written){ ++ int sys_write(int fd, const void *buff, size_t count, ssize_t *bytes_written) { + return ENOSYS; + } -+ int sys_seek(int fd, off_t offset, int whence, off_t *new_offset){ ++ int sys_seek(int fd, off_t offset, int whence, off_t *new_offset) { + return ENOSYS; + } + @@ -232,11 +234,14 @@ index 0000000..4486461 + return ENOSYS; + } + -+ int sys_vm_map(void *hint, size_t size, int prot, int flags, int fd, off_t offset, void** window){ -+ return ENOSYS; ++ int sys_vm_map(void *hint, size_t size, int prot, int flags, int fd, off_t offset, void **window) { ++ long ret; ++ long err = syscall(SYSCALL_MMAP, &ret, (uint64_t)hint, size, prot, flags, fd, offset); ++ *window = (void *)ret; ++ return err; + } + -+ int sys_vm_unmap(void* pointer, size_t size) { ++ int sys_vm_unmap(void *pointer, size_t size) { + return ENOSYS; + } + @@ -269,14 +274,15 @@ index 0000000..990eca0 +#endif diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h new file mode 100644 -index 0000000..2b6ae3a +index 0000000..8f1ee3c --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,24 @@ +@@ -0,0 +1,25 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + +#define SYSCALL_PRINT 0 ++#define SYSCALL_MMAP 1 + +#include +#include