diff options
Diffstat (limited to 'kernel/linker-scripts/riscv64.lds')
| -rw-r--r-- | kernel/linker-scripts/riscv64.lds | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/kernel/linker-scripts/riscv64.lds b/kernel/linker-scripts/riscv64.lds new file mode 100644 index 0000000..51b6330 --- /dev/null +++ b/kernel/linker-scripts/riscv64.lds @@ -0,0 +1,92 @@ +/* Tell the linker that we want a riscv64 ELF64 output file */ +OUTPUT_FORMAT(elf64-littleriscv) + +/* We want the symbol kmain to be our entry point */ +ENTRY(kmain) + +/* Define the program headers we want so the bootloader gives us the right */ +/* MMU permissions; this also allows us to exert more control over the linking */ +/* process. */ +PHDRS +{ + limine_requests PT_LOAD; + text PT_LOAD; + rodata PT_LOAD; + data PT_LOAD; +} + +SECTIONS +{ + /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ + /* and because that is what the Limine spec mandates. */ + /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ + /* that is the beginning of the region. */ + . = 0xffffffff80000000; + + kernel_start = .; + + /* Define a section to contain the Limine requests and assign it to its own PHDR */ + .limine_requests : { + KEEP(*(.limine_requests_start)) + KEEP(*(.limine_requests)) + KEEP(*(.limine_requests_end)) + } :limine_requests + + /* Move to the next memory page for .text */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .text : { + *(.text .text.*) + } :text + + /* Move to the next memory page for .rodata */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .rodata : { + *(.rodata .rodata.*) + *(.srodata .srodata.*) + *(.sdata2 .sdata2.*) + } :rodata + + /* Add a .note.gnu.build-id output section in case a build ID flag is added to the */ + /* linker command. */ + .note.gnu.build-id : { + *(.note.gnu.build-id) + } :rodata + + /* C++ is a language that allows for global constructors. In order to obtain the */ + /* address of the ".init_array" section we need to define a symbol for it. */ + .init_array : { + __init_array = .; + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(.init_array .ctors)) + __init_array_end = .; + } :rodata + + /* Move to the next memory page for .data */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .data : { + *(.data .data.*) + *(.sdata .sdata.*) + } :data + + /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ + /* unnecessary zeros will be written to the binary. */ + /* If you need, for example, .init_array and .fini_array, those should be placed */ + /* above this. */ + .bss : { + *(.bss .bss.*) + *(.sbss .sbss.*) + *(COMMON) + } :data + + /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ + /DISCARD/ : { + *(.eh_frame*) + *(.note .note.*) + } + + kernel_end = .; + +} |
