diff options
| author | Ada Christine <adachristine18@gmail.com> | 2021-03-27 15:17:05 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2021-03-27 15:17:05 +0000 |
| commit | fda565807ee5b7c99eadcd2e7bfe0d36f68991ab (patch) | |
| tree | 4ac4d723889d79ec2bb1e45c268998a21a0795dc /loader | |
| parent | 5dde6af87db95c156c6465ec77af53957c665e0e (diff) | |
loader makes fractal maps of kernel page tables, changed location of stack
Diffstat (limited to 'loader')
| -rw-r--r-- | loader/loader_efi.c | 50 |
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]; |
