limine: Rework modules/file/kernel_file

This commit is contained in:
mintsuki 2022-03-26 09:27:09 +01:00
parent 652b5447fe
commit e8fcc85b03
5 changed files with 156 additions and 121 deletions

View File

@ -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 ### Module Feature
ID: ID:
@ -494,33 +521,15 @@ Response:
struct limine_module_response { struct limine_module_response {
uint64_t revision; uint64_t revision;
uint64_t module_count; uint64_t module_count;
struct limine_module **modules; struct limine_file **modules;
}; };
``` ```
* `module_count` - How many modules are present. * `module_count` - How many modules are present.
* `modules` - Pointer to an array of `module_count` pointers to * `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. ### File Structure
```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
```c ```c
struct limine_uuid { struct limine_uuid {
@ -530,8 +539,12 @@ struct limine_uuid {
uint8_t d[8]; uint8_t d[8];
}; };
struct limine_file_location { struct limine_file {
uint64_t revision; uint64_t revision;
void *base;
uint64_t length;
char *path;
char *cmdline;
uint64_t partition_index; uint64_t partition_index;
uint32_t tftp_ip; uint32_t tftp_ip;
uint32_t tftp_port; 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 * `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 * `tftp_ip` - If non-0, this is the IP of the TFTP server the file was loaded
from. from.
* `tftp_port` - Likewise, but port. * `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. 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. 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. was loaded from as reported in the GPT.
* `part_uuid` - If non-0, this is the UUID of the filesystem of the partition * `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 ### RSDP Feature

View File

@ -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) { void *freadall(struct file_handle *fd, uint32_t type) {
if (fd->is_memfile) { 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); memmap_alloc_range((uint64_t)(size_t)fd->fd, ALIGN_UP(fd->size, 4096), type, false, true, false, false);
fd->readall = true; fd->readall = true;
return fd->fd; return fd->fd;

View File

@ -39,8 +39,12 @@ static uint64_t physical_base, virtual_base, slide, direct_map_offset;
static size_t requests_count; static size_t requests_count;
static void *requests[MAX_REQUESTS]; static void *requests[MAX_REQUESTS];
static struct limine_file_location get_file_loc(struct file_handle *file) { static uint64_t reported_addr(void *addr) {
struct limine_file_location ret = {0}; 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) { if (file->pxe) {
ret.tftp_ip = file->pxe_ip; 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)); 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; 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]) { static void *_get_request(uint64_t id[4]) {
for (size_t i = 0; i < requests_count; i++) { for (size_t i = 0; i < requests_count; i++) {
uint64_t *p = requests[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) if ((kernel_file = uri_open(kernel_path)) == NULL)
panic(true, "limine: Failed to open kernel with path `%s`. Is the path correct?", kernel_path); 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); 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"); char *kaslr_s = config_get_value(config, 0, "KASLR");
bool kaslr = true; bool kaslr = true;
if (kaslr_s != NULL && strcmp(kaslr_s, "no") == 0) if (kaslr_s != NULL && strcmp(kaslr_s, "no") == 0)
@ -225,6 +218,10 @@ FEAT_START
} }
FEAT_END 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 // Entry point feature
FEAT_START FEAT_START
struct limine_entry_point_request *entrypoint_request = get_request(LIMINE_ENTRY_POINT_REQUEST); struct limine_entry_point_request *entrypoint_request = get_request(LIMINE_ENTRY_POINT_REQUEST);
@ -348,6 +345,21 @@ FEAT_START
FEAT_END FEAT_END
#endif #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 // Modules
FEAT_START FEAT_START
struct limine_module_request *module_request = get_request(LIMINE_MODULE_REQUEST); struct limine_module_request *module_request = get_request(LIMINE_MODULE_REQUEST);
@ -362,31 +374,19 @@ FEAT_START
break; break;
} }
// Module 0 is always the kernel
module_count++;
struct limine_module_response *module_response = struct limine_module_response *module_response =
ext_mem_alloc(sizeof(struct limine_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); for (size_t i = 0; i < module_count; i++) {
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++) {
struct conf_tuple conf_tuple = struct conf_tuple conf_tuple =
config_get_tuple(config, i - 1, config_get_tuple(config, i,
"MODULE_PATH", "MODULE_CMDLINE"); "MODULE_PATH", "MODULE_CMDLINE");
char *module_path = conf_tuple.value1; char *module_path = conf_tuple.value1;
char *module_cmdline = conf_tuple.value2; char *module_cmdline = conf_tuple.value2;
struct limine_module *m = &modules[i];
if (module_cmdline == NULL) { if (module_cmdline == NULL) {
module_cmdline = ""; module_cmdline = "";
} }
@ -397,19 +397,8 @@ FEAT_START
if ((f = uri_open(module_path)) == NULL) if ((f = uri_open(module_path)) == NULL)
panic(true, "limine: Failed to open module with path `%s`. Is the path correct?", module_path); 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)); struct limine_file *l = &modules[i];
m->length = f->size; *l = get_file(f, module_cmdline);
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);
fclose(f); fclose(f);
} }

View File

@ -20,8 +20,12 @@ struct limine_uuid {
uint8_t d[8]; uint8_t d[8];
}; };
struct limine_file_location { struct limine_file {
uint64_t revision; uint64_t revision;
LIMINE_PTR(void *) base;
uint64_t length;
LIMINE_PTR(char *) path;
LIMINE_PTR(char *) cmdline;
uint64_t partition_index; uint64_t partition_index;
uint32_t tftp_ip; uint32_t tftp_ip;
uint32_t tftp_port; uint32_t tftp_port;
@ -212,22 +216,29 @@ struct limine_entry_point_request {
LIMINE_PTR(limine_entry_point) entry; 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 */ /* Module */
#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } #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 { struct limine_module_response {
uint64_t revision; uint64_t revision;
uint64_t module_count; uint64_t module_count;
LIMINE_PTR(struct limine_module **) modules; LIMINE_PTR(struct limine_file **) modules;
}; };
struct limine_module_request { struct limine_module_request {

View File

@ -32,6 +32,11 @@ struct limine_memmap_request memmap_request = {
.revision = 0, .response = NULL .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 = { struct limine_module_request module_request = {
.id = LIMINE_MODULE_REQUEST, .id = LIMINE_MODULE_REQUEST,
.revision = 0, .response = NULL .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) { static void print_file(struct limine_file *file) {
e9_printf("Loc->Revision: %d", file_location->revision); e9_printf("File->Revision: %d", file->revision);
e9_printf("Loc->PartIndex: %d", file_location->partition_index); e9_printf("File->Base: %x", file->base);
e9_printf("Loc->TFTPIP: %d.%d.%d.%d", e9_printf("File->Length: %x", file->length);
(file_location->tftp_ip & (0xff << 0)) >> 0, e9_printf("File->Path: %s", file->path);
(file_location->tftp_ip & (0xff << 8)) >> 8, e9_printf("File->CmdLine: %s", file->cmdline);
(file_location->tftp_ip & (0xff << 16)) >> 16, e9_printf("File->PartIndex: %d", file->partition_index);
(file_location->tftp_ip & (0xff << 24)) >> 24); e9_printf("File->TFTPIP: %d.%d.%d.%d",
e9_printf("Loc->TFTPPort: %d", file_location->tftp_port); (file->tftp_ip & (0xff << 0)) >> 0,
e9_printf("Loc->MBRDiskId: %x", file_location->mbr_disk_id); (file->tftp_ip & (0xff << 8)) >> 8,
e9_printf("Loc->GPTDiskUUID: %x-%x-%x-%x", (file->tftp_ip & (0xff << 16)) >> 16,
file_location->gpt_disk_uuid.a, (file->tftp_ip & (0xff << 24)) >> 24);
file_location->gpt_disk_uuid.b, e9_printf("File->TFTPPort: %d", file->tftp_port);
file_location->gpt_disk_uuid.c, e9_printf("File->MBRDiskId: %x", file->mbr_disk_id);
*(uint64_t *)file_location->gpt_disk_uuid.d); e9_printf("File->GPTDiskUUID: %x-%x-%x-%x",
e9_printf("Loc->GPTPartUUID: %x-%x-%x-%x", file->gpt_disk_uuid.a,
file_location->gpt_part_uuid.a, file->gpt_disk_uuid.b,
file_location->gpt_part_uuid.b, file->gpt_disk_uuid.c,
file_location->gpt_part_uuid.c, *(uint64_t *)file->gpt_disk_uuid.d);
*(uint64_t *)file_location->gpt_part_uuid.d); e9_printf("File->GPTPartUUID: %x-%x-%x-%x",
e9_printf("Loc->PartUUID: %x-%x-%x-%x", file->gpt_part_uuid.a,
file_location->part_uuid.a, file->gpt_part_uuid.b,
file_location->part_uuid.b, file->gpt_part_uuid.c,
file_location->part_uuid.c, *(uint64_t *)file->gpt_part_uuid.d);
*(uint64_t *)file_location->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 { #define FEAT_START do {
@ -216,6 +225,17 @@ FEAT_START
} }
FEAT_END 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 FEAT_START
e9_printf(""); e9_printf("");
if (module_request.response == NULL) { if (module_request.response == NULL) {
@ -226,14 +246,9 @@ FEAT_START
e9_printf("Modules feature, revision %d", module_response->revision); e9_printf("Modules feature, revision %d", module_response->revision);
e9_printf("%d module(s)", module_response->module_count); e9_printf("%d module(s)", module_response->module_count);
for (size_t i = 0; i < module_response->module_count; i++) { for (size_t i = 0; i < module_response->module_count; i++) {
struct limine_module *m = module_response->modules[i]; struct limine_file *f = module_response->modules[i];
e9_printf("---");
e9_printf("Base: %x", m->base); print_file(f);
e9_printf("Length: %x", m->length);
e9_printf("Path: %s", m->path);
e9_printf("Cmdline: %s", m->cmdline);
print_file_loc(m->file_location);
} }
FEAT_END FEAT_END