limine: Implement internal modules concept
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")))
