-
Notifications
You must be signed in to change notification settings - Fork 0
RISC V Arch
Machine (M) Mode (highest privilege, mandatory, runs bootloader/firmware): Runs on physical memory
Supervisor (S) Mode (for operating systems), and : Runs on virtual memory
User (U) Mode (for applications): Runs on virtual memory
We use Firmware layer(like openSBI or ARM TFA) to standardise the interface between HW and OS kernel.
To protect kernel from accessing some HW register for security concerns. Firmware acts as secure monitor.
ARM TEE manages the transition from NORAML world to SECURE world.
This firmware layer also coordinates power states for multiples CPUs.
Firmware initialises early stages HWs like clocks, memory controllers and prepare the environment before handling it to kernel.
FDT: passing of dtb address to kernel In arm64, bootloader places the dtb address into x0 register. RISC V: The bootloader (or firmware like OpenSBI) puts the DTB address in register a1. Register a0 typically carries the Hart ID (CPU core ID).
DTB header: totalsize, off_dt_struct, off_dt_strings, off_mem_rsvmap, size_dt_struct, size_dt_strings
version, last_comp_version
boot_cpuid_phys
Memory Management:
Kernel enables the virtual memory.
Kernel does the identity mapping of current physical address and simultaneously also maps same physical address to high virtual address where kernel wants to live.
On RISC V: Kernel writes the early page table into satp register. As soon as write completes the the subsequent memory address is translated by MMU. Now, the MMU is ON, the kernel long jumps to high virtual address. Once running in high memory virtual address it discards the temporary identity mapping.
The kernel transitions by creating a temporary "trampoline" page table that maps its current location both physically and virtually, enabling the MMU via the satp register, and then jumping into the high-memory virtual address space.
In the RISC-V world, the kernel cannot simply "send a signal" to a dead core to wake it up. It must ask the OpenSBI layer to do it using the HSM (Hart State Management) extension.
a0: The Hart ID of the secondary core you want to wake up.
a1: The Physical Address (not virtual!) where the secondary core should start executing (usually an assembly "trampoline").
a2: An Opaque Parameter (usually a pointer to a struct containing that core's unique stack and page table info). ecall
Cold Boot: The very first hart starting from a power-on reset.
Warm Boot: Secondary harts starting up via an SBI HSM call.
Trampoline: The tiny bit of assembly code the secondary hart runs to enable its MMU before it can jump into C code.
I/O Virtualisation
qemu uses virtQueue for talking to devices. Three part of virtqueue
- Descriptor Table: Array which contains, DATA RAM pointer, size of data and flags(RO or WO)
- Available ring: Indices of descriptor to tell the device, that some work is there to do.
- Used Ring: Device's inbox. Device puts the descriptor index here to tell the driver that work is done.
Sending a network packet Workflow WorkFlow: Buffer preparation(Driver) -> Notification to work to Device (Driver) -> Processing (Device) -> Completion(Device) -> Clean up (Driver)
Adv: Zero copy data transfer. Only pointers are moved.
This process launches the first user process.
PMP is a RISC-V hardware feature that allows M-mode (the highest privilege) to set boundaries on what S-mode (Kernel) and U-mode (User apps) can access.
PMP is configured using two sets of Control and Status Registers (CSRs):
pmpaddrX: Stores the address boundary.
pmpcfgX: A configuration byte that defines the permissions for that address range:
R/W/X: Read, Write, Execute bits.
A (Address Matching): Defines how the address is interpreted (e.g., NAPOT - Naturally Aligned Power-of-Two, or TOR - Top of Range).
L (Locked): If set, even M-mode cannot change this setting until a system reset. This is crucial for "locking down" the system after boot.
MIDELEG (Machine Interrupt Delegation): When a bit is set here, the hardware is told: "When this interrupt happens, don't wake me (M-Mode). Wake up the Supervisor (S-Mode) instead."
MEDELEG (Machine Exception Delegation): This handles synchronous events like Page Faults or Illegal Instructions. If you didn't delegate these, every time a user program had a minor page fault, the CPU would trap into OpenSBI, slowing the system to a crawl.
RISC-V uses a layered privilege model. OpenSBI runs in M-Mode and uses MEDELEG and MIDELEG to delegate standard interrupts and exceptions down to the S-Mode Kernel. This avoids the overhead of trapping into firmware for routine tasks like Page Faults or software interrupts, while still allowing the firmware to maintain control over secure hardware resources.