From dfe7a1dbc73e8ff9a5d710ae20d3efbad3e1ba88 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Fri, 24 Mar 2023 23:43:09 +0100 Subject: [PATCH] mmap syscall declaration --- core/main.c | 1 + core/syscall.c | 19 +++++++++++++++++++ core/syscall.h | 1 + core/uaccess.c | 38 +++++++++++++++++++++++++++++++++++++- core/uaccess.h | 1 + disk.sfdisk | 1 - drivers/zero.h | 9 +++++++++ userspace/kernel/syscall.h | 1 + userspace/libc.c | 5 ++++- userspace/libc.h | 1 + userspace/main_user.c | 13 +++++++++++++ 11 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 drivers/zero.h diff --git a/core/main.c b/core/main.c index e52114b..ba1f9ef 100644 --- a/core/main.c +++ b/core/main.c @@ -28,6 +28,7 @@ #include "time.h" #include "types.h" #include "vga.h" +#include "zero.h" #define CHECK_FLAG(flags, bit) ((flags) & (1 << (bit))) diff --git a/core/syscall.c b/core/syscall.c index b836c67..8fac05a 100644 --- a/core/syscall.c +++ b/core/syscall.c @@ -5,6 +5,7 @@ #include "stdarg.h" #include "thread.h" #include "types.h" +#include "uaccess.h" #include "uaddrspace.h" int syscallExecute(int syscallId, const struct cpu_state *userCtx) @@ -55,6 +56,24 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx) threadChangeCurrentContext(NULL); break; } + case SYSCALL_ID_MMAP: { + struct uAddrSpace *as; + uaddr_t uaddr; + size_t size; + uint32_t rights; + uint32_t flags; + uaddr_t userPath; + + char path[256]; + + as = processGetAddrSpace(getCurrentThread()->process); + ret = syscallGet5args(userCtx, (unsigned int *)&uaddr, (unsigned int *)&size, (unsigned int *)&rights, + (unsigned int *)&flags, (unsigned int *)&userPath); + strzcpyFromUser((vaddr_t *)path, (uaddr_t *)userPath, sizeof(path)); + printf("Trying mmap for device %s\n", path); + (void)as; + break; + } default: printf("Unknon syscall id %d\n", syscallId); ret = -ENOENT; diff --git a/core/syscall.h b/core/syscall.h index 099e51a..6ac00c4 100644 --- a/core/syscall.h +++ b/core/syscall.h @@ -9,6 +9,7 @@ #define SYSCALL_ID_READ 4 #define SYSCALL_ID_TEST 5 #define SYSCALL_ID_BRK 6 +#define SYSCALL_ID_MMAP 7 #ifdef __KERNEL__ int syscallExecute(int syscallId, const struct cpu_state *user_ctx); diff --git a/core/uaccess.c b/core/uaccess.c index 852cc5e..023a591 100644 --- a/core/uaccess.c +++ b/core/uaccess.c @@ -1,10 +1,12 @@ +#include "uaccess.h" #include "assert.h" #include "errno.h" +#include "minmax.h" #include "mmuContext.h" #include "paging.h" #include "process.h" #include "thread.h" -#include "uaccess.h" +#include "types.h" static int bindtoUserContext() { @@ -52,3 +54,37 @@ int memcpyFromUser(vaddr_t to, uaddr_t from, size_t size) return memcpyUserMemNoCheck(to, from, size); } + +static int strzcpyFromUserNoCheck(char *to, char *from, size_t size) +{ + int ret; + + ret = bindtoUserContext(); + if (ret != 0) + return ret; + + for (unsigned int i = 0; i < size; i++) { + to[i] = from[i]; + if (from[i] == '\0') + break; + } + + if (size > 0) + to[size - 1] = '\0'; + + ret = unbindUserContext(); + if (ret != 0) + return ret; + + return size; +} + +int strzcpyFromUser(vaddr_t *to, uaddr_t *from, size_t size) +{ + if ((uint)from < PAGING_BASE_USER_ADDRESS) + return -EPERM; + if ((uint)from > PAGING_TOP_USER_ADDRESS - size) + return -EPERM; + + return strzcpyFromUserNoCheck((char *)to, (char *)from, size); +} diff --git a/core/uaccess.h b/core/uaccess.h index 465e268..bf97293 100644 --- a/core/uaccess.h +++ b/core/uaccess.h @@ -3,3 +3,4 @@ #include "stdarg.h" int memcpyFromUser(vaddr_t to, uaddr_t from, size_t size); +int strzcpyFromUser(vaddr_t *to, uaddr_t *from, size_t size); diff --git a/disk.sfdisk b/disk.sfdisk index 2004b3d..a1ecf61 100644 --- a/disk.sfdisk +++ b/disk.sfdisk @@ -2,7 +2,6 @@ label: dos label-id: 0x9ec19bcc device: disk.img unit: sectors -sector-size: 512 disk.img1 : start= 2048, size= 32768, type=6, bootable disk.img2 : start= 34816, size= 30720, type=83 diff --git a/drivers/zero.h b/drivers/zero.h new file mode 100644 index 0000000..83f4672 --- /dev/null +++ b/drivers/zero.h @@ -0,0 +1,9 @@ +#pragma once + + +#include "types.h" +#include +#include +int zeroSetup(); + +int zeroMmap(uaddr_t *uaddr, size_t size, uint32_t rights, uint32_t flags); diff --git a/userspace/kernel/syscall.h b/userspace/kernel/syscall.h index 099e51a..6ac00c4 100644 --- a/userspace/kernel/syscall.h +++ b/userspace/kernel/syscall.h @@ -9,6 +9,7 @@ #define SYSCALL_ID_READ 4 #define SYSCALL_ID_TEST 5 #define SYSCALL_ID_BRK 6 +#define SYSCALL_ID_MMAP 7 #ifdef __KERNEL__ int syscallExecute(int syscallId, const struct cpu_state *user_ctx); diff --git a/userspace/libc.c b/userspace/libc.c index 4b1dff0..61c0681 100644 --- a/userspace/libc.c +++ b/userspace/libc.c @@ -662,7 +662,6 @@ struct heapBlock *getHeapBlock(void *ptr) { return (struct heapBlock *)ptr - 1; } - void free(void *ptr){ if(!ptr) return; @@ -673,3 +672,7 @@ void free(void *ptr){ blk->free = 1; } +void *mmap(void *addr, size_t len, int prot, int flags, char *path){ + + return (void *)syscall5(SYSCALL_ID_MMAP, (unsigned int)addr, len, prot, flags, (unsigned int)path); +} diff --git a/userspace/libc.h b/userspace/libc.h index 4e2a4a5..5c68b45 100644 --- a/userspace/libc.h +++ b/userspace/libc.h @@ -29,6 +29,7 @@ int putc(const int c); int vsnprintf(char *str, size_t size, const char *format, va_list ap) __attribute__ ((__format__ (printf, 3, 0))); int vprintf(const char *format, va_list ap) __attribute__ ((__format__ (printf, 1, 0))); int printf(const char *format, ...) __attribute__ ((__format__ (printf, 1, 2))); +void *mmap(void *addr, size_t len, int prot, int flags, char *path); int asprintf(char **strp, const char *fmt, ...) __attribute__ ((__format__ (printf, 2, 3))); int vasprintf(char **strp, const char *fmt, va_list ap) __attribute__ ((__format__ (printf, 2, 0))); diff --git a/userspace/main_user.c b/userspace/main_user.c index 420b3bc..3b7c1fb 100644 --- a/userspace/main_user.c +++ b/userspace/main_user.c @@ -55,6 +55,15 @@ int func_alloc() return 0; } +int func_mmap() +{ + + char *path ="/dev/zero"; + mmap(0, 4096, 0, 0, path); + + return 0; +} + int main(int argc, char *argv[]) { (void)argc; @@ -85,6 +94,10 @@ int main(int argc, char *argv[]) func_tiny(); continue; } + if (strcmp(buf, "mmap") == 0) { + func_mmap(); + continue; + } } return 0; }