diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-04-17 01:05:31 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-04-17 01:05:31 +0800 |
| commit | e2564d112ba03b432f9f44f445cbc4a3ed85751a (patch) | |
| tree | 1541ee010bfd9c0e614fc91c2de5c9aa741418ae /na/linker.ld | |
| parent | 81563cb415d8214f1d1e34f73d49a404424f8f2c (diff) | |
| download | lume-e2564d112ba03b432f9f44f445cbc4a3ed85751a.tar.gz lume-e2564d112ba03b432f9f44f445cbc4a3ed85751a.tar.xz | |
feat: add initial RISC-V architecture support and core kernel functionality
- Implement MMU hardware primitives for RISC-V SV39 in mmu.h
- Create trap vector control primitives in trap.h
- Define trap frame structure for RISC-V in trapframe.h
- Add assembly routines for context switching in swtch.S
- Implement trap vector entry/exit in trap_vector.S
- Introduce basic error number definitions in errno.h
- Provide placement new/delete operators in new.h
- Define kernel panic handler in panic.h and implement in panic.cc
- Establish basic type definitions in types.h
- Create the kernel main entry point in main.cc with global initialization
- Add synchronization primitives using spinlocks in spinlock.h and spinlock.cc
- Define per-CPU state tracking for interrupts in cpu_state.h
- Create a linker script for the kernel in linker.ld
- Update module makefiles for kernel and library components
Diffstat (limited to 'na/linker.ld')
| -rw-r--r-- | na/linker.ld | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/na/linker.ld b/na/linker.ld new file mode 100644 index 0000000..54f619c --- /dev/null +++ b/na/linker.ld @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2026 Richard Qin */ + +/* + * LumeOS Kernel Linker Script + * + * Memory Layout (SV39 Higher-Half Kernel): + * Virtual Base: 0xFFFFFFC080200000 + * Physical Base: 0x80200000 + * VA-PA Offset: 0xFFFFFFC000000000 (PAGE_OFFSET) + * + * The AT() directives produce correct LMA (Load Memory Address) so the + * bootloader loads sections at their physical addresses while the kernel + * code references their virtual addresses. + * + * Reference: docs/specs/linker_and_entry.md + */ + +OUTPUT_ARCH(riscv) + +PAGE_OFFSET = 0xFFFFFFC000000000; +BASE_ADDRESS = 0xFFFFFFC080200000; +PHYS_BASE = 0x80200000; + +/* ELF entry point must be the PHYSICAL address because OpenSBI/QEMU + * jumps to it before MMU is enabled. _start is at VMA, so we use + * the computed physical equivalent. */ +ENTRY(_start) + +SECTIONS { + . = BASE_ADDRESS; + + /* ===== .head.text: Image Header (must be at byte 0) ===== */ + .head.text : AT(PHYS_BASE) { + _start = .; + KEEP(*(.head.text)) + } + + /* ===== .text: Executable Code ===== */ + .text : AT(ADDR(.text) - PAGE_OFFSET) { + _stext = .; + *(.text .text.*) + _etext = .; + } = 0 + + . = ALIGN(4096); + + /* ===== .rodata: Read-Only Data ===== */ + .rodata : AT(ADDR(.rodata) - PAGE_OFFSET) { + _srodata = .; + *(.rodata .rodata.*) + + /* C++ global constructor table (.init_array) */ + . = ALIGN(8); + __init_array_start = .; + KEEP(*(.init_array .init_array.*)) + __init_array_end = .; + + _erodata = .; + } + + . = ALIGN(4096); + + /* ===== .data: Initialized Read-Write Data ===== */ + .data : AT(ADDR(.data) - PAGE_OFFSET) { + _sdata = .; + *(.data .data.*) + + /* GP anchor: RISC-V medany model uses gp-relative addressing + * for .sdata/.sbss within +/- 2KB of __global_pointer$ */ + . = ALIGN(16); + PROVIDE(__global_pointer$ = . + 0x800); + *(.sdata .sdata.*) + + _edata = .; + } + + . = ALIGN(4096); + + /* ===== .bss: Uninitialized Data (zeroed by entry.S) ===== */ + .bss : AT(ADDR(.bss) - PAGE_OFFSET) { + _sbss = .; + *(.bss .bss.*) + *(.sbss .sbss.*) + + /* Early page table: 4KB aligned, used by entry.S before VMM */ + . = ALIGN(4096); + early_pgdir = .; + . += 4096; + + /* Per-CPU boot stacks: 8KB per CPU, max 8 CPUs */ + . = ALIGN(4096); + boot_stack = .; + . += 8192 * 8; /* NCPU_MAX = 8, BOOT_STACK_SIZE = 8KB */ + boot_stack_top = .; + + _ebss = .; + } + + . = ALIGN(4096); + + /* ===== End of kernel image ===== */ + _kernel_end = .; + + /* Discard unwanted sections */ + /DISCARD/ : { + *(.eh_frame .eh_frame_hdr) + *(.note .note.*) + *(.comment) + } +}
\ No newline at end of file |
