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
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

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) {
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;

View File

@ -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);
}

View File

@ -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 {

View File

@ -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