limine: Rework modules/file/kernel_file
diff --git a/PROTOCOL.md b/PROTOCOL.md
index 88ae006b..f56c0395 100644
--- a/PROTOCOL.md
+++ b/PROTOCOL.md
@@ -473,6 +473,33 @@ struct limine_entry_point_response {
};
```
+### Kernel File Feature
+
+ID:
+```c
+#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 }
+```
+
+Request:
+```c
+struct limine_kernel_file_request {
+ uint64_t id[4];
+ uint64_t revision;
+ struct limine_kernel_file_response *response;
+};
+```
+
+Response:
+```c
+struct limine_kernel_file_response {
+ uint64_t revision;
+ struct limine_file *kernel_file;
+};
+```
+
+* `kernel_file` - Pointer to the `struct limine_file` structure (see below)
+for the kernel file.
+
### Module Feature
ID:
@@ -494,33 +521,15 @@ Response:
struct limine_module_response {
uint64_t revision;
uint64_t module_count;
- struct limine_module **modules;
+ struct limine_file **modules;
};
```
* `module_count` - How many modules are present.
* `modules` - Pointer to an array of `module_count` pointers to
-`struct limine_module` structures.
-
-Note: The first module (module 0) is always the kernel file.
-
-```c
-struct limine_module {
- void *base;
- uint64_t length;
- char *path;
- char *cmdline;
- struct limine_file_location *file_location;
-};
-```
-
-* `base` - The address of the module.
-* `length` - The size of the module.
-* `path` - The path of the module within the volume, with a leading slash.
-* `cmdline` - A command line associated with the module.
-* `file_location` - A pointer to the file location structure for the module.
+`struct limine_file` structures (see below).
-#### File Location Structure
+### File Structure
```c
struct limine_uuid {
@@ -530,8 +539,12 @@ struct limine_uuid {
uint8_t d[8];
};
-struct limine_file_location {
+struct limine_file {
uint64_t revision;
+ void *base;
+ uint64_t length;
+ char *path;
+ char *cmdline;
uint64_t partition_index;
uint32_t tftp_ip;
uint32_t tftp_port;
@@ -542,20 +555,24 @@ struct limine_file_location {
};
```
-* `revision` - Revision of the `struct limine_file_location` structure.
+* `revision` - Revision of the `struct limine_file` structure.
+* `base` - The address of the file.
+* `length` - The size of the file.
+* `path` - The path of the file within the volume, with a leading slash.
+* `cmdline` - A command line associated with the file.
* `partition_index` - 1-based partition index of the volume from which the
-module was loaded. If 0, it means invalid or unpartitioned.
+file was loaded. If 0, it means invalid or unpartitioned.
* `tftp_ip` - If non-0, this is the IP of the TFTP server the file was loaded
from.
* `tftp_port` - Likewise, but port.
-* `mbr_disk_id` - If non-0, this is the ID of the disk the module was loaded
+* `mbr_disk_id` - If non-0, this is the ID of the disk the file was loaded
from as reported in its MBR.
-* `gpt_disk_uuid` - If non-0, this is the UUID of the disk the module was
+* `gpt_disk_uuid` - If non-0, this is the UUID of the disk the file was
loaded from as reported in its GPT.
-* `gpt_part_uuid` - If non-0, this is the UUID of the partition the module
+* `gpt_part_uuid` - If non-0, this is the UUID of the partition the file
was loaded from as reported in the GPT.
* `part_uuid` - If non-0, this is the UUID of the filesystem of the partition
-the module was loaded from.
+the file was loaded from.
### RSDP Feature
diff --git a/common/fs/file.s2.c b/common/fs/file.s2.c
index 3adf1891..f4f099bf 100644
--- a/common/fs/file.s2.c
+++ b/common/fs/file.s2.c
@@ -154,6 +154,9 @@ void fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count) {
void *freadall(struct file_handle *fd, uint32_t type) {
if (fd->is_memfile) {
+ if (fd->readall) {
+ return fd->fd;
+ }
memmap_alloc_range((uint64_t)(size_t)fd->fd, ALIGN_UP(fd->size, 4096), type, false, true, false, false);
fd->readall = true;
return fd->fd;
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 9713882b..4e61f019 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -39,8 +39,12 @@ static uint64_t physical_base, virtual_base, slide, direct_map_offset;
static size_t requests_count;
static void *requests[MAX_REQUESTS];
-static struct limine_file_location get_file_loc(struct file_handle *file) {
- struct limine_file_location ret = {0};
+static uint64_t reported_addr(void *addr) {
+ return (uint64_t)(uintptr_t)addr + direct_map_offset;
+}
+
+static struct limine_file get_file(struct file_handle *file, char *cmdline) {
+ struct limine_file ret = {0};
if (file->pxe) {
ret.tftp_ip = file->pxe_ip;
@@ -67,18 +71,17 @@ static struct limine_file_location get_file_loc(struct file_handle *file) {
memcpy(&ret.gpt_disk_uuid, &gpt_disk_uuid, sizeof(struct limine_uuid));
}
- return ret;
-}
+ char *path = ext_mem_alloc(strlen(file->path) + 1);
+ strcpy(path, file->path);
+ ret.path = reported_addr(path);
-static uint64_t reported_addr(void *addr) {
- return (uint64_t)(uintptr_t)addr + direct_map_offset;
-}
+ ret.base = reported_addr(freadall(file, MEMMAP_KERNEL_AND_MODULES));
+ ret.length = file->size;
-/*
-static uintptr_t get_phys_addr(uint64_t addr) {
- return physical_base + (addr - virtual_base);
+ ret.cmdline = reported_addr(cmdline);
+
+ return ret;
}
-*/
static void *_get_request(uint64_t id[4]) {
for (size_t i = 0; i < requests_count; i++) {
@@ -120,18 +123,8 @@ bool limine_load(char *config, char *cmdline) {
if ((kernel_file = uri_open(kernel_path)) == NULL)
panic(true, "limine: Failed to open kernel with path `%s`. Is the path correct?", kernel_path);
- char *kpath = ext_mem_alloc(strlen(kernel_file->path) + 1);
- strcpy(kpath, kernel_file->path);
-
uint8_t *kernel = freadall(kernel_file, MEMMAP_BOOTLOADER_RECLAIMABLE);
- size_t kernel_file_size = kernel_file->size;
-
- struct limine_file_location *kl = ext_mem_alloc(sizeof(struct limine_file_location));
- *kl = get_file_loc(kernel_file);
-
- fclose(kernel_file);
-
char *kaslr_s = config_get_value(config, 0, "KASLR");
bool kaslr = true;
if (kaslr_s != NULL && strcmp(kaslr_s, "no") == 0)
@@ -225,6 +218,10 @@ FEAT_START
}
FEAT_END
+ struct limine_file *kf = ext_mem_alloc(sizeof(struct limine_file));
+ *kf = get_file(kernel_file, cmdline);
+ fclose(kernel_file);
+
// Entry point feature
FEAT_START
struct limine_entry_point_request *entrypoint_request = get_request(LIMINE_ENTRY_POINT_REQUEST);
@@ -348,6 +345,21 @@ FEAT_START
FEAT_END
#endif
+ // Kernel file
+FEAT_START
+ struct limine_kernel_file_request *kernel_file_request = get_request(LIMINE_KERNEL_FILE_REQUEST);
+ if (kernel_file_request == NULL) {
+ break; // next feature
+ }
+
+ struct limine_kernel_file_response *kernel_file_response =
+ ext_mem_alloc(sizeof(struct limine_kernel_file_response));
+
+ kernel_file_response->kernel_file = reported_addr(kf);
+
+ kernel_file_request->response = reported_addr(kernel_file_response);
+FEAT_END
+
// Modules
FEAT_START
struct limine_module_request *module_request = get_request(LIMINE_MODULE_REQUEST);
@@ -362,31 +374,19 @@ FEAT_START
break;
}
- // Module 0 is always the kernel
- module_count++;
-
struct limine_module_response *module_response =
ext_mem_alloc(sizeof(struct limine_module_response));
- struct limine_module *modules = ext_mem_alloc(module_count * sizeof(struct limine_module));
+ struct limine_file *modules = ext_mem_alloc(module_count * sizeof(struct limine_file));
- modules[0].base = reported_addr(kernel);
- modules[0].length = kernel_file_size;
- modules[0].path = reported_addr(kpath);
- modules[0].cmdline = reported_addr(cmdline);
-
- modules[0].file_location = reported_addr(kl);
-
- for (size_t i = 1; i < module_count; i++) {
+ for (size_t i = 0; i < module_count; i++) {
struct conf_tuple conf_tuple =
- config_get_tuple(config, i - 1,
+ config_get_tuple(config, i,
"MODULE_PATH", "MODULE_CMDLINE");
char *module_path = conf_tuple.value1;
char *module_cmdline = conf_tuple.value2;
- struct limine_module *m = &modules[i];
-
if (module_cmdline == NULL) {
module_cmdline = "";
}
@@ -397,19 +397,8 @@ FEAT_START
if ((f = uri_open(module_path)) == NULL)
panic(true, "limine: Failed to open module with path `%s`. Is the path correct?", module_path);
- m->base = reported_addr(freadall(f, MEMMAP_KERNEL_AND_MODULES));
- m->length = f->size;
-
- char *mpath = ext_mem_alloc(strlen(f->path) + 1);
- strcpy(mpath, f->path);
- m->path = reported_addr(mpath);
-
- m->cmdline = reported_addr(module_cmdline);
-
- struct limine_file_location *l = ext_mem_alloc(sizeof(struct limine_file_location));
- *l = get_file_loc(f);
-
- m->file_location = reported_addr(l);
+ struct limine_file *l = &modules[i];
+ *l = get_file(f, module_cmdline);
fclose(f);
}
diff --git a/limine.h b/limine.h
index c6a9048e..d82f6cd8 100644
--- a/limine.h
+++ b/limine.h
@@ -20,8 +20,12 @@ struct limine_uuid {
uint8_t d[8];
};
-struct limine_file_location {
+struct limine_file {
uint64_t revision;
+ LIMINE_PTR(void *) base;
+ uint64_t length;
+ LIMINE_PTR(char *) path;
+ LIMINE_PTR(char *) cmdline;
uint64_t partition_index;
uint32_t tftp_ip;
uint32_t tftp_port;
@@ -212,22 +216,29 @@ struct limine_entry_point_request {
LIMINE_PTR(limine_entry_point) entry;
};
-/* Module */
+/* Kernel File */
-#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee }
+#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 }
-struct limine_module {
- LIMINE_PTR(void *) base;
- uint64_t length;
- LIMINE_PTR(char *) path;
- LIMINE_PTR(char *) cmdline;
- LIMINE_PTR(struct limine_file_location *) file_location;
+struct limine_kernel_file_response {
+ uint64_t revision;
+ LIMINE_PTR(struct limine_file *) kernel_file;
+};
+
+struct limine_kernel_file_request {
+ uint64_t id[4];
+ uint64_t revision;
+ LIMINE_PTR(struct limine_kernel_file_response *) response;
};
+/* Module */
+
+#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee }
+
struct limine_module_response {
uint64_t revision;
uint64_t module_count;
- LIMINE_PTR(struct limine_module **) modules;
+ LIMINE_PTR(struct limine_file **) modules;
};
struct limine_module_request {
diff --git a/test/limine.c b/test/limine.c
index 732c3848..99a6a6f2 100644
--- a/test/limine.c
+++ b/test/limine.c
@@ -32,6 +32,11 @@ struct limine_memmap_request memmap_request = {
.revision = 0, .response = NULL
};
+struct limine_kernel_file_request kf_request = {
+ .id = LIMINE_KERNEL_FILE_REQUEST,
+ .revision = 0, .response = NULL
+};
+
struct limine_module_request module_request = {
.id = LIMINE_MODULE_REQUEST,
.revision = 0, .response = NULL
@@ -95,31 +100,35 @@ static char *get_memmap_type(uint64_t type) {
}
}
-static void print_file_loc(struct limine_file_location *file_location) {
- e9_printf("Loc->Revision: %d", file_location->revision);
- e9_printf("Loc->PartIndex: %d", file_location->partition_index);
- e9_printf("Loc->TFTPIP: %d.%d.%d.%d",
- (file_location->tftp_ip & (0xff << 0)) >> 0,
- (file_location->tftp_ip & (0xff << 8)) >> 8,
- (file_location->tftp_ip & (0xff << 16)) >> 16,
- (file_location->tftp_ip & (0xff << 24)) >> 24);
- e9_printf("Loc->TFTPPort: %d", file_location->tftp_port);
- e9_printf("Loc->MBRDiskId: %x", file_location->mbr_disk_id);
- e9_printf("Loc->GPTDiskUUID: %x-%x-%x-%x",
- file_location->gpt_disk_uuid.a,
- file_location->gpt_disk_uuid.b,
- file_location->gpt_disk_uuid.c,
- *(uint64_t *)file_location->gpt_disk_uuid.d);
- e9_printf("Loc->GPTPartUUID: %x-%x-%x-%x",
- file_location->gpt_part_uuid.a,
- file_location->gpt_part_uuid.b,
- file_location->gpt_part_uuid.c,
- *(uint64_t *)file_location->gpt_part_uuid.d);
- e9_printf("Loc->PartUUID: %x-%x-%x-%x",
- file_location->part_uuid.a,
- file_location->part_uuid.b,
- file_location->part_uuid.c,
- *(uint64_t *)file_location->part_uuid.d);
+static void print_file(struct limine_file *file) {
+ e9_printf("File->Revision: %d", file->revision);
+ e9_printf("File->Base: %x", file->base);
+ e9_printf("File->Length: %x", file->length);
+ e9_printf("File->Path: %s", file->path);
+ e9_printf("File->CmdLine: %s", file->cmdline);
+ e9_printf("File->PartIndex: %d", file->partition_index);
+ e9_printf("File->TFTPIP: %d.%d.%d.%d",
+ (file->tftp_ip & (0xff << 0)) >> 0,
+ (file->tftp_ip & (0xff << 8)) >> 8,
+ (file->tftp_ip & (0xff << 16)) >> 16,
+ (file->tftp_ip & (0xff << 24)) >> 24);
+ e9_printf("File->TFTPPort: %d", file->tftp_port);
+ e9_printf("File->MBRDiskId: %x", file->mbr_disk_id);
+ e9_printf("File->GPTDiskUUID: %x-%x-%x-%x",
+ file->gpt_disk_uuid.a,
+ file->gpt_disk_uuid.b,
+ file->gpt_disk_uuid.c,
+ *(uint64_t *)file->gpt_disk_uuid.d);
+ e9_printf("File->GPTPartUUID: %x-%x-%x-%x",
+ file->gpt_part_uuid.a,
+ file->gpt_part_uuid.b,
+ file->gpt_part_uuid.c,
+ *(uint64_t *)file->gpt_part_uuid.d);
+ e9_printf("File->PartUUID: %x-%x-%x-%x",
+ file->part_uuid.a,
+ file->part_uuid.b,
+ file->part_uuid.c,
+ *(uint64_t *)file->part_uuid.d);
}
#define FEAT_START do {
@@ -216,6 +225,17 @@ FEAT_START
}
FEAT_END
+FEAT_START
+ e9_printf("");
+ if (kf_request.response == NULL) {
+ e9_printf("Kernel file not passed");
+ break;
+ }
+ struct limine_kernel_file_response *kf_response = kf_request.response;
+ e9_printf("Kernel file feature, revision %d", kf_response->revision);
+ print_file(kf_response->kernel_file);
+FEAT_END
+
FEAT_START
e9_printf("");
if (module_request.response == NULL) {
@@ -226,14 +246,9 @@ FEAT_START
e9_printf("Modules feature, revision %d", module_response->revision);
e9_printf("%d module(s)", module_response->module_count);
for (size_t i = 0; i < module_response->module_count; i++) {
- struct limine_module *m = module_response->modules[i];
-
- e9_printf("Base: %x", m->base);
- e9_printf("Length: %x", m->length);
- e9_printf("Path: %s", m->path);
- e9_printf("Cmdline: %s", m->cmdline);
-
- print_file_loc(m->file_location);
+ struct limine_file *f = module_response->modules[i];
+ e9_printf("---");
+ print_file(f);
}
FEAT_END
