Compare commits

...

5 Commits

Author SHA1 Message Date
Eric-Paul Ickhorn 4f5da10be1 Renamed run.sh to run.bash aswell 2023-05-29 23:45:29 +02:00
Eric-Paul Ickhorn 09ed173eef Renamed build.sh to build.bash to more clearly indicate bash 2023-05-29 23:43:36 +02:00
Eric-Paul Ickhorn 3a90af4704 Added cleanup-functionality to build.sh 2023-05-29 23:43:16 +02:00
Eric-Paul Ickhorn 1ad60a7351 Slightly bigger restructuring to get the dependencies into this repo 2023-05-29 22:59:31 +02:00
Eric-Paul Ickhorn 2f9ca93cb1 Basic userspace driver infrastructure 2023-05-29 15:42:56 +02:00
22 changed files with 679 additions and 171 deletions

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "libraries/libnoxos"]
path = libraries/libnoxos
url = https://git.nerdcult.net/noxos/libnoxos.git
[submodule "initrd/sources/userland"]
path = initrd/sources/userland
url = https://git.nerdcult.net/noxos/userland.git

View File

@ -3,6 +3,21 @@
# This file is part of noxos and licensed under the MIT open source license
set -e
PROJECT_ROOT=$PWD
OVMF_PATH=" "
if [[ -f "/usr/share/ovmf/x64/OVMF.fd" ]]; then
OVMF_PATH="/usr/share/ovmf/x64/OVMF.fd"
elif [[ -f "/usr/share/OVMF/OVMF.fd" ]]; then
OVMF_PATH="/usr/share/OVMF/OVMF.fd"
elif [[ -f "$PROECT_ROOT/build/ovmf/x64/OVMF.fd" ]]; then
OVMF_PATH="$PROECT_ROOT/build/ovmf/x64/OVMF.fd"
else
echo "Could not find OVMF-file! Did search at:"
echo "1) /usr/share/ovmf/x64/OVMF.fd"
echo "2) /usr/share/OVMF/OVMF.fd"
echo "3) $PROECT_ROOT/build/OVMF/x64/OVMF.fd"
exit 255
fi
workspace_setup() {
echo " --> Setting up workspace"
@ -25,14 +40,12 @@ check_toolchain() {
echo " |--> found xorriso"
hash qemu-system-x86_64
echo " |--> found qemu"
[ ! -d "/usr/share/ovmf/x64/" ] && echo "OVMF binaries not found!" && exit 255
echo " |--> found ovmf"
echo " --> All checks passed"
}
kernel_build() {
echo " --> Building kernel"
cd build/cmake
@ -42,17 +55,12 @@ kernel_build() {
echo ""
}
libnx_build() {
cd ../libnx
bash build.sh
cd ../kernel
libnoxos_build() {
cd libraries/libnoxos/
# bash build.sh
cd $PROJECT_ROOT
}
shell_build() {
gcc shell.c -o ramdisk/shell.elf -nostdlib -nolibc -fno-stack-protector -I../libnx/inc ../libnx/build/cmake/libnx.so
}
limine_install() {
echo " --> Installing Limine"
cd build
@ -67,7 +75,10 @@ limine_install() {
generate_initial_ramdisk() {
echo " --> Generating initrd"
tar -C ramdisk -cvf build/initrd.tar .
cd initrd
bash build.bash
cd $PROJECT_ROOT
tar -C initrd -cvf build/initrd.tar .
}
generate_image() {
@ -98,18 +109,25 @@ generate_image() {
echo ""
}
echo "!=====[ NoxOS build script ]=====!"
cleanup_files() {
rm -Rf build/
}
echo "!=====[ NOXOS build script ]=====!"
case $1 in
"check")
check_toolchain
;;
"cleanup")
cleanup_files
;;
*)
workspace_setup
kernel_build
[ ! -d "build/limine" ] && limine_install
libnx_build
shell_build
libnoxos_build
generate_initial_ramdisk
generate_image
;;

View File

@ -82,16 +82,18 @@ typedef struct {
json_node_T* root_node;
} json_T;
json_T* json_from_string (string_t str);
void json_destruct (json_T* json);
json_node_T* json_node_alloc (json_node_T* parent, json_node_type_E type, json_token_T* token);
void json_node_destruct (json_node_T* node);
void json_node_dump (json_node_T* node, uint32_t indent);
string_t json_node_type_to_string (json_node_type_E type);
void json_tokenize (json_T* json, string_t str);
bool json_parse (json_T* json);
bool json_parse_assignment (json_T* json, uint32_t* token_id, json_node_T* node);
bool json_parse_object (json_T* json, uint32_t* token_id, json_node_T* node);
bool json_parse_array (json_T* json, uint32_t* token_id, json_node_T* node);
json_T * json_from_string (string_t str);
void json_destruct (json_T* json);
json_node_T * json_node_alloc (json_node_T* parent, json_node_type_E type, json_token_T* token);
void json_node_destruct (json_node_T* node);
void json_node_dump (json_node_T* node, uint32_t indent);
string_t json_node_type_to_string (json_node_type_E type);
void json_tokenize (json_T* json, string_t str);
bool json_parse (json_T* json);
bool json_parse_assignment (json_T* json, uint32_t* token_id, json_node_T* node);
bool json_parse_object (json_T* json, uint32_t* token_id, json_node_T* node);
bool json_parse_array (json_T* json, uint32_t* token_id, json_node_T* node);
json_node_T * json_resolve_path (json_node_T *base, char *path);
#endif //NOXOS_JSON_H

View File

@ -0,0 +1,79 @@
#ifndef NOXOS_DEVICE_H
#define NOXOS_DEVICE_H
#include <utils/stdtypes.h>
#include <drivers/driver_manager.h>
typedef enum {
DEVICE_PCI = 1,
DEVICE_USB = 2,
DEVICE_VIRTUAL = 255
} device_category_E;
typedef enum {
DEVICE_CAPABILITY_TRANSMISSION,
DEVICE_CAPABILITY_STORAGE,
DEVICE_CAPABILITY_GRAPHICS,
DEVICE_CAPABILITY_AUDIO
} device_top_level_capability_E;
typedef struct device_capabilities_t {
device_top_level_capability_E *top_level;
struct device_transmission_capability_t {
// TODO
} transmission;
struct device_storage_capability_t {
char uuid[32];
uint64_t size;
} storage;
struct device_graphics_capability_t {
uint32_t fb_width;
uint32_t fb_height;
uint16_t bits_per_pixel;
} graphics;
struct device_audio_capability_t {
// TODO
} audio;
} device_capabilities_T;
typedef struct device_t {
uint32_t id;
device_category_E category;
void *specific;
driver_T *driver;
} device_T;
typedef struct device_manager_t {
uint32_t num_devices;
device_T *devices;
} device_manager_T;
extern device_manager_T g_device_manager;
void device_manager_init ();
void device_remove (device_T *device);
device_T * device_find (device_capabilities_T capabilities, uint32_t index, uint32_t *out_count);
#endif

View File

@ -0,0 +1,117 @@
#ifndef NOXOS_DRIVER_H
#define NOXOS_DRIVER_H
#include "utils/stdtypes.h"
#define DRIVER_COMMAND_SIZE 32
typedef enum {
DRIVER_UNKNOWN = 0x0000,
DRIVER_RESERVED = 0x0001,
// Specific Driver
DRIVER_MASS_STORAGE = 0x0101,
DRIVER_FILESYSTEM = 0x0102,
DRIVER_GRAPHICS = 0x0103,
DRIVER_AUDIO = 0x0104,
// Drivers which define the transmission of data but have multiple
// intended usages, such as USB for mass storage, input, etc..
DRIVER_TRANSMISSION = 0x0201,
DRIVER_USB_DEVICE = 0x0202,
DRIVER_PCI_DEVICE = 0x0203,
DRIVER_PCIE_DEVICE = 0x0204,
DRIVER_NVME_DEVICE = 0x0205,
DRIVER_BLUETOOTH = 0x0206,
DRIVER_ETHERNET = 0x0207,
// MISCELLANEOUS
DRIVER_EMULATION = 0x7fff
} driver_category_E;
typedef struct driver_mass_storage_t {
} driver_mass_storage_T;
typedef struct driver_configuration_t
{
uint16_t category;
uint16_t max_command_buffers;
uint16_t category_dependencies[16];
uint8_t reserved[220];
} driver_configuration_T;
typedef struct driver_command_buffer_config_t
{
uint64_t num_commands;
void *mapping_address;
uint8_t reserved[240];
} driver_command_buffer_config_T;
typedef struct driver_command_buffer_t
{
uint64_t command_capacity;
void *mapping_address;
} driver_command_buffer_T;
typedef struct driver_t // TODO: Accesses must be thread-safe
{
driver_category_E category;
uint32_t id;
uint16_t max_command_buffers;
driver_command_buffer_T *command_buffers;
} driver_T;
typedef struct driver_manager_t {
uint32_t max_drivers;
uint32_t num_drivers;
driver_T *drivers;
} driver_manager_T;
extern driver_manager_T g_driver_manager;
void driver_manager_init ();
void driver_manager_load_single_driver (char *driver_config_path);
void driver_manager_load_drivers (char *main_config_path);
uint32_t driver_manager_register_driver (driver_configuration_T *configuration);
driver_T * driver_manager_resolve_driver_id (uint32_t id);
// driver_add_command_buffer: Adds a command buffer to the 'command_buffers'-array in the given driver.
void driver_add_command_buffer (driver_T *driver, driver_command_buffer_config_T *configuration);
// driver_flush_command_buffer: Flushes the command buffer that 'buffer' points to,
// meaning that it executes all commands stored in it. 'buffer' doesn't need to be the first
// byte; the function will execute from the first command in a buffer even if some byte in the
// middle of the buffer is given into this function.
void driver_flush_command_buffer (driver_T *driver, void *buffer);
#endif

View File

@ -7,9 +7,10 @@
#include "utils/status.h"
typedef enum {
SYSCALLS_FILES = 0x01,
SYSCALLS_MEMORY = 0x02,
SYSCALLS_PROC = 0x03,
SYSCALLS_FILES = 0x00,
SYSCALLS_MEMORY = 0x01,
SYSCALLS_PROCESS = 0x02,
SYSCALLS_DRIVER = 0x03,
SYSCALLS_RUNTIME_LINKER = 0x04,
SYSCALLS_COMPATABILITY = 0x05,
@ -17,40 +18,44 @@ typedef enum {
}syscall_group_E;
typedef enum {
SYSCALL_FILES_OPEN = 0x0101,
SYSCALL_FILES_CLOSE = 0x0102,
SYSCALL_FILES_READ = 0x0103,
SYSCALL_FILES_WRITE = 0x0104,
SYSCALL_FILES_DELETE = 0x0105,
SYSCALL_FILES_LIST = 0x0106,
SYSCALL_FILES_INFO = 0x0107,
SYSCALL_FILES_OPEN = 0x0001,
SYSCALL_FILES_CLOSE = 0x0002,
SYSCALL_FILES_READ = 0x0003,
SYSCALL_FILES_WRITE = 0x0004,
SYSCALL_FILES_DELETE = 0x0005,
SYSCALL_FILES_LIST = 0x0006,
SYSCALL_FILES_INFO = 0x0007,
SYSCALL_MEMORY_MAP = 0x0201,
SYSCALL_MEMORY_UNMAP = 0x0202,
SYSCALL_MEMORY_LABEL = 0x0203,
SYSCALL_MEMORY_RANGE = 0x0204,
SYSCALL_MEMORY_ACCESS = 0x0205,
SYSCALL_MEMORY_MAP = 0x0101,
SYSCALL_MEMORY_UNMAP = 0x0102,
SYSCALL_MEMORY_LABEL = 0x0103,
SYSCALL_MEMORY_RANGE = 0x0104,
SYSCALL_MEMORY_ACCESS = 0x0105,
SYSCALL_PROCESS_CREATE = 0x0301,
SYSCALL_PROCESS_ENV = 0x0302,
SYSCALL_PROCESS_SIGNAL = 0x0303,
SYSCALL_PROCESS_THREAD_CREATE = 0x0304,
SYSCALL_PROCESS_THREAD_START = 0x0305,
SYSCALL_PROCESS_THREAD_PAUSE = 0x0306,
SYSCALL_PROCESS_THREAD_KILL = 0x0307,
SYSCALL_PROCESS_CREATE = 0x0201,
SYSCALL_PROCESS_ENV = 0x0202,
SYSCALL_PROCESS_SIGNAL = 0x0203,
SYSCALL_PROCESS_THREAD_CREATE = 0x0204,
SYSCALL_PROCESS_THREAD_START = 0x0205,
SYSCALL_PROCESS_THREAD_PAUSE = 0x0206,
SYSCALL_PROCESS_THREAD_KILL = 0x0207,
SYSCALL_DRIVER_REGISTER = 0x0301,
SYSCALL_DRIVER_CREATE_COMMAND_BUFFER = 0x0302,
SYSCALL_DRIVER_FLUSH_COMMAND_BUFFER = 0x0303,
SYSCALL_RUNTIME_LINKER_OPEN = 0x7f01,
SYSCALL_RUNTIME_LINKER_CLOSE = 0x7f02,
SYSCALL_RUNTIME_LINKER_LOAD_SYMBOL = 0x7f03,
SYSCALL_RUNTIME_LINKER_STATUS = 0x7f04,
SYSCALL_RUNTIME_LINKER_STANDARD_MOD = 0x7f05,
SYSCALL_RUNTIME_LINKER_OPEN = 0x0401,
SYSCALL_RUNTIME_LINKER_CLOSE = 0x0402,
SYSCALL_RUNTIME_LINKER_LOAD_SYMBOL = 0x0403,
SYSCALL_RUNTIME_LINKER_STATUS = 0x0404,
SYSCALL_RUNTIME_LINKER_STANDARD_MOD = 0x0405,
SYSCALL_COMPATABILITY_ABI_TYPE = 0x0501,
SYSCALL_COMPATABILITY_ABI_VERSION = 0x0502,
SYSCALL_COMPATABILITY_ACTION = 0x0503,
SYSCALL_COMPATABILITY_ABI_TYPE = 0x0501,
SYSCALL_COMPATABILITY_ABI_VERSION = 0x0502,
SYSCALL_COMPATABILITY_ACTION = 0x0503,
SYSCALL_KERNEL_SCHEDULER_START = 0xFF00,
SYSCALL_KERNEL_PANIC = 0xFF01
SYSCALL_KERNEL_SCHEDULER_START = 0xFF00,
SYSCALL_KERNEL_PANIC = 0xFF01
} syscall_E;
typedef enum {

View File

@ -45,6 +45,10 @@ struct process_T {
page_map_T* page_map;
elf_executable_T* executable;
file_descriptor_array_T* fd_array;
// driver: If this process is a driver, this tells the ID
// of that driver within the driver management system.
uint32_t driver;
pipe_T* stdout;
pipe_T stdin;
@ -52,12 +56,12 @@ struct process_T {
bitmap_T waiting;
uint32_t num_threads;
uint32_t num_threads;
void* threads;
bitmap_T thread_ids;
process_T* parent;
process_T* childs;
process_T* childs; // TODO: Must be 'children'
process_T* prev;
process_T* next;
};

11
inc/utils/file.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef NOXOS_FILE_UTILS_H
#define NOXOS_FILE_UTILS_H
#include <utils/stdtypes.h>
uint64_t file_get_length (char *path);
uint64_t file_read_into_buffer (char *path, void *buffer, uint64_t offset, uint64_t num_bytes);
#endif

3
initrd/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
build/

5
initrd/build.bash Normal file
View File

@ -0,0 +1,5 @@
#!/bin/bash
cd sources/userland/
# bash build.bash

@ -0,0 +1 @@
Subproject commit 9999b292ac52afd0ff629b566b372aeb5db978cf

1
libraries/libnoxos Submodule

@ -0,0 +1 @@
Subproject commit d5ed088f54751dd1874aaf2c2678cc5ab292434a

View File

@ -1,8 +0,0 @@
{
"PS2_ACPI_VALIDATION": true,
"LOG_GRAPHICAL": false,
"modules": {
"FAT32": "/initrd/modules/fat32.nxkm"
}
}

View File

@ -1,11 +0,0 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Proin molestie porta erat eu interdum.
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
Cras semper porta ligula quis condimentum.
Aliquam sed bibendum diam, sit amet gravida orci.
Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
Proin vitae urna vel magna luctus pulvinar.
Etiam diam diam, vulputate nec eros a, bibendum tristique velit.
Donec interdum consectetur vehicula.
Vestibulum gravida varius nisi non fringilla.
Nam eu accumsan erat, ac condimentum massa.

View File

@ -5,6 +5,11 @@ EMUFLAGS="-no-reboot -machine type=q35,accel=kvm -cpu max -m 256M \
-drive file=build/noxos.iso \
-chardev stdio,id=log,logfile=noxos.log -serial chardev:log"
OVMF_PATH="/usr/share/ovmf/x64/OVMF.fd"
if [[ -f "/usr/share/OVMF/OVMF.fd" ]]; then
OVMF_PATH="/usr/share/OVMF/OVMF.fd"
fi
emulate_bios() {
echo "<=====| Emulating |=====>"
qemu-system-x86_64 $EMUFLAGS
@ -12,13 +17,13 @@ emulate_bios() {
emulate_uefi() {
echo "<=====| Emulating in UEFI mode |=====>"
qemu-system-x86_64 -bios /usr/share/ovmf/x64/OVMF.fd $EMUFLAGS
qemu-system-x86_64 -bios $OVMF_PATH $EMUFLAGS
}
# qemu will wait for gdb to connect, before booting
emulate_debug() {
echo "<=====| Emulating in debug mode |=====>"
qemu-system-x86_64 -s -S -bios /usr/share/ovmf/x64/OVMF.fd $EMUFLAGS
qemu-system-x86_64 -s -S -bios $OVMF_PATH $EMUFLAGS
}
case $1 in

63
shell.c
View File

@ -1,63 +0,0 @@
#include "nox/stdio.h"
#include "nox/memory.h"
#include "nox/math.h"
#define COMMAND_BUFFER_SIZE 512
int read_command(char* command_buffer) {
char chr = 0;
int pos = 0;
while (chr != '\n') {
chr = getc();
switch (chr) {
case '\b': {
if (pos > 0) pos--;
break;
}
default: {
if (pos < COMMAND_BUFFER_SIZE) {
command_buffer[pos] = chr;
pos++;
}
break;
}
}
}
command_buffer[--pos] = '\0';
return pos;
}
bool handle_command(char* command_buffer) {
int command_length = strlen(command_buffer);
if (command_length < 2) return true;
if (memcmp(command_buffer, "help", min(4, command_length))) {
printf("Commands:\n");
printf(" help | shows this help message\n");
printf(" exit | exit noxsh\n");
} else if (memcmp(command_buffer, "exit", min(4, command_length))) {
printf("exiting noxsh\n");
return false;
} else {
printf("Unknown command: '");
printf(command_buffer);
printf("'\n");
}
return true;
}
void _start() {
printf("Welcome to the nox shell.\ntype 'help' for a list of commands\n");
bool running = true;
while(running) {
printf("\n[/]=> ");
char command_buffer[COMMAND_BUFFER_SIZE];
read_command(command_buffer);
running = handle_command(command_buffer);
}
}

View File

@ -35,39 +35,41 @@ void kernel_init(boot_info_T* boot_info) {
idt_init();
pic_init();
pit_set_divisor(PIT_DIVISOR);
paging_init();
CORE_INTERRUPTS_ENABLE
memory_allocator_init((void*)MEM_REGION_KERNEL_HEAP);
graphics_renderer_init(boot_info);
vfs_init(boot_info);
sysconfig_init();
if (g_sysconfig->log_graphical) graphical_log_init();
scheduler_init(boot_info);
acpi_init(boot_info);
module_manager_init();
drive_manager_init();
pci_init();
driver_manager_init();
tty_init();
ps2_controller_init();
}
void kmain(boot_info_T boot_info) {
limine_terminal_print(&boot_info, "Booting NoxOS...\n");
log(LOG_DEBUG, "Booting NoxOS");
limine_terminal_print(&boot_info, "Booting NOXOS...\n");
log(LOG_DEBUG, "Booting NOXOS");
kernel_init(&boot_info);

View File

@ -0,0 +1,28 @@
#include <drivers/device_manager.h>
#include <drivers/builtin/fs/vfs.h>
device_manager_T g_device_manager;
void device_manager_init() {
}
void device_remove(device_T *device) {
}
device_T * device_find(device_capabilities_T capabilities, uint32_t index, uint32_t *out_count) {
}

View File

@ -0,0 +1,140 @@
#include <drivers/driver_manager.h>
#include <drivers/builtin/json.h>
#include <utils/file.h>
#include <utils/memory.h>
#include <utils/logger.h>
driver_manager_T g_driver_manager;
void driver_manager_init()
{
log(LOG_INFO, "Starting Driver Manager!");
driver_manager_T manager;
manager.max_drivers = 1024;
manager.num_drivers = 0;
manager.drivers = memory_allocate(sizeof(driver_T) * manager.max_drivers);
g_driver_manager = manager;
}
void driver_manager_load_single_driver(char *driver_config_path)
{ // TODO
uint64_t len_file = file_get_length(driver_config_path);
void *content = memory_allocate(len_file+1);
file_read_into_buffer(driver_config_path, content, 0, len_file);
((uint8_t *) content)[len_file] = 0x00; // End it with a NULL-terminator
json_T *config_json = json_from_string(content);
// config_json->root_node->
}
void driver_manager_load_drivers(char *main_config_path)
{
}
driver_T * driver_manager_find_free_driver_slot()
{
driver_T *drivers = g_driver_manager.drivers;
uint32_t index = 0;
while(index < g_driver_manager.max_drivers)
{
if(drivers[index].category == DRIVER_UNKNOWN) return &drivers[index];
++index;
}
return NULL; // TODO: Resize array
}
uint32_t driver_manager_find_unused_driver_id()
{
driver_T *drivers = g_driver_manager.drivers;
uint32_t index = 0;
uint32_t id = 0;
while(id < 131072)
{
while(index < g_driver_manager.max_drivers)
{
if(drivers[index].id == id) break;
++index;
}
++id;
}
return id;
}
bool driver_is_configuration_valid(driver_configuration_T *configuration)
{
if(configuration->max_command_buffers == 0) return false;
if(configuration->max_command_buffers > 32) return false;
return true;
}
uint32_t driver_manager_register_driver(driver_configuration_T *configuration)
{
if(!driver_is_configuration_valid(configuration)) return 0; // TODO: Log
driver_T *driver = driver_manager_find_free_driver_slot();
driver->category = DRIVER_RESERVED;
driver->max_command_buffers = configuration->max_command_buffers;
driver->command_buffers = memory_allocate(sizeof(driver_T) * driver->max_command_buffers);
driver->id = driver_manager_find_unused_driver_id();
driver->category = configuration->category; // Activate the entry
return driver->id;
}
driver_T * driver_manager_resolve_driver_id(uint32_t id)
{
driver_T *drivers = g_driver_manager.drivers;
uint32_t index = 0;
while(index < g_driver_manager.max_drivers)
{
if(drivers[index].id == id) return &drivers[index];
++index;
}
return NULL;
}
driver_command_buffer_T * driver_find_free_command_buffer_slot(driver_T *driver)
{
driver_command_buffer_T *buffers = driver->command_buffers;
uint32_t index = 0;
while(index < driver->max_command_buffers)
{
if(buffers[index].mapping_address == NULL) return &buffers[index];
++index;
}
return NULL;
}
void driver_add_command_buffer(driver_T *driver, driver_command_buffer_config_T *configuration)
{
driver_command_buffer_T *buffer = driver_find_free_command_buffer_slot(driver);
buffer->command_capacity = configuration->num_commands;
buffer->mapping_address = configuration->mapping_address;
}
void driver_flush_command_buffer(driver_T *driver, void *buffer)
{
}

View File

@ -6,6 +6,8 @@
#include "utils/memory.h"
#include "proc/scheduler.h"
#include "drivers/builtin/fs/vfs.h"
#include <drivers/driver_manager.h>
#include "mm/page_frame.h"
#include "mm/region.h"
@ -25,9 +27,9 @@ void syscall_handle_nx_fopen(cpu_state_T* state) {
void syscall_handle_nx_fclose(cpu_state_T* state) {
file_descriptor_t fd = (file_descriptor_t)state->rdi; // arg1
file_descriptor_free(scheduler_get_current_process()->fd_array, fd);
state->rax = STATUS_SUCCESS;
}
@ -188,11 +190,13 @@ void syscall_handle_nx_mmap(cpu_state_T* state) {
}
void syscall_handle_nx_munmap(cpu_state_T* state) {
void* addr = (void*)state->rdi; // arg1
uint64_t n = state->rsi; // arg2
void *addr = (void *) state->rdi; // arg1
uint64_t n = state->rsi; // arg2
if ((uint64_t)&addr[n * PFRAME_SIZE] > MEM_REGION_KERNEL ||
(uint64_t)addr < MEM_REGION_PROCESS_USABLE) {
if(
((uint64_t) &addr[n * PFRAME_SIZE] > MEM_REGION_KERNEL) ||
((uint64_t) addr < MEM_REGION_PROCESS_USABLE)
) {
state->rax = STATUS_PERMISSION_DENIED;
return;
}
@ -264,6 +268,124 @@ void syscall_handle_nx_psignal(cpu_state_T* state) {
state->rax = STATUS_SUCCESS;
}
uint64_t ceil_to(uint64_t base, uint64_t factor)
{
return base + (base % factor);
}
uint64_t floor_to(uint64_t base, uint64_t factor)
{
return (base + (base % factor)) - factor;
}
bool are_process_pages_unused(process_T *process, void *address, uint64_t num_pages)
{
page_map_T *process_page_map = process->page_map;
uint64_t page_index = 0;
while(page_index < num_pages)
{
if(page_map_check_memory(
process_page_map,
&address[page_index * PFRAME_SIZE])
) {
return false;
}
++page_index;
}
return true;
}
bool are_process_memory_bytes_unused(process_T *process, void *address, uint64_t num_bytes)
{
uint64_t first_full_page_address = floor_to(address, PFRAME_SIZE);
uint64_t num_pages = ceil_to(address+num_bytes, PFRAME_SIZE) / PFRAME_SIZE;
return are_process_pages_unused(process, first_full_page_address, num_pages);
}
void mark_memory_region_for_process(process_T *process,
void *address, uint64_t num_pages,
bool read_write, bool executable)
{
uint64_t map_flags = 0;
if(read_write) map_flags |= PM_FLAG_READ_WRITE;
if(!executable) map_flags |= PM_FLAG_NO_EXECUTE;
page_map_T *process_page_map = process->page_map;
uint64_t page_index = 0;
while(page_index < num_pages)
{
page_map_map_memory(process_page_map, &address[page_index * PFRAME_SIZE], pframe_request(), map_flags);
++page_index;
}
}
// map_memory_for_user: Returns FALSE if the action failed and TRUE otherwise.
bool map_memory_for_process(process_T *process,void *address, uint64_t num_pages, bool read_write, bool executable)
{
if(address == NULL)
{
return false;
}
if(!are_process_pages_unused(process, address, num_pages))
{
return false;
}
mark_memory_region_for_process(process, address, num_pages, read_write, executable);
return true;
}
void syscall_handle_nx_drv_register_driver(cpu_state_T* state)
{
void *configuration = state->rdi;
process_T *caller = scheduler_get_current_process();
// Check permissions
if(are_process_memory_bytes_unused(caller, configuration, 256))
{
state->rax = STATUS_RESOURCE_NOT_AVAILABLE;
return;
}
caller->driver = driver_manager_register_driver(configuration);
}
void syscall_handle_nx_drv_create_command_buffer(cpu_state_T* state)
{
void *address = (void *) state->rdi;
uint64_t wanted_commands = state->rsi;
uint64_t num_pages = ceil_to(wanted_commands * DRIVER_COMMAND_SIZE, PFRAME_SIZE) / PFRAME_SIZE;
process_T *caller = scheduler_get_current_process();
driver_T *driver = driver_manager_resolve_driver_id(caller->driver);
if(map_memory_for_process(caller, address, num_pages, true, false))
{
driver_command_buffer_config_T buffer_config;
buffer_config.num_commands = num_pages;
buffer_config.mapping_address = address;
driver_add_command_buffer(driver, &buffer_config);
state->rax = address;
return;
}
// TODO: Select an address for the process and re-run map_memory_for_process.
state->rax = STATUS_RESOURCE_NOT_AVAILABLE;
}
void syscall_handle_nx_drv_flush_command_buffer(cpu_state_T* state)
{
void *command_buffer = state->rsi;
process_T *caller = scheduler_get_current_process();
driver_T *driver = driver_manager_resolve_driver_id(caller->driver);
driver_flush_command_buffer(driver, command_buffer);
}
cpu_state_T* syscall_handle(cpu_state_T* state) {
cpu_state_T* return_state = state;
syscall_group_E group_id = (state->rax & 0xFF00) >> 8;
@ -315,7 +437,7 @@ cpu_state_T* syscall_handle(cpu_state_T* state) {
break;
}
case SYSCALLS_PROC: {
case SYSCALLS_PROCESS: {
switch (state->rax) {
case SYSCALL_PROCESS_CREATE: {
syscall_handle_nx_pcreate(state);
@ -328,7 +450,23 @@ cpu_state_T* syscall_handle(cpu_state_T* state) {
}
break;
}
case SYSCALLS_DRIVER: {
switch(state->rax) {
case SYSCALL_DRIVER_REGISTER: {
syscall_handle_nx_drv_register_driver(state);
} break;
case SYSCALL_DRIVER_CREATE_COMMAND_BUFFER: {
syscall_handle_nx_drv_create_command_buffer(state);
} break;
case SYSCALL_DRIVER_FLUSH_COMMAND_BUFFER: {
syscall_handle_nx_drv_flush_command_buffer(state);
} break;
}
}
case SYSCALLS_RUNTIME_LINKER: {
break;
}
@ -369,4 +507,4 @@ cpu_state_T* syscall_handle(cpu_state_T* state) {
}
return return_state;
}
}

20
src/utils/file.c Normal file
View File

@ -0,0 +1,20 @@
#include <utils/file.h>
#include <drivers/builtin/fs/vfs.h>
uint64_t file_get_length(char *path)
{
vfs_node_T *file = vfs_resolve_path(&g_root_fs, path);
if(file == NULL) return 0;
return file->size;
}
uint64_t file_read_into_buffer(char *path, void *buffer, uint64_t offset, uint64_t num_bytes)
{
vfs_node_T *file = vfs_resolve_path(&g_root_fs, path);
if(file == NULL) return 0;
uint64_t actual_read_bytes = vfs_file_read(file, offset, num_bytes, buffer);
vfs_node_destruct(file);
return actual_read_bytes;
}

5
update.bash Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
git submodule update libraries/libnoxos/
git submodule update initrd/sources/userland/