mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
kernel_args: redo implementation
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user