Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

memmap.ld

This document explains memmap.ld, the single source of truth for the physical memory layout shared across every linked image in this project (currently jny, the bootloader, and emilia, the kernel).

Why this is its own repo

jny.ld and emilia.ld each need to agree on where RAM starts, how big it is, and where the boot region ends and the kernel region begins. If each repo hardcoded its own copy of those numbers, they could silently drift apart, one script gets edited, the other doesn't, and now the bootloader hands off to an address the kernel script doesn't actually own. Keeping the numbers in one place and pulling a copy into each consuming repo (via puller.toml/pulled.toml thanks to pff) means there is exactly one place to change the memory map, and every image that includes it picks up the same values.

The file

RAM_SIZE = 128M;
BOOT_ORIGIN = 0x80000000;
BOOT_LENGTH = 16K;
KERNEL_ORIGIN = BOOT_ORIGIN + BOOT_LENGTH;
KERNEL_LENGTH = RAM_SIZE - BOOT_LENGTH;
Constant Value Meaning
RAM_SIZE 128M Total usable RAM on the target (matches qemu-system-riscv64 -m 128M)
BOOT_ORIGIN 0x80000000 Start of DRAM on QEMU's RISC-V virt machine
BOOT_LENGTH 16K Size of the region reserved for the bootloader image
KERNEL_ORIGIN BOOT_ORIGIN + BOOT_LENGTH Start of the region reserved for the kernel image
KERNEL_LENGTH RAM_SIZE - BOOT_LENGTH Size of the region reserved for the kernel image

BOOT_ORIGIN is a QEMU/SiFive convention, not a RISC-V architectural requirement, virt reserves the low addresses for boot ROM and memory-mapped devices and leaves 0x80000000 as the start of DRAM. See jny.ld for the full breakdown of virt's memory map.

KERNEL_ORIGIN is defined in terms of BOOT_ORIGIN + BOOT_LENGTH rather than as its own literal, so the boot and kernel regions are always adjacent and non-overlapping by construction: grow BOOT_LENGTH and KERNEL_ORIGIN moves with it automatically, there's no second number to remember to update.

Who consumes this

  • jny.ld: the bootloader's linker script. Its MEMORY block is ORIGIN = BOOT_ORIGIN, LENGTH = BOOT_LENGTH, and it exposes _kstart = KERNEL_ORIGIN as the handoff address it jumps to once boot setup is done.
  • emilia.ld: the kernel's linker script. Its MEMORY block is ORIGIN = KERNEL_ORIGIN, LENGTH = KERNEL_LENGTH, picking up exactly where the boot region ends.

Known limitations (intentional, for this stage)

  • Single flat RAM region. No separate regions for boot ROM, flash, or MMIO device ranges, only the split between boot and kernel RAM. QEMU's virt machine's device ranges below 0x80000000 don't need describing here since neither consuming script ever places sections there.
  • No FPGA target yet. These values are QEMU-specific. A real SoC build will need its own memory map (or a variant of this one) once RAM size, origin, and any additional reserved regions are known for the actual board.

These will be revisited as the project grows, this file covers exactly what's needed for the two images that exist today.

About

Single source of truth for the physical memory layout (RAM origin, boot/kernel region split) shared by jny.ld and emilia.ld.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages