matos/userspace/main_user.c

189 lines
5.1 KiB
C
Raw Normal View History

#include "errno.h"
2021-11-05 23:02:23 +01:00
#include "libc.h"
2022-09-03 23:41:33 +02:00
#include "stdarg.h"
#include "stddef.h"
2024-02-10 21:26:01 +01:00
#include "sys/mman.h"
2024-02-14 23:20:46 +01:00
#include "thread.h"
2023-03-21 23:11:56 +01:00
#include "tiny.h"
2024-02-14 18:43:47 +01:00
#include "unistd.h"
2021-11-06 00:13:40 +01:00
int func_help()
{
printf("\nAvailable Commands:\n");
2023-11-11 00:09:00 +01:00
printf(" help: this help\n");
printf(" suicide: userspace self kill\n");
printf(" syscall5: a syscall with parameters over the stack \n");
printf(" alloc: test allocation\n");
printf(" tiny: a tiny C-like interpreter\n");
printf(" mmap: test mmap \n");
printf(" munmap: test munmap \n");
2024-02-13 00:19:39 +01:00
printf(" thread: run a user thread\n");
2021-11-06 00:13:40 +01:00
return 0;
}
int func_suicide()
{
printf("User is about to suicide\n");
int *yolo = 0;
*yolo = 1;
return 0;
}
2023-11-11 00:09:00 +01:00
char *initialHeap = 0;
2022-09-03 23:41:33 +02:00
int func_alloc()
{
if (initialHeap == 0) {
initialHeap = sbrk(0);
2022-08-09 16:15:00 +02:00
}
2022-09-03 23:41:33 +02:00
printf("Testing allocation\n");
2024-01-29 21:47:24 +01:00
int allocSize = 4096 * 2;
char *currentHeap = sbrk(0);
2022-09-03 23:41:33 +02:00
if (currentHeap - initialHeap < allocSize) {
brk(initialHeap + allocSize);
2022-08-09 16:15:00 +02:00
}
2022-09-03 23:41:33 +02:00
int *allocatedData = (int *)initialHeap;
for (unsigned int i = 0; i < allocSize / sizeof(int); i++) {
allocatedData[i] = i;
2024-01-29 21:47:24 +01:00
}
printf("Success\nTesting malloc\n");
uintptr_t heap = (uintptr_t)sbrk(0);
for (int i = 0; i < 12; i++) {
void *ptr = malloc(1 << i);
printf("malloc size %d: 0x%p\n", (1 << i), ptr);
if (ptr == NULL) {
printf("Malloc failed\n");
}
memset(ptr, 0, 1 << i);
free(ptr);
2022-08-09 16:15:00 +02:00
}
2024-01-29 21:47:24 +01:00
uintptr_t newHeap = (uintptr_t)sbrk(0);
printf("Malloc used %dB\n", newHeap - heap);
2022-09-03 23:41:33 +02:00
2022-08-09 16:15:00 +02:00
return 0;
}
struct mmapedArea {
void *addr;
size_t size;
struct mmapedArea *next;
};
static struct mmapedArea *listMmap = NULL;
2023-03-24 23:43:09 +01:00
int func_mmap()
{
struct mmapedArea *area = (struct mmapedArea *)malloc(sizeof(struct mmapedArea));
if (area == NULL) {
printf("Fail to allocate area\n");
return -1;
}
2024-02-07 23:17:55 +01:00
char *path = "/dev/zero";
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;
}
2024-02-07 23:17:55 +01:00
printf("Zero mmaped at %p\n", mapAddr);
int data = *(int *)mapAddr;
*(int *)mapAddr = data;
2023-03-24 23:43:09 +01:00
area->addr = mapAddr;
area->size = 4096;
area->next = listMmap;
listMmap = area;
2023-03-24 23:43:09 +01:00
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;
}
printf("unmap done\n");
listMmap = listMmap->next;
free(area);
return ret;
}
2024-02-13 00:19:39 +01:00
static void *print_hello(void *arg) {
(void)arg;
2024-02-15 18:40:45 +01:00
printf("Hello World from thread %lu\n", gettid());
2024-02-16 00:47:47 +01:00
usleep(100);
2024-02-13 00:19:39 +01:00
return NULL;
}
int func_thread() {
2024-02-14 23:20:46 +01:00
pthread_t id;
void *retval;
2024-02-14 23:20:46 +01:00
thread_create(&id, print_hello, NULL, 4096);
thread_join(id, &retval);
2024-02-13 00:19:39 +01:00
return 0;
}
int main(int argc, char *argv[]) {
2021-11-05 23:02:23 +01:00
(void)argc;
(void)argv;
2021-11-06 00:13:40 +01:00
char buf[64];
2024-02-14 23:20:46 +01:00
assert(getpid() == gettid());
2021-11-08 22:52:46 +01:00
printf("Shell starting... type \"help\" for help\n");
2021-11-06 00:13:40 +01:00
while (1) {
printf(">");
if (readline(buf, sizeof(buf)))
continue;
if (strcmp(buf, "help") == 0) {
func_help();
continue;
}
if (strcmp(buf, "suicide") == 0) {
func_suicide();
continue;
}
if (strcmp(buf, "syscall5") == 0) {
testSycall5(1, 2, 3, 4, 5);
continue;
}
2022-08-09 16:15:00 +02:00
if (strcmp(buf, "alloc") == 0) {
func_alloc();
continue;
}
2023-03-21 23:11:56 +01:00
if (strcmp(buf, "tiny") == 0) {
pthread_t id;
void *retval;
thread_create(&id, func_tiny, NULL, 4096);
thread_join(id, &retval);
2023-03-21 23:11:56 +01:00
continue;
}
2023-03-24 23:43:09 +01:00
if (strcmp(buf, "mmap") == 0) {
func_mmap();
continue;
}
if (strcmp(buf, "munmap") == 0) {
func_munmap();
continue;
}
2024-02-13 00:19:39 +01:00
if (strcmp(buf, "thread") == 0) {
func_thread();
continue;
}
2021-11-06 00:13:40 +01:00
}
2021-11-05 23:02:23 +01:00
return 0;
}