limine: Rework modules/file/kernel_file
This commit is contained in:
parent
652b5447fe
commit
e8fcc85b03
73
PROTOCOL.md
73
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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
31
limine.h
31
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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue