limine: Add memmap feature

This commit is contained in:
mintsuki 2022-03-12 21:41:36 +01:00
parent b2e614e7c2
commit e33a76bd99
4 changed files with 120 additions and 16 deletions

View File

@ -4,39 +4,35 @@
#include <stdint.h>
#ifdef LIMINE_NO_POINTERS
# define LIMINE_CHARPTR uint64_t
# define LIMINE_VOIDPTR uint64_t
# define LIMINE_VOIDPTRPTR uint64_t
# define LIMINE_PTR(TYPE) uint64_t
#else
# define LIMINE_CHARPTR char *
# define LIMINE_VOIDPTR void *
# define LIMINE_VOIDPTRPTR void **
# define LIMINE_PTR(TYPE) TYPE
#endif
#define LIMINE_MAGIC { 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b }
struct limine_header {
uint64_t magic[2];
LIMINE_VOIDPTR entry;
LIMINE_PTR(void *) entry;
uint64_t features_count;
LIMINE_VOIDPTRPTR features;
LIMINE_PTR(void *) features;
};
// Boot info
#define LIMINE_BOOT_INFO_REQUEST ((LIMINE_VOIDPTR) 1 )
#define LIMINE_BOOT_INFO_REQUEST ((LIMINE_PTR(void *)) 1 )
struct limine_boot_info_response {
uint64_t flags;
LIMINE_CHARPTR loader;
LIMINE_PTR(char *) loader;
};
// Framebuffer
#define LIMINE_FRAMEBUFFER_REQUEST ((LIMINE_VOIDPTR) 2 )
#define LIMINE_FRAMEBUFFER_REQUEST ((LIMINE_PTR(void *)) 2 )
struct limine_framebuffer_request {
LIMINE_VOIDPTR id;
LIMINE_PTR(void *) id;
#define LIMINE_FRAMEBUFFER_PREFER_LFB 0
#define LIMINE_FRAMEBUFFER_PREFER_TEXT 1
@ -52,7 +48,7 @@ struct limine_framebuffer_request {
// 5-level paging
#define LIMINE_5_LEVEL_PAGING_REQUEST ((LIMINE_VOIDPTR) 3 )
#define LIMINE_5_LEVEL_PAGING_REQUEST ((LIMINE_PTR(void *)) 3 )
struct limine_5_level_paging_response {
uint64_t flags;
@ -60,6 +56,32 @@ struct limine_5_level_paging_response {
// PMRs
#define LIMINE_PMR_REQUEST ((LIMINE_VOIDPTR) 4 )
#define LIMINE_PMR_REQUEST ((LIMINE_PTR(void *)) 4 )
// Memory map
#define LIMINE_MEMMAP_REQUEST ((LIMINE_PTR(void *)) 5 )
#define LIMINE_MEMMAP_USABLE 0
#define LIMINE_MEMMAP_RESERVED 1
#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2
#define LIMINE_MEMMAP_ACPI_NVS 3
#define LIMINE_MEMMAP_BAD_MEMORY 4
#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5
#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6
#define LIMINE_MEMMAP_FRAMEBUFFER 7
struct limine_memmap_entry {
uint64_t base;
uint64_t length;
uint64_t type;
};
struct limine_memmap_response {
uint64_t flags;
uint64_t entries_count;
LIMINE_PTR(struct limine_memmap_entry *) entries;
};
#endif

View File

@ -234,9 +234,54 @@ FEAT_END
// Memmap
FEAT_START
struct feature memmap_feat = get_feature(LIMINE_MEMMAP_REQUEST);
struct limine_memmap_response *memmap_response;
if (memmap_feat.found == true) {
memmap_response = ext_mem_alloc(sizeof(struct limine_memmap_response));
}
size_t mmap_entries;
struct e820_entry_t *mmap = get_memmap(&mmap_entries);
(void)mmap;
if (memmap_feat.found == false) {
break; // next feature
}
for (size_t i = 0; i < mmap_entries; i++) {
switch (mmap[i].type) {
case MEMMAP_USABLE:
mmap[i].type = LIMINE_MEMMAP_USABLE;
break;
case MEMMAP_ACPI_RECLAIMABLE:
mmap[i].type = LIMINE_MEMMAP_ACPI_RECLAIMABLE;
break;
case MEMMAP_ACPI_NVS:
mmap[i].type = LIMINE_MEMMAP_ACPI_NVS;
break;
case MEMMAP_BAD_MEMORY:
mmap[i].type = LIMINE_MEMMAP_BAD_MEMORY;
break;
case MEMMAP_BOOTLOADER_RECLAIMABLE:
mmap[i].type = LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE;
break;
case MEMMAP_KERNEL_AND_MODULES:
mmap[i].type = LIMINE_MEMMAP_KERNEL_AND_MODULES;
break;
case MEMMAP_FRAMEBUFFER:
mmap[i].type = LIMINE_MEMMAP_FRAMEBUFFER;
break;
default:
case MEMMAP_RESERVED:
mmap[i].type = LIMINE_MEMMAP_RESERVED;
break;
}
}
memmap_response->entries_count = mmap_entries;
memmap_response->entries = reported_addr(mmap);
features_orig[memmap_feat.index] = reported_addr(memmap_response);
FEAT_END
// Final wrap-up

View File

@ -9,7 +9,7 @@ struct e820_entry_t {
uint64_t length;
uint32_t type;
uint32_t unused;
} __attribute__((packed));
};
extern struct e820_entry_t e820_map[];
extern size_t e820_entries;

View File

@ -14,6 +14,7 @@ static struct limine_framebuffer_request framebuffer_request = {
static void *features_array[] = {
LIMINE_BOOT_INFO_REQUEST,
&framebuffer_request,
LIMINE_MEMMAP_REQUEST,
LIMINE_5_LEVEL_PAGING_REQUEST,
LIMINE_PMR_REQUEST
};
@ -28,6 +29,29 @@ static struct limine_header limine_header = {
.features = features_array
};
static char *get_memmap_type(uint64_t type) {
switch (type) {
case LIMINE_MEMMAP_USABLE:
return "Usable";
case LIMINE_MEMMAP_RESERVED:
return "Reserved";
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
return "ACPI reclaimable";
case LIMINE_MEMMAP_ACPI_NVS:
return "ACPI NVS";
case LIMINE_MEMMAP_BAD_MEMORY:
return "Bad memory";
case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE:
return "Bootloader reclaimable";
case LIMINE_MEMMAP_KERNEL_AND_MODULES:
return "Kernel and modules";
case LIMINE_MEMMAP_FRAMEBUFFER:
return "Framebuffer";
default:
return "???";
}
}
#define FEAT_START do {
#define FEAT_END } while (0);
@ -36,12 +60,25 @@ static void limine_main(void) {
FEAT_START
if (features_array[0] == NULL) {
e9_printf("Boot info not passed");
break;
}
struct limine_boot_info_response *boot_info_response = features_array[0];
e9_printf("Boot info response:");
e9_printf("Bootloader name: %s", boot_info_response->loader);
FEAT_END
FEAT_START
if (features_array[2] == NULL) {
e9_printf("Memory map not passed");
break;
}
struct limine_memmap_response *memmap_response = features_array[2];
e9_printf("%d memory map entries", memmap_response->entries_count);
for (size_t i = 0; i < memmap_response->entries_count; i++) {
struct limine_memmap_entry *e = &memmap_response->entries[i];
e9_printf("%x->%x %s", e->base, e->base + e->length, get_memmap_type(e->type));
}
FEAT_END
for (;;);