limine: Add modules request
This commit is contained in:
parent
1e62d99374
commit
a51f8a39c0
@ -56,6 +56,7 @@ extern struct volume **volume_index;
|
||||
extern size_t volume_index_i;
|
||||
|
||||
bool gpt_get_guid(struct guid *guid, struct volume *volume);
|
||||
uint32_t mbr_get_id(struct volume *volume);
|
||||
|
||||
int part_get(struct volume *part, struct volume *volume, int partition);
|
||||
|
||||
|
@ -208,6 +208,59 @@ struct mbr_entry {
|
||||
uint32_t sect_count;
|
||||
} __attribute__((packed));
|
||||
|
||||
static bool is_valid_mbr(struct volume *volume) {
|
||||
// Check if actually valid mbr
|
||||
uint16_t hint = 0;
|
||||
volume_read(volume, &hint, 218, sizeof(uint16_t));
|
||||
if (hint != 0)
|
||||
return false;
|
||||
|
||||
volume_read(volume, &hint, 444, sizeof(uint16_t));
|
||||
if (hint != 0 && hint != 0x5a5a)
|
||||
return false;
|
||||
|
||||
volume_read(volume, &hint, 510, sizeof(uint16_t));
|
||||
if (hint != 0xaa55)
|
||||
return false;
|
||||
|
||||
volume_read(volume, &hint, 446, sizeof(uint8_t));
|
||||
if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
|
||||
return false;
|
||||
volume_read(volume, &hint, 462, sizeof(uint8_t));
|
||||
if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
|
||||
return false;
|
||||
volume_read(volume, &hint, 478, sizeof(uint8_t));
|
||||
if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
|
||||
return false;
|
||||
volume_read(volume, &hint, 494, sizeof(uint8_t));
|
||||
if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
|
||||
return false;
|
||||
|
||||
char hintc[64];
|
||||
volume_read(volume, hintc, 4, 8);
|
||||
if (memcmp(hintc, "_ECH_FS_", 8) == 0)
|
||||
return false;
|
||||
volume_read(volume, hintc, 54, 3);
|
||||
if (memcmp(hintc, "FAT", 3) == 0)
|
||||
return false;
|
||||
volume_read(volume, &hint, 1080, sizeof(uint16_t));
|
||||
if (hint == 0xef53)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t mbr_get_id(struct volume *volume) {
|
||||
if (!is_valid_mbr(volume)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ret;
|
||||
volume_read(volume, &ret, 0x1b8, sizeof(uint32_t));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mbr_get_logical_part(struct volume *ret, struct volume *extended_part,
|
||||
int partition) {
|
||||
struct mbr_entry entry;
|
||||
@ -261,43 +314,9 @@ static int mbr_get_logical_part(struct volume *ret, struct volume *extended_part
|
||||
}
|
||||
|
||||
static int mbr_get_part(struct volume *ret, struct volume *volume, int partition) {
|
||||
// Check if actually valid mbr
|
||||
uint16_t hint = 0;
|
||||
volume_read(volume, &hint, 218, sizeof(uint16_t));
|
||||
if (hint != 0)
|
||||
return INVALID_TABLE;
|
||||
|
||||
volume_read(volume, &hint, 444, sizeof(uint16_t));
|
||||
if (hint != 0 && hint != 0x5a5a)
|
||||
return INVALID_TABLE;
|
||||
|
||||
volume_read(volume, &hint, 510, sizeof(uint16_t));
|
||||
if (hint != 0xaa55)
|
||||
return INVALID_TABLE;
|
||||
|
||||
volume_read(volume, &hint, 446, sizeof(uint8_t));
|
||||
if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
|
||||
return INVALID_TABLE;
|
||||
volume_read(volume, &hint, 462, sizeof(uint8_t));
|
||||
if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
|
||||
return INVALID_TABLE;
|
||||
volume_read(volume, &hint, 478, sizeof(uint8_t));
|
||||
if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
|
||||
return INVALID_TABLE;
|
||||
volume_read(volume, &hint, 494, sizeof(uint8_t));
|
||||
if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
|
||||
return INVALID_TABLE;
|
||||
|
||||
char hintc[64];
|
||||
volume_read(volume, hintc, 4, 8);
|
||||
if (memcmp(hintc, "_ECH_FS_", 8) == 0)
|
||||
return INVALID_TABLE;
|
||||
volume_read(volume, hintc, 54, 3);
|
||||
if (memcmp(hintc, "FAT", 3) == 0)
|
||||
return INVALID_TABLE;
|
||||
volume_read(volume, &hint, 1080, sizeof(uint16_t));
|
||||
if (hint == 0xef53)
|
||||
if (!is_valid_mbr(volume)) {
|
||||
return INVALID_TABLE;
|
||||
}
|
||||
|
||||
struct mbr_entry entry;
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Misc
|
||||
|
||||
#ifdef LIMINE_NO_POINTERS
|
||||
# define LIMINE_PTR(TYPE) uint64_t
|
||||
#else
|
||||
@ -11,6 +13,21 @@
|
||||
|
||||
#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b
|
||||
|
||||
struct limine_uuid {
|
||||
uint32_t a;
|
||||
uint16_t b;
|
||||
uint16_t c;
|
||||
uint8_t d[8];
|
||||
};
|
||||
|
||||
struct limine_file_location {
|
||||
uint64_t partition_index;
|
||||
uint32_t mbr_disk_id;
|
||||
struct limine_uuid gpt_disk_uuid;
|
||||
struct limine_uuid gpt_part_uuid;
|
||||
struct limine_uuid part_uuid;
|
||||
};
|
||||
|
||||
// Boot info
|
||||
|
||||
#define LIMINE_BOOT_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 }
|
||||
@ -140,4 +157,30 @@ struct limine_entry_point_request {
|
||||
LIMINE_PTR(void *) entry;
|
||||
};
|
||||
|
||||
// Module
|
||||
|
||||
#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee }
|
||||
|
||||
struct limine_module {
|
||||
uint64_t base;
|
||||
uint64_t length;
|
||||
LIMINE_PTR(char *) path;
|
||||
LIMINE_PTR(char *) cmdline;
|
||||
LIMINE_PTR(struct limine_file_location *) file_location;
|
||||
uint8_t reserved[256];
|
||||
};
|
||||
|
||||
struct limine_module_response {
|
||||
uint64_t flags;
|
||||
|
||||
uint64_t modules_count;
|
||||
LIMINE_PTR(struct limine_module *) modules;
|
||||
};
|
||||
|
||||
struct limine_module_request {
|
||||
uint64_t id[4];
|
||||
uint64_t flags;
|
||||
LIMINE_PTR(struct limine_module_response *) response;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -127,6 +127,7 @@ static const char *VALID_KEYS[] = {
|
||||
"INITRD_PATH",
|
||||
"MODULE_PATH",
|
||||
"MODULE_STRING",
|
||||
"MODULE_CMDLINE",
|
||||
"RESOLUTION",
|
||||
"TEXTMODE",
|
||||
"KASLR",
|
||||
|
@ -39,6 +39,29 @@ 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 volume *vol) {
|
||||
struct limine_file_location ret = {0};
|
||||
|
||||
ret.partition_index = vol->partition;
|
||||
|
||||
ret.mbr_disk_id = mbr_get_id(vol);
|
||||
|
||||
if (vol->guid_valid) {
|
||||
memcpy(&ret.part_uuid, &vol->guid, sizeof(struct limine_uuid));
|
||||
}
|
||||
|
||||
if (vol->part_guid_valid) {
|
||||
memcpy(&ret.gpt_part_uuid, &vol->part_guid, sizeof(struct limine_uuid));
|
||||
}
|
||||
|
||||
struct guid gpt_disk_uuid;
|
||||
if (gpt_get_guid(&gpt_disk_uuid, vol->backing_dev ?: vol) == true) {
|
||||
memcpy(&ret.gpt_disk_uuid, &gpt_disk_uuid, sizeof(struct limine_uuid));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint64_t reported_addr(void *addr) {
|
||||
return (uint64_t)(uintptr_t)addr + direct_map_offset;
|
||||
}
|
||||
@ -230,6 +253,63 @@ FEAT_START
|
||||
cmdline_request->response = reported_addr(cmdline_response);
|
||||
FEAT_END
|
||||
|
||||
// Modules
|
||||
FEAT_START
|
||||
struct limine_module_request *module_request = get_request(LIMINE_MODULE_REQUEST);
|
||||
if (module_request == NULL) {
|
||||
break; // next feature
|
||||
}
|
||||
|
||||
size_t module_count;
|
||||
for (module_count = 0; ; module_count++) {
|
||||
char *module_file = config_get_value(config, module_count, "MODULE_PATH");
|
||||
if (module_file == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
for (size_t i = 0; i < module_count; i++) {
|
||||
struct conf_tuple conf_tuple =
|
||||
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 = "";
|
||||
}
|
||||
|
||||
print("limine: Loading module `%s`...\n", module_path);
|
||||
|
||||
struct file_handle *f;
|
||||
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;
|
||||
m->path = reported_addr(module_path);
|
||||
m->cmdline = reported_addr(module_cmdline);
|
||||
|
||||
struct limine_file_location *l = ext_mem_alloc(sizeof(struct limine_file_location));
|
||||
*l = get_file_loc(f->vol);
|
||||
|
||||
m->file_location = reported_addr(l);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
module_response->modules_count = module_count;
|
||||
module_response->modules = reported_addr(modules);
|
||||
|
||||
module_request->response = reported_addr(module_response);
|
||||
FEAT_END
|
||||
|
||||
// Framebuffer feature
|
||||
FEAT_START
|
||||
term_deinit();
|
||||
|
@ -37,6 +37,12 @@ static struct limine_memmap_request memmap_request = {
|
||||
.flags = 0, .response = NULL
|
||||
};
|
||||
|
||||
__attribute__((used))
|
||||
static struct limine_module_request module_request = {
|
||||
.id = LIMINE_MODULE_REQUEST,
|
||||
.flags = 0, .response = NULL
|
||||
};
|
||||
|
||||
static char *get_memmap_type(uint64_t type) {
|
||||
switch (type) {
|
||||
case LIMINE_MEMMAP_USABLE:
|
||||
@ -60,6 +66,26 @@ static char *get_memmap_type(uint64_t type) {
|
||||
}
|
||||
}
|
||||
|
||||
static void print_file_loc(struct limine_file_location *file_location) {
|
||||
e9_printf("Loc->PartIndex: %d", file_location->partition_index);
|
||||
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);
|
||||
}
|
||||
|
||||
#define FEAT_START do {
|
||||
#define FEAT_END } while (0);
|
||||
|
||||
@ -122,5 +148,24 @@ FEAT_START
|
||||
}
|
||||
FEAT_END
|
||||
|
||||
FEAT_START
|
||||
if (module_request.response == NULL) {
|
||||
e9_printf("Modules not passed");
|
||||
break;
|
||||
}
|
||||
struct limine_module_response *module_response = module_request.response;
|
||||
e9_printf("%d module(s)", module_response->modules_count);
|
||||
for (size_t i = 0; i < module_response->modules_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);
|
||||
}
|
||||
FEAT_END
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ KERNEL_PATH=${STIVALE_KERNEL}
|
||||
KERNEL_CMDLINE=Woah! Another example!
|
||||
|
||||
MODULE_PATH=${BACKGROUND_PATH}
|
||||
MODULE_STRING=yooooo
|
||||
MODULE_CMDLINE=yooooo
|
||||
|
||||
# Test that the module string provided to the kernel will be
|
||||
# the module path since a module string is not specified.
|
||||
|
Loading…
Reference in New Issue
Block a user