summaryrefslogtreecommitdiff
path: root/loader/loader_efi.c
diff options
context:
space:
mode:
Diffstat (limited to 'loader/loader_efi.c')
-rw-r--r--loader/loader_efi.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/loader/loader_efi.c b/loader/loader_efi.c
index 1df9f68..6130074 100644
--- a/loader/loader_efi.c
+++ b/loader/loader_efi.c
@@ -80,29 +80,42 @@ static uint64_t *get_page_map(void)
void set_page_map(uint64_t *map)
{
+ __asm__("cli");
__asm__("mov %0, %%cr3" :: "r"(map));
}
-static uint64_t *get_page_entry(uint64_t *map, uint64_t virt)
+static uint64_t *get_page_table(uint64_t *map, uint64_t virt, int level)
{
- for (int level = PAGE_MAP_LEVELS; level > 1; level--)
+ if ((level < 1) || (level > PAGE_MAP_LEVELS))
+ {
+ return NULL;
+ }
+
+ for (int i = PAGE_MAP_LEVELS; i > level; i--)
{
- if (!map[page_table_index(virt, level)])
+ if (!map[page_table_index(virt, i)])
{
uint64_t *next_map = new_page_table();
- map[page_table_index(virt, level)] =
+ map[page_table_index(virt, i)] =
(uint64_t)next_map|PAGE_PRESENT|PAGE_WRITE;
map = next_map;
}
else
{
- uint64_t next_map_entry = map[page_table_index(virt, level)];
+ uint64_t next_map_entry = map[page_table_index(virt, i)];
next_map_entry &= PAGE_TABLE_ADDRESS_MASK;
map = (uint64_t *)next_map_entry;
}
}
- return &map[page_table_index(virt, 1)];
+ return map;
+}
+
+static uint64_t *get_page_entry(uint64_t *map, uint64_t virt)
+{
+ int level = 1;
+ uint64_t *table = get_page_table(map, virt, level);
+ return &table[page_table_index(virt, level)];
}
static void map_page(void *map,
@@ -141,6 +154,9 @@ static void map_pages(void *map,
}
}
+#define KERNEL_SPACE_LOWER 0xffffffff80000000
+#define KERNEL_SPACE_UPPER 0xffffffffc0000000
+
static void create_kernel_maps(struct system_image *image)
{
Elf64_Ehdr *ehdr = &image->ehdr;
@@ -164,6 +180,21 @@ static void create_kernel_maps(struct system_image *image)
size);
}
}
+
+
+ // Create fractal mappings
+ uint64_t *lower_page_dir = get_page_table(image->maps,
+ KERNEL_SPACE_LOWER,
+ 2);
+ uint64_t *upper_page_dir = get_page_table(image->maps,
+ KERNEL_SPACE_UPPER,
+ 2);
+
+ upper_page_dir[PAGE_TABLE_INDEX_MASK] =
+ (uint64_t)upper_page_dir|PAGE_PRESENT|PAGE_WRITE;
+ upper_page_dir[PAGE_TABLE_INDEX_MASK - 1] =
+ (uint64_t)lower_page_dir|PAGE_PRESENT|PAGE_WRITE;
+
}
static struct system_buffer get_system_buffer(UINTN size)
@@ -193,8 +224,8 @@ static struct system_buffer get_system_buffer(UINTN size)
}
#define KERNEL_ENTRY_STACK_SIZE 0x10000
-#define KERNEL_ENTRY_STACK_BASE (uint64_t)-KERNEL_ENTRY_STACK_SIZE
-#define KERNEL_ENTRY_STACK_HEAD 0
+#define KERNEL_ENTRY_STACK_HEAD 0xffffffffffc00000
+#define KERNEL_ENTRY_STACK_BASE (KERNEL_ENTRY_STACK_HEAD - KERNEL_ENTRY_STACK_SIZE)
static void enter_kernel(struct system_image *kernel_image)
{
@@ -202,6 +233,7 @@ static void enter_kernel(struct system_image *kernel_image)
kernel_entry_func kernel_entry;
kernel_entry = (kernel_entry_func)(kernel_image->ehdr.e_entry);
+
struct system_buffer kernel_entry_stack =
get_system_buffer(KERNEL_ENTRY_STACK_SIZE);
@@ -212,6 +244,7 @@ static void enter_kernel(struct system_image *kernel_image)
DATA_PAGE_TYPE,
kernel_entry_stack.size);
+
data.system_table = e_st;
data.framebuffer = get_framebuffer_data();
data.acpi_rsdp = get_acpi_rsdp();
@@ -226,6 +259,7 @@ static void enter_kernel(struct system_image *kernel_image)
efi_exit(status);
}
+ // parasitic map of uefi page tables is this ok???????
uint64_t *efi_map = get_page_map();
kernel_image->maps[0] = efi_map[0];