limine: Add modules request

This commit is contained in:
mintsuki 2022-03-16 06:49:41 +01:00
parent 1e62d99374
commit a51f8a39c0
7 changed files with 226 additions and 37 deletions

View File

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

View File

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

View File

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

View File

@ -127,6 +127,7 @@ static const char *VALID_KEYS[] = {
"INITRD_PATH",
"MODULE_PATH",
"MODULE_STRING",
"MODULE_CMDLINE",
"RESOLUTION",
"TEXTMODE",
"KASLR",

View File

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

View File

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

View File

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