kernel_args: redo implementation

This commit is contained in:
Matheus
2025-09-07 23:09:34 -03:00
parent a3a51abfed
commit 80786cf97a
15 changed files with 198 additions and 107 deletions
-77
View File
@@ -1,77 +0,0 @@
#include <kernel/cmdline.h>
#include <kernel/alloc.h>
#include <hashtable.h>
#include <limine.h>
#include <logging.h>
static volatile struct limine_kernel_file_request kernel_file_request = {
.id = LIMINE_KERNEL_FILE_REQUEST,
.revision = 0
};
static hashtable_t pair_table;
char *cmdline_get(char *key) {
void *v;
return hashtable_get(&pair_table, &v, key, strlen(key)) == 0 ? v : NULL;
}
void cmdline_parse() {
__assert(hashtable_init(&pair_table, 16) == 0);
__assert(kernel_file_request.response);
struct limine_file *kernel_file = kernel_file_request.response->kernel_file;
__assert(kernel_file);
char *cmdline = kernel_file->cmdline;
__assert(cmdline);
size_t buffer_len = strlen(cmdline) + 1;
char buffer[buffer_len];
memset(buffer, 0, buffer_len);
char *cmdline_ptr = cmdline;
char *buffer_ptr = buffer;
bool do_convert = true;
while (*cmdline_ptr) {
char cmd_char = *cmdline_ptr++;
if (cmd_char == ' ' && do_convert)
*buffer_ptr++ = '\0';
else if (cmd_char == '"') {
do_convert = !do_convert;
--buffer_len;
} else
*buffer_ptr++ = cmd_char;
}
buffer[buffer_len - 1] = '\0';
int i = 0;
while (i < buffer_len) {
char *iterator = &buffer[i];
bool pair = false;
while (*iterator) {
if (*iterator == '=') {
pair = true;
*iterator = '\0';
}
++iterator;
}
size_t key_len = strlen(&buffer[i]);
if (pair) {
char *value_ptr = &buffer[i + key_len + 1];
size_t value_len = strlen(value_ptr);
char *value = alloc(value_len) + 1;
__assert(value);
strcpy(value, value_ptr);
__assert(hashtable_set(&pair_table, value, &buffer[i], key_len, true) == 0);
i += value_len + 1;
} else {
char *value = alloc(key_len + 1);
__assert(value);
strcpy(value, &buffer[i]);
__assert(hashtable_set(&pair_table, value, &buffer[i], key_len, true) == 0);
}
i += key_len + 1;
}
}
+82
View File
@@ -0,0 +1,82 @@
#include <kernel/kernel_args.h>
#include <kernel/alloc.h>
#include <hashtable.h>
#include <limine.h>
#include <logging.h>
#define TOTAL_ARGUMENTS_CHARACTER_LIMIT 4096
static volatile struct limine_kernel_file_request kernel_file_request = {
.id = LIMINE_KERNEL_FILE_REQUEST,
.revision = 0
};
static size_t allocated = 0;
static char argument_buffer[TOTAL_ARGUMENTS_CHARACTER_LIMIT];
extern kernel_argument_t *kernel_arguments[];
extern kernel_argument_t *kernel_arguments_end[];
static void insert_argument(const char *key, const char *value) {
size_t argument_count = ((uintptr_t)kernel_arguments_end - (uintptr_t)kernel_arguments) / sizeof(kernel_argument_t *);
char *buffer = &argument_buffer[allocated];
if (value) {
strcpy(buffer, value);
allocated += strlen(value) + 1;
}
for (int i = 0; i < argument_count; ++i) {
if (strcmp(kernel_arguments[i]->key, key))
continue;
kernel_arguments[i]->found = true;
switch (kernel_arguments[i]->type) {
case KERNEL_ARGUMENT_TYPE_STR:
kernel_arguments[i]->value_str = value ? buffer : NULL;
break;
case KERNEL_ARGUMENT_TYPE_INT:
kernel_arguments[i]->value_int = value ? atoll(buffer) : 0;
break;
}
}
}
void kernel_arguments_parse(void) {
__assert(kernel_file_request.response);
const char *cmdline = kernel_file_request.response->kernel_file->cmdline;
__assert(cmdline);
size_t length = min(strlen(cmdline), TOTAL_ARGUMENTS_CHARACTER_LIMIT);
char temp_buffer[length];
memcpy(temp_buffer, cmdline, length);
bool escaping = false;
const char *key = temp_buffer[0] == ' ' ? NULL : temp_buffer;
const char *value = NULL;
for (int i = 0; i < length; ++i) {
if (temp_buffer[i] == '"') {
escaping = !escaping;
temp_buffer[i] = '\0';
continue;
}
if (temp_buffer[i] == '=') {
value = &temp_buffer[i + 1];
temp_buffer[i] = '\0';
continue;
}
if (temp_buffer[i] == ' ' && !escaping) {
temp_buffer[i] = '\0';
if (key)
insert_argument(key, value);
key = &temp_buffer[i + 1];
value = NULL;
}
}
if (key != temp_buffer + length)
insert_argument(key, value);
}
+4 -2
View File
@@ -8,7 +8,7 @@
#include <kernel/scheduler.h>
#include <kernel/elf.h>
#include <kernel/devfs.h>
#include <kernel/cmdline.h>
#include <kernel/kernel_args.h>
static hashtable_t pid_table;
static scache_t *processcache;
@@ -292,6 +292,8 @@ void proc_exit(void) {
}
}
DEFINE_KERNEL_ARGUMENT(initarg, char *);
void proc_run_init() {
printf("proc: loading /init\n");
@@ -358,7 +360,7 @@ void proc_run_init() {
proc->root = vfsroot;
VOP_HOLD(vfsroot);
char *argv[] = {"/init", cmdline_get("initarg"), NULL};
char *argv[] = {"/init", GET_KERNEL_ARGUMENT(initarg, char *), NULL};
char *envp[] = {NULL};
void *stack = elf_preparestack(STACK_TOP, &auxv64, argv, envp, "/init");
-1
View File
@@ -10,7 +10,6 @@
#include <semaphore.h>
#include <kernel/devfs.h>
#include <kernel/jobctl.h>
#include <kernel/cmdline.h>
#include <kernel/auth.h>
#include <arch/smp.h>
#include <kernel/init.h>
+4 -2
View File
@@ -1,9 +1,11 @@
#include <kernel/syscalls.h>
#include <kernel/scheduler.h>
#include <kernel/cmdline.h>
#include <kernel/kernel_args.h>
#include <kernel/alloc.h>
#include <arch/cpu.h>
DEFINE_KERNEL_ARGUMENT(nomultithread, bool);
syscallret_t syscall_newthread(context_t *, void *entry, void *stack) {
syscallret_t ret = {
.ret = -1
@@ -11,7 +13,7 @@ syscallret_t syscall_newthread(context_t *, void *entry, void *stack) {
// TODO perhaps clean up threads here as well
// if the kernel was specified to have no user threading in the cmdline
if (cmdline_get("nomultithread")) {
if (GET_KERNEL_ARGUMENT(nomultithread, bool)) {
ret.errno = ENOSYS;
return ret;
}