From 404be92d431fb8cc9069c3980476ee3f1058b3e0 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 8 May 2023 05:15:56 +0300 Subject: [PATCH] Rewrite the linker script --- Architecture/amd64/linker.ld | 64 ++++++++++++++++++++++++---------- Core/Memory/Memory.cpp | 66 ++++++++++++++++++++++++++++++------ include/memory.hpp | 6 +++- 3 files changed, 107 insertions(+), 29 deletions(-) diff --git a/Architecture/amd64/linker.ld b/Architecture/amd64/linker.ld index 554fbed..bfaf98b 100644 --- a/Architecture/amd64/linker.ld +++ b/Architecture/amd64/linker.ld @@ -20,55 +20,83 @@ OUTPUT_ARCH(i386:x86-64) ENTRY(_start) +PF_R = 0x4; +PF_W = 0x2; +PF_X = 0x1; + +PHDRS +{ + bootstrap PT_LOAD FLAGS( PF_R | PF_W /*| PF_X*/ ); + text PT_LOAD FLAGS( PF_R | PF_X ); + data PT_LOAD FLAGS( PF_R | PF_W ); + rodata PT_LOAD FLAGS( PF_R ); + bss PT_LOAD FLAGS( PF_R | PF_W ); +} + +KERNEL_VMA = 0xFFFFFFFF80000000; + SECTIONS { - . = 0xffffffff80000000; + . = 0x100000; + _bootstrap_start = .; + .bootstrap : + { + *(.bootstrap .bootstrap.*) + } :bootstrap + . += CONSTANT(MAXPAGESIZE); + _bootstrap_end = ALIGN(CONSTANT(MAXPAGESIZE)); - _kernel_start = .; - .text : + . += KERNEL_VMA; + + _kernel_start = ALIGN(CONSTANT(MAXPAGESIZE)); + _kernel_text_start = ALIGN(CONSTANT(MAXPAGESIZE)); + .text : AT(ADDR(.text) - KERNEL_VMA) { *(.text .text.*) - } - _kernel_text_end = ALIGN(CONSTANT(MAXPAGESIZE)); + } :text . += CONSTANT(MAXPAGESIZE); + _kernel_text_end = ALIGN(CONSTANT(MAXPAGESIZE)); - .data : + _kernel_data_start = ALIGN(CONSTANT(MAXPAGESIZE)); + .data : AT(ADDR(.data) - KERNEL_VMA) { *(.data .data.*) - } - _kernel_data_end = ALIGN(CONSTANT(MAXPAGESIZE)); + } :data . += CONSTANT(MAXPAGESIZE); + _kernel_data_end = ALIGN(CONSTANT(MAXPAGESIZE)); - .rodata : + _kernel_rodata_start = ALIGN(CONSTANT(MAXPAGESIZE)); + .rodata : AT(ADDR(.rodata) - KERNEL_VMA) { *(.rodata .rodata.*) - } - _kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE)); - . += CONSTANT(MAXPAGESIZE); + } :rodata - .init_array : + .init_array : AT(ADDR(.init_array) - KERNEL_VMA) { PROVIDE_HIDDEN(__init_array_start = .); KEEP(*(.init_array .ctors)) KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) PROVIDE_HIDDEN (__init_array_end = .); - } + } :rodata - .fini_array : + .fini_array : AT(ADDR(.fini_array) - KERNEL_VMA) { PROVIDE_HIDDEN(__fini_array_start = .); KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) KEEP(*(.fini_array .dtors)) PROVIDE_HIDDEN (__fini_array_end = .); - } + } :rodata . += CONSTANT(MAXPAGESIZE); + _kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE)); - .bss : + _kernel_bss_start = ALIGN(CONSTANT(MAXPAGESIZE)); + .bss : AT(ADDR(.bss) - KERNEL_VMA) { *(COMMON) *(.bss .bss.*) - } + } :bss . += CONSTANT(MAXPAGESIZE); + _kernel_bss_end = ALIGN(CONSTANT(MAXPAGESIZE)); _kernel_end = ALIGN(CONSTANT(MAXPAGESIZE)); /DISCARD/ : diff --git a/Core/Memory/Memory.cpp b/Core/Memory/Memory.cpp index f1ae7f0..303bf1c 100644 --- a/Core/Memory/Memory.cpp +++ b/Core/Memory/Memory.cpp @@ -146,26 +146,70 @@ NIF void MapFramebuffer(PageTable *PT, BootInfo *Info) NIF void MapKernel(PageTable *PT, BootInfo *Info) { debug("Mapping Kernel"); - uintptr_t KernelStart = (uintptr_t)&_kernel_start; + + /* RWX */ + uintptr_t BootstrapStart = (uintptr_t)&_bootstrap_start; + uintptr_t BootstrapEnd = (uintptr_t)&_bootstrap_end; + + /* RX */ + uintptr_t KernelTextStart = (uintptr_t)&_kernel_text_start; uintptr_t KernelTextEnd = (uintptr_t)&_kernel_text_end; + + /* RW */ + uintptr_t KernelDataStart = (uintptr_t)&_kernel_data_start; uintptr_t KernelDataEnd = (uintptr_t)&_kernel_data_end; + + /* R */ + uintptr_t KernelRoDataStart = (uintptr_t)&_kernel_rodata_start; uintptr_t KernelRoDataEnd = (uintptr_t)&_kernel_rodata_end; + + /* RW */ + uintptr_t KernelBssStart = (uintptr_t)&_kernel_bss_start; + uintptr_t KernelBssEnd = (uintptr_t)&_kernel_bss_end; + + uintptr_t KernelStart = (uintptr_t)&_kernel_start; uintptr_t KernelEnd = (uintptr_t)&_kernel_end; uintptr_t KernelFileStart = (uintptr_t)Info->Kernel.FileBase; uintptr_t KernelFileEnd = KernelFileStart + Info->Kernel.Size; + debug("Bootstrap: %#lx-%#lx", BootstrapStart, BootstrapEnd); + debug("Kernel text: %#lx-%#lx", KernelTextStart, KernelTextEnd); + debug("Kernel data: %#lx-%#lx", KernelDataStart, KernelDataEnd); + debug("Kernel rodata: %#lx-%#lx", KernelRoDataStart, KernelRoDataEnd); + debug("Kernel bss: %#lx-%#lx", KernelBssStart, KernelBssEnd); + debug("Kernel: %#lx-%#lx", KernelStart, KernelEnd); + debug("Kernel file: %#lx-%#lx", KernelFileStart, KernelFileEnd); + debug("File size: %ld KB", TO_KB(Info->Kernel.Size)); - debug(".text size: %ld KB", TO_KB(KernelTextEnd - KernelStart)); - debug(".data size: %ld KB", TO_KB(KernelDataEnd - KernelTextEnd)); - debug(".rodata size: %ld KB", TO_KB(KernelRoDataEnd - KernelDataEnd)); - debug(".bss size: %ld KB", TO_KB(KernelEnd - KernelRoDataEnd)); + debug(".bootstrap size: %ld KB", TO_KB(BootstrapEnd - BootstrapStart)); + debug(".text size: %ld KB", TO_KB(KernelTextEnd - KernelTextStart)); + debug(".data size: %ld KB", TO_KB(KernelDataEnd - KernelDataStart)); + debug(".rodata size: %ld KB", TO_KB(KernelRoDataEnd - KernelRoDataStart)); + debug(".bss size: %ld KB", TO_KB(KernelBssEnd - KernelBssStart)); uintptr_t BaseKernelMapAddress = (uintptr_t)Info->Kernel.PhysicalBase; + debug("Base kernel map address: %#lx", BaseKernelMapAddress); uintptr_t k; Virtual va = Virtual(PT); + /* Bootstrap section */ + if (BaseKernelMapAddress == BootstrapStart) + { + for (k = BootstrapStart; k < BootstrapEnd; k += PAGE_SIZE) + { + va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); + KernelAllocator.ReservePage((void *)BaseKernelMapAddress); + BaseKernelMapAddress += PAGE_SIZE; + } + } + else + { + trace("Ignoring bootstrap section."); + /* Bootstrap section must be mapped at 0x100000. */ + } + /* Text section */ - for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE) + for (k = KernelTextStart; k < KernelTextEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); KernelAllocator.ReservePage((void *)BaseKernelMapAddress); @@ -173,7 +217,7 @@ NIF void MapKernel(PageTable *PT, BootInfo *Info) } /* Data section */ - for (k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE) + for (k = KernelDataStart; k < KernelDataEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); KernelAllocator.ReservePage((void *)BaseKernelMapAddress); @@ -181,21 +225,23 @@ NIF void MapKernel(PageTable *PT, BootInfo *Info) } /* Read only data section */ - for (k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE) + for (k = KernelRoDataStart; k < KernelRoDataEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::G); KernelAllocator.ReservePage((void *)BaseKernelMapAddress); BaseKernelMapAddress += PAGE_SIZE; } - /* BSS section */ - for (k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE) + /* Block starting symbol section */ + for (k = KernelBssStart; k < KernelBssEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); KernelAllocator.ReservePage((void *)BaseKernelMapAddress); BaseKernelMapAddress += PAGE_SIZE; } + debug("Base kernel map address: %#lx", BaseKernelMapAddress); + /* Kernel file */ for (k = KernelFileStart; k < KernelFileEnd; k += PAGE_SIZE) { diff --git a/include/memory.hpp b/include/memory.hpp index 7b1fd4d..fc42edd 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -29,8 +29,12 @@ #ifdef __cplusplus +extern uintptr_t _bootstrap_start, _bootstrap_end; extern uintptr_t _kernel_start, _kernel_end; -extern uintptr_t _kernel_text_end, _kernel_data_end, _kernel_rodata_end; +extern uintptr_t _kernel_text_start, _kernel_text_end; +extern uintptr_t _kernel_data_start, _kernel_data_end; +extern uintptr_t _kernel_rodata_start, _kernel_rodata_end; +extern uintptr_t _kernel_bss_start, _kernel_bss_end; // kilobyte #define TO_KB(d) ((d) / 1024)