From e8fcc85b032ce3acf3f793a38049d52e7c207a2c Mon Sep 17 00:00:00 2001 From: mintsuki Date: Sat, 26 Mar 2022 09:27:09 +0100 Subject: [PATCH] limine: Rework modules/file/kernel_file --- PROTOCOL.md | 73 +++++++++++++++++++++------------- common/fs/file.s2.c | 3 ++ common/protos/limine.c | 89 ++++++++++++++++++------------------------ limine.h | 31 ++++++++++----- test/limine.c | 81 ++++++++++++++++++++++---------------- 5 files changed, 156 insertions(+), 121 deletions(-) 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. +`struct limine_file` structures (see below). -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. - -#### 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,19 +71,18 @@ static struct limine_file_location get_file_loc(struct file_handle *file) { memcpy(&ret.gpt_disk_uuid, &gpt_disk_uuid, sizeof(struct limine_uuid)); } + char *path = ext_mem_alloc(strlen(file->path) + 1); + strcpy(path, file->path); + ret.path = reported_addr(path); + + ret.base = reported_addr(freadall(file, MEMMAP_KERNEL_AND_MODULES)); + ret.length = file->size; + + ret.cmdline = reported_addr(cmdline); + return ret; } -static uint64_t reported_addr(void *addr) { - return (uint64_t)(uintptr_t)addr + direct_map_offset; -} - -/* -static uintptr_t get_phys_addr(uint64_t addr) { - return physical_base + (addr - virtual_base); -} -*/ - static void *_get_request(uint64_t id[4]) { for (size_t i = 0; i < requests_count; i++) { uint64_t *p = requests[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; }; +/* Kernel File */ + +#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } + +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 { - 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_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