implement munmap

Also add basic errno.h
This commit is contained in:
Mathieu Maret 2024-02-10 23:25:24 +01:00
parent 3339f8b059
commit 27c2f503cc
9 changed files with 122 additions and 24 deletions

View File

@ -70,8 +70,12 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
char path[256];
as = processGetAddrSpace(getCurrentThread()->process);
ret = syscallGet5args(userCtx, (unsigned int *)&uaddr_ptr, (unsigned int *)&size, (unsigned int *)&rights,
(unsigned int *)&flags, (unsigned int *)&userPath);
ret = syscallGet5args(userCtx, (unsigned int *)&uaddr_ptr, (unsigned int *)&size,
(unsigned int *)&rights, (unsigned int *)&flags,
(unsigned int *)&userPath);
if (ret)
break;
if (memcpyFromUser((vaddr_t)&uaddr, uaddr_ptr, sizeof(uaddr)) != sizeof(uaddr)) {
ret = -EFAULT;
@ -92,6 +96,20 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
}
break;
}
case SYSCALL_ID_MUNMAP: {
struct uAddrSpace *as;
uaddr_t uaddr;
size_t size;
ret = syscallGet2args(userCtx, (unsigned int *)&uaddr, (unsigned int *)&size);
if (ret)
break;
as = processGetAddrSpace(getCurrentThread()->process);
ret = uAddrSpaceUnmap(as, uaddr, size);
break;
}
default:
printf("Unknon syscall id %d\n", syscallId);
ret = -ENOENT;

View File

@ -10,6 +10,7 @@
#define SYSCALL_ID_TEST 5
#define SYSCALL_ID_BRK 6
#define SYSCALL_ID_MMAP 7
#define SYSCALL_ID_MUNMAP 8
#ifdef __KERNEL__
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);

View File

@ -1,5 +1,6 @@
#include "uaddrspace.h"
#include "alloc.h"
#include "errno.h"
#include "kernel.h"
#include "klibc.h"
#include "list.h"
@ -153,7 +154,9 @@ int uAddrSpaceUnmap(struct uAddrSpace *as, uaddr_t uaddr, size_t size)
{
if (uaddr < PAGING_BASE_USER_ADDRESS || uaddr > PAGING_TOP_USER_ADDRESS - size)
return -EINVAL;
if (!ALIGN(uaddr, PAGE_SIZE) || size <= 0)
if (!IS_ALIGNED(uaddr, PAGE_SIZE) || size <= 0)
return -EINVAL;
if(!as)
return -EINVAL;
size = ALIGN(size, PAGE_SIZE);
@ -168,13 +171,20 @@ int uAddrSpaceUnmap(struct uAddrSpace *as, uaddr_t uaddr, size_t size)
if (reg->addr >= uaddr && (reg->addr + reg->size <= uaddr + size)) {
list_delete_named(as->listVirtualReg, reg, prevInAddrSpace, nextInAddrSpace);
list_delete_named(reg->res->listVirtualReg, reg, prevInMappedRes, nextInMappedRes);
if (reg->res->ops && reg->res->ops->unmap)
reg->res->ops->unmap(reg, uaddr, size);
if (reg->res->ops && reg->res->ops->close)
reg->res->ops->close(reg);
if (reg == next)//singleton
next = NULL;
free(reg);
// Unmaped space is inside and smaller than the VR
// VR should be splitted
} else if (reg->addr > uaddr && (reg->addr + reg->size <= uaddr + size)) {
} else if (reg->addr > uaddr && (reg->addr + reg->size < uaddr + size)) {
struct uAddrVirtualReg *new =
(struct uAddrVirtualReg *)zalloc(sizeof(struct uAddrSpace));
if (!new)

View File

@ -21,6 +21,7 @@ static int zeroClose(struct uAddrVirtualReg *vreg)
ent->refCnt--;
if (ent->refCnt == 0) {
free(vreg->res->customData);
free(vreg->res);
}
return 0;
}

View File

@ -10,6 +10,7 @@
#define SYSCALL_ID_TEST 5
#define SYSCALL_ID_BRK 6
#define SYSCALL_ID_MMAP 7
#define SYSCALL_ID_MUNMAP 8
#ifdef __KERNEL__
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);

View File

@ -1,7 +1,9 @@
#include "libc.h"
#include "errno.h"
#include "list.h"
#include "minmax.h"
#include "swintr.h"
#include "sys/mman.h"
#include "syscall.h"
int errno = 0;
@ -732,5 +734,14 @@ void *mmap(void *addr, size_t len, int prot, int flags, char *path) {
if(!ret)
return addr;
errno = ret;
return (void *)-1;
return MAP_FAILED;
}
int munmap(void *addr, size_t len)
{
if (len == 0)
return -EINVAL;
return syscall2(SYSCALL_ID_MUNMAP, (unsigned int)&addr, len);
}

View File

@ -37,6 +37,7 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap) __attribut
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 munmap(void *addr, size_t len);
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)));

View File

@ -1,5 +1,7 @@
#include "errno.h"
#include "libc.h"
#include "stdarg.h"
#include "stddef.h"
#include "sys/mman.h"
#include "tiny.h"
@ -12,6 +14,7 @@ int func_help()
printf(" alloc: test allocation\n");
printf(" tiny: a tiny C-like interpreter\n");
printf(" mmap: test mmap \n");
printf(" munmap: test munmap \n");
return 0;
}
@ -57,17 +60,63 @@ int func_alloc()
return 0;
}
int func_mmap() {
struct mmapedArea {
void *addr;
size_t size;
struct mmapedArea *next;
};
static struct mmapedArea *listMmap = NULL;
int func_mmap()
{
struct mmapedArea *area = (struct mmapedArea *)malloc(sizeof(struct mmapedArea));
if (area == NULL) {
printf("Fail to allocate area\n");
return -1;
}
char *path = "/dev/zero";
void *mapAddr = mmap((void *)4096, 4096, PROT_READ | PROT_WRITE, 0, path);
void *mapAddr = mmap((void *)0, 4096, PROT_READ | PROT_WRITE, 0, path);
if (mapAddr == MAP_FAILED) {
printf("mmap failed errno %d\n", errno);
return -1;
}
printf("Zero mmaped at %p\n", mapAddr);
int data = *(int *)mapAddr;
*(int *)mapAddr = data;
area->addr = mapAddr;
area->size = 4096;
area->next = listMmap;
listMmap = area;
return 0;
}
int func_munmap()
{
if (!listMmap) {
printf("Nothing to unmap... mmap first! \n");
return -1;
}
struct mmapedArea *area = listMmap;
int ret = munmap(area->addr, area->size);
if (ret) {
printf("Fail to unmap area at 0x%p (size %d) error %d\n", area->addr, area->size, ret);
return ret;
}
listMmap = listMmap->next;
free(area);
return ret;
}
int main(int argc, char *argv[])
{
(void)argc;
@ -102,6 +151,10 @@ int main(int argc, char *argv[])
func_mmap();
continue;
}
if (strcmp(buf, "munmap") == 0) {
func_munmap();
continue;
}
}
return 0;
}

View File

@ -9,3 +9,5 @@
#define MAP_PRIVATE (1 << 1)
#define MAP_FIXED (1 << 2)
#define MAP_FAILED (void *)-1