OUTPUT_ARCH(riscv) /* The kernel runs in the upper half: linked at its physical load address plus PHYS_OFFSET (mmu::PHYS_OFFSET), loaded at the physical address. Firmware jumps to the physical entry with the MMU off; _start switches to the high mapping before any Rust code runs. */ PHYS_OFFSET = 0xFFFFFFC000000000; LOAD_ADDRESS = 0x80200000; ENTRY(_start_phys) /* Every boundary below is page aligned: the kernel maps each range with its own permissions (W^X), see mmu::init_kernel_page_table. */ SECTIONS { . = PHYS_OFFSET + LOAD_ADDRESS; _text_start = .; .text : AT(ADDR(.text) - PHYS_OFFSET) { *(.text.entry) *(.text .text.*) } . = ALIGN(4096); _text_end = .; .rodata : AT(ADDR(.rodata) - PHYS_OFFSET) { *(.rodata .rodata.*) *(.srodata .srodata.*) } .eh_frame : AT(ADDR(.eh_frame) - PHYS_OFFSET) { *(.eh_frame) } . = ALIGN(4096); _rodata_end = .; .data : AT(ADDR(.data) - PHYS_OFFSET) { *(.data .data.*) *(.sdata .sdata.*) } . = ALIGN(4096); .bss : AT(ADDR(.bss) - PHYS_OFFSET) { _bss_start = .; *(.bss .bss.*) *(.sbss .sbss.*) _bss_end = .; } /* One kernel stack per hart (smp::MAX_HARTS, smp::STACK_SLOT): each slot is an unmapped guard page, so overflowing a stack faults instead of silently overwriting what lies below, then the stack. */ . = ALIGN(4096); _stacks_start = .; . += 8 * (4096 + 0x80000); _stacks_end = .; _heap_start = .; } _start_phys = _start - PHYS_OFFSET;