From d4334699e310773b61205ebd60aa8f3730b74a5e Mon Sep 17 00:00:00 2001 From: mintsuki Date: Fri, 24 Mar 2023 01:02:31 +0100 Subject: [PATCH] limine: Implement internal modules concept --- common/protos/limine.c | 38 +++++++++++++++++++++++++++++++++----- limine.h | 12 ++++++++++++ test/limine.c | 14 +++++++++++++- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/common/protos/limine.c b/common/protos/limine.c index 1163cfa7..74c8722b 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -194,6 +194,17 @@ static uint64_t reported_addr(void *addr) { return (uint64_t)(uintptr_t)addr + direct_map_offset; } +#define get_phys_addr(addr) ({ \ + __auto_type get_phys_addr__addr = (addr); \ + uintptr_t get_phys_addr__r; \ + if (get_phys_addr__addr & ((uint64_t)1 << 63)) { \ + get_phys_addr__r = physical_base + (get_phys_addr__addr - virtual_base); \ + } else { \ + get_phys_addr__r = get_phys_addr__addr; \ + } \ + get_phys_addr__r; \ +}) + static struct limine_file get_file(struct file_handle *file, char *cmdline) { struct limine_file ret = {0}; @@ -623,6 +634,12 @@ FEAT_START break; } + size_t config_module_count = module_count; + + if (module_request->revision >= 1) { + module_count += module_request->internal_module_count; + } + if (module_count == 0) { break; } @@ -633,12 +650,23 @@ FEAT_START struct limine_file *modules = ext_mem_alloc(module_count * sizeof(struct limine_file)); for (size_t i = 0; i < module_count; i++) { - struct conf_tuple conf_tuple = - config_get_tuple(config, i, - "MODULE_PATH", "MODULE_CMDLINE"); + char *module_path; + char *module_cmdline; - char *module_path = conf_tuple.value1; - char *module_cmdline = conf_tuple.value2; + if (i < config_module_count) { + struct conf_tuple conf_tuple = + config_get_tuple(config, i, + "MODULE_PATH", "MODULE_CMDLINE"); + + module_path = conf_tuple.value1; + module_cmdline = conf_tuple.value2; + } else { + uint64_t *internal_modules = (void *)get_phys_addr(module_request->internal_modules); + struct limine_internal_module *internal_module = (void *)get_phys_addr(internal_modules[i - config_module_count]); + + module_path = (char *)get_phys_addr(internal_module->path); + module_cmdline = (char *)get_phys_addr(internal_module->cmdline); + } if (module_cmdline == NULL) { module_cmdline = ""; diff --git a/limine.h b/limine.h index 13688842..44e14c40 100644 --- a/limine.h +++ b/limine.h @@ -355,6 +355,14 @@ struct limine_kernel_file_request { #define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } +#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) + +struct limine_internal_module { + LIMINE_PTR(const char *) path; + LIMINE_PTR(const char *) cmdline; + uint64_t flags; +}; + struct limine_module_response { uint64_t revision; uint64_t module_count; @@ -365,6 +373,10 @@ struct limine_module_request { uint64_t id[4]; uint64_t revision; LIMINE_PTR(struct limine_module_response *) response; + + /* Revision 1 */ + uint64_t internal_module_count; + LIMINE_PTR(struct limine_internal_module **) internal_modules; }; /* RSDP */ diff --git a/test/limine.c b/test/limine.c index 27ec7b20..9ac0b5f6 100644 --- a/test/limine.c +++ b/test/limine.c @@ -55,9 +55,21 @@ struct limine_kernel_file_request kf_request = { __attribute__((section(".limine_reqs"))) void *kf_req = &kf_request; +struct limine_internal_module internal_module1 = { + .path = "boot:///boot/test.elf", + .cmdline = "First internal module" +}; + +struct limine_internal_module *internal_modules[] = { + &internal_module1 +}; + struct limine_module_request module_request = { .id = LIMINE_MODULE_REQUEST, - .revision = 0, .response = NULL + .revision = 1, .response = NULL, + + .internal_module_count = 1, + .internal_modules = internal_modules }; __attribute__((section(".limine_reqs")))