From aa3f73440637318e263add95abbbc6df568782d0 Mon Sep 17 00:00:00 2001 From: Jozef Nagy Date: Thu, 17 Apr 2025 16:28:43 +0200 Subject: [PATCH] Fixed paging --- boot/arch/x86_64/common/mm/paging.c | 2 +- boot/common/proto/aurix.c | 15 +-- boot/include/mm/memmap.h | 50 +++++++++ boot/platform/uefi/mm/memmap.c | 153 ++++++++++++++++++++++++++++ 4 files changed, 212 insertions(+), 8 deletions(-) create mode 100644 boot/include/mm/memmap.h create mode 100644 boot/platform/uefi/mm/memmap.c diff --git a/boot/arch/x86_64/common/mm/paging.c b/boot/arch/x86_64/common/mm/paging.c index 2c65b4d..40826fd 100644 --- a/boot/arch/x86_64/common/mm/paging.c +++ b/boot/arch/x86_64/common/mm/paging.c @@ -59,7 +59,7 @@ static void _map(pagetable *pm, uintptr_t virt, uintptr_t phys, uint64_t flags) pagetable *pml1_table = (pagetable *)(pml2_table->entries[pml2_idx] & 0x000FFFFFFFFFF000); if ((pml1_table->entries[pml1_idx] & 1)) { - debug("_map(): Remapping present page\n"); + // debug("_map(): Remapping present page\n"); } pml1_table->entries[pml1_idx] = (phys & 0x000FFFFFFFFFF000) | flags; diff --git a/boot/common/proto/aurix.c b/boot/common/proto/aurix.c index 10fa041..5c79856 100644 --- a/boot/common/proto/aurix.c +++ b/boot/common/proto/aurix.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -30,21 +31,22 @@ extern __attribute__((noreturn)) void aurix_handoff(void *pagemap, void *stack, uint64_t entry, void *params); extern char _aurix_handoff_start[], _aurix_handoff_end[]; -void aurix_load(char *kernel) +void aurix_load(char *kernel_path) { // read kernel -> test read char *kbuf = NULL; - vfs_read(kernel, &kbuf); - + vfs_read(kernel_path, &kbuf); + // TODO: Do something with the kernel :p pagetable *pm = create_pagemap(); - // __asm__ volatile("mov %%cr3, %0" : "=r"(pm)); if (!pm) { debug("aurix_load(): Failed to create kernel pagemap! Halting...\n"); // TODO: Halt while (1); } + axboot_memmap *memmap = get_memmap(pm); + map_pages(pm, (uintptr_t)pm, (uintptr_t)pm, PAGE_SIZE, VMM_WRITABLE); map_pages(pm, (uintptr_t)_aurix_handoff_start, (uintptr_t)_aurix_handoff_start, (uint64_t)_aurix_handoff_end - (uint64_t)_aurix_handoff_start, 0); @@ -58,7 +60,7 @@ void aurix_load(char *kernel) void *kernel_entry = (void *)elf_load(kbuf, pm); if (!kernel_entry) { - debug("aurix_load(): Failed to load '%s'! Halting...\n", kernel); + debug("aurix_load(): Failed to load '%s'! Halting...\n", kernel_path); mem_free(kbuf); while (1); } @@ -75,6 +77,5 @@ void aurix_load(char *kernel) "movq %[stack], %%rsp\n" "callq *%[entry]\n" :: [pml4]"r"(pm), [stack]"r"(stack), [entry]"r"(kernel_entry) : "memory"); - // __asm__ volatile("callq *%[entry]\n" - // :: [entry]"r"(kernel_entry)); + __builtin_unreachable(); } diff --git a/boot/include/mm/memmap.h b/boot/include/mm/memmap.h new file mode 100644 index 0000000..6f2e629 --- /dev/null +++ b/boot/include/mm/memmap.h @@ -0,0 +1,50 @@ +/*********************************************************************************/ +/* Module Name: memmap.h */ +/* Project: AurixOS */ +/* */ +/* Copyright (c) 2024-2025 Jozef Nagy */ +/* */ +/* This source is subject to the MIT License. */ +/* See License.txt in the root of this repository. */ +/* All other rights reserved. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */ +/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */ +/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */ +/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */ +/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */ +/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ +/* SOFTWARE. */ +/*********************************************************************************/ + +#ifndef _MEM_MEMMAP_H +#define _MEM_MEMMAP_H + +#include + +enum AxBootMemMapType { + MemMapReserved = 0, + MemMapFaulty = 1, + + MemMapACPIReclaimable = 2, + MemMapACPIMappedIO = 3, + MemMapACPIMappedIOPortSpace = 4, + MemMapACPINVS = 5, + + MemMapFirmware = 6, + + // stuff we can consider usable after loading the kernel + MemMapFreeOnLoad = 7, + + MemMapUsable = 10, +}; + +typedef struct _axboot_memmap { + uintptr_t base; + uintptr_t size; + int type; +} axboot_memmap; + +axboot_memmap *get_memmap(); + +#endif /* _MEM_MEMMAP_H */ \ No newline at end of file diff --git a/boot/platform/uefi/mm/memmap.c b/boot/platform/uefi/mm/memmap.c new file mode 100644 index 0000000..d0dee4e --- /dev/null +++ b/boot/platform/uefi/mm/memmap.c @@ -0,0 +1,153 @@ +/*********************************************************************************/ +/* Module Name: memmap.c */ +/* Project: AurixOS */ +/* */ +/* Copyright (c) 2024-2025 Jozef Nagy */ +/* */ +/* This source is subject to the MIT License. */ +/* See License.txt in the root of this repository. */ +/* All other rights reserved. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */ +/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */ +/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */ +/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */ +/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */ +/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ +/* SOFTWARE. */ +/*********************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int efi_type_to_axboot(uint32_t efi_type) +{ + switch (efi_type) { + case EfiReservedMemoryType: + return MemMapReserved; + case EfiLoaderCode: + return MemMapFirmware; + case EfiLoaderData: + return MemMapFirmware; + case EfiBootServicesCode: + case EfiBootServicesData: + return MemMapFreeOnLoad; + case EfiRuntimeServicesCode: + case EfiRuntimeServicesData: + return MemMapFirmware; + case EfiConventionalMemory: + return MemMapUsable; + case EfiUnusableMemory: + return MemMapFaulty; + case EfiACPIReclaimMemory: + return MemMapACPIReclaimable; + case EfiACPIMemoryNVS: + return MemMapACPINVS; + case EfiMemoryMappedIO: + return MemMapACPIMappedIO; + case EfiMemoryMappedIOPortSpace: + return MemMapACPIMappedIOPortSpace; + case EfiPalCode: + return MemMapUsable; + case EfiPersistentMemory: + return MemMapUsable; + case EfiUnacceptedMemoryType: + return MemMapReserved; + default: + return MemMapReserved; + } +} + +axboot_memmap *get_memmap(pagetable *pm) +{ + EFI_MEMORY_DESCRIPTOR *efi_map; + EFI_UINTN efi_map_key; + EFI_UINTN size = 0; + EFI_UINTN desc_size; + EFI_UINT32 desc_ver; + EFI_STATUS status; + + status = gBootServices->GetMemoryMap(&size, efi_map, &efi_map_key, &desc_size, &desc_ver); + if (EFI_ERROR(status) && status != EFI_BUFFER_TOO_SMALL) { + debug("get_memmap(): GetMemoryMap() returned an error: %s (0x%llx)\n", efi_status_to_str(status), status); + return NULL; + } + + efi_map = (EFI_MEMORY_DESCRIPTOR *)mem_alloc(size); + + do { + status = gBootServices->GetMemoryMap(&size, efi_map, &efi_map_key, &desc_size, &desc_ver); + if (!EFI_ERROR(status)) { + break; + } else if (status == EFI_BUFFER_TOO_SMALL) { + size += 2 * desc_size; + efi_map = (EFI_MEMORY_DESCRIPTOR *)mem_realloc(efi_map, size); + } else { + debug("get_memmap(): GetMemoryMap() returned an error: %s (0x%llx)\n", efi_status_to_str(status), status); + return NULL; + } + } while (status != EFI_SUCCESS); + + EFI_MEMORY_DESCRIPTOR *cur_entry = efi_map; + uint32_t entry_count = size / desc_size; + + // map all the memory + for (int i = 0; i < entry_count; i++) { + uint64_t flags; + switch (cur_entry->Type) { + case EfiConventionalMemory: + case EfiBootServicesCode: + case EfiBootServicesData: + flags = VMM_WRITABLE; + break; + case EfiRuntimeServicesCode: + flags = 0; + break; + case EfiRuntimeServicesData: + case EfiACPIReclaimMemory: + case EfiACPIMemoryNVS: + case EfiMemoryMappedIO: + case EfiMemoryMappedIOPortSpace: + flags = VMM_WRITABLE | VMM_NX; + break; + case EfiUnusableMemory: + case EfiReservedMemoryType: + case EfiLoaderData: + case EfiLoaderCode: + case EfiPalCode: + flags = 0; + break; + default: + flags = VMM_WRITABLE | VMM_NX; + break; + } + + map_pages(pm, cur_entry->PhysicalStart, cur_entry->PhysicalStart, cur_entry->NumberOfPages * PAGE_SIZE, flags); + cur_entry = (EFI_MEMORY_DESCRIPTOR *)((uint8_t *)cur_entry + desc_size); + } + + axboot_memmap *new_map = (axboot_memmap *)mem_alloc(sizeof(axboot_memmap) * entry_count); + memset(new_map, 0, sizeof(axboot_memmap) * entry_count); + + cur_entry = efi_map; + + // translate efi memmap to axboot memmap + for (int i = 0; i < entry_count; i++) { + new_map[i].base = cur_entry->PhysicalStart; + new_map[i].size = cur_entry->NumberOfPages * PAGE_SIZE; + new_map[i].type = efi_type_to_axboot(efi_map[i].Type); + + cur_entry = (EFI_MEMORY_DESCRIPTOR *)((uint8_t *)cur_entry + desc_size); + } + + mem_free(efi_map); + + return new_map; +}