Compare commits

..

2 Commits

Author SHA1 Message Date
7f8a8cdcaf
kernel, libc: Add an usleep() system call and use that to implement usleep() and sleep() in libc
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-22 15:00:20 +01:00
d5b1d72396
x86_64/MMU: Map the kernel page directory to virtual memory
This avoids depending on the kernel address space to create a new userspace one,
since there is no physical memory access.

This was fine for a single process, since its address space was created from the kernel one
and no more address spaces were created,
but for two or more, this started to become problematic, since we would create one address space
while being in another process's address space, which has no direct mapping of physical memory.
2023-01-22 14:46:03 +01:00
8 changed files with 48 additions and 3 deletions

View File

@ -22,6 +22,7 @@ set(SOURCES
src/sys/console_write.cpp
src/sys/clock_gettime.cpp
src/sys/allocate_memory.cpp
src/sys/usleep.cpp
src/InitRD.cpp
src/ELF.cpp
)

View File

@ -1,4 +1,5 @@
#include "arch/MMU.h"
#include "Log.h"
#include "memory/MemoryManager.h"
#include <luna/CString.h>
#include <luna/Result.h>
@ -9,6 +10,7 @@
#pragma GCC diagnostic ignored "-Wconversion"
PageDirectory* g_kernel_directory;
u64 g_kernel_directory_virt;
void PageTableEntry::set_address(u64 addr)
{
@ -278,12 +280,18 @@ namespace MMU
{
PageDirectory* const dir = get_page_directory();
g_kernel_directory = dir;
const u64 paddr = (u64)dir;
PageTableEntry& recursive_entry = dir->entries[rindex];
recursive_entry.read_write = true;
recursive_entry.present = true;
recursive_entry.set_address(paddr);
flush_all();
g_kernel_directory_virt =
MemoryManager::get_kernel_mapping_for_frames((u64)dir, 1, MMU::ReadWrite | MMU::NoExecute).value();
kdbgln("MMU init page directory (ring0): virt %#.16lx, phys %p", g_kernel_directory_virt, g_kernel_directory);
}
Result<PageDirectory*> create_page_directory_for_userspace()
@ -298,7 +306,9 @@ namespace MMU
recursive_entry.present = true;
recursive_entry.set_address(directory_phys);
directory->entries[511] = g_kernel_directory->entries[511];
kdbgln("MMU init page directory (ring3): virt %p, phys %#.16lx", directory, directory_phys);
directory->entries[511] = ((PageDirectory*)g_kernel_directory_virt)->entries[511];
// From now on, we're only going to use the physical address, since accessing the PageDirectory will be dealt
// with using recursive mapping. So let's make sure we don't leak any VM.

12
kernel/src/sys/usleep.cpp Normal file
View File

@ -0,0 +1,12 @@
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
#include <sys/types.h>
Result<u64> sys_usleep(Registers*, SyscallArgs args)
{
useconds_t us = (useconds_t)args[0];
kernel_sleep(us / 1000);
return 0;
}

View File

@ -1,4 +1,4 @@
file(GLOB HEADERS include/*.h)
file(GLOB_RECURSE HEADERS include/*.h)
set(SOURCES
${HEADERS}

View File

@ -11,5 +11,6 @@
typedef int pid_t;
typedef __i64_t time_t;
typedef __u16_t mode_t;
typedef __u64_t useconds_t;
#endif

View File

@ -24,6 +24,12 @@ extern "C"
/* Calls the operating system kernel for a specific service. */
long syscall(long num, ...);
/* Sleeps for X microseconds. */
int usleep(useconds_t us);
/* Sleeps for X seconds. */
unsigned long sleep(unsigned long seconds);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,7 @@
#include <bits/errno-return.h>
#include <stdarg.h>
#include <stdint.h>
#include <sys/syscall.h>
#include <unistd.h>
extern "C" long arch_invoke_syscall(long, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
@ -23,4 +25,16 @@ extern "C"
return rc;
}
int usleep(useconds_t us)
{
long rc = syscall(SYS_usleep, us);
__errno_return(rc, int);
}
unsigned long sleep(unsigned long seconds)
{
syscall(SYS_usleep, seconds * 1000000);
return 0;
}
}

View File

@ -1,6 +1,7 @@
#pragma once
#define enumerate_syscalls(_e) _e(exit) _e(console_write) _e(clock_gettime) _e(allocate_memory) _e(deallocate_memory)
#define enumerate_syscalls(_e) \
_e(exit) _e(console_write) _e(clock_gettime) _e(allocate_memory) _e(deallocate_memory) _e(usleep)
enum Syscalls
{