This page is intended to provide an informal overview of the internals of the RISC OS kernel, to help inform OS maintainers of how everything fits together.
The kernel source is located at RiscOS/Sources/Kernel in gitlab. Currently the main development branch is the master branch, but there are many other branches which have performed key roles over the years. As a summary:
There are five main parts to the kernel source:
The kernel workspace is defined in hdr.KernelWS. There are two workspace layouts available:
The type of workspace in use is selected via the HighProcVecs option in hdr.Options.
Although the majority of the kernel workspace is kept private, there are several locations exported publicly to the rest of the OS in hdr.PublicWS. However only the legacy locations are exported here; for compatibility with kernels that use zero page relocation, programs should first attempt to query the address using OS_ReadSysInfo 6 before falling back on the legacy address.
Significant workspace locations are listed below:
CursorChunkAddress marks the start of a second area of workspace (currently) located at &FAFF0000. This area is used for the cursor & sound DMA buffers, along with the OSCLI workspace and SWI/IRQ dispatchers.
The SWI despatcher is a small routine that gets copied out of ROM (see SVCDespatcher in s.Kernel).
The default IRQ dispatcher is a small routine that gets copied out of ROM (see DefaultIRQ1Vcode in s.NewIRQs).
The CAM is a data structure used to track the allocation of physical RAM pages. The name refers to the Content-Addressable Memory that the MEMC chips used to store the memory map. In MEMC, the CAM wasn’t readable by the CPU – so to avoid losing track of what memory was being used where, the OS had to maintain its own copy of the data. This is the origin of the RAM-based “CAM soft copy” that is described here. Modern ARMs handle memory mapping in a different way, using TLBs and RAM-based page tables, but the “CAM” name in the OS sources has stuck, and the data structure still serves a useful purpose.
This RAM based CAM is implemented as a simple table indexed by the physical (RAM) page number. Each CAM entry is four words long. PhysRamTable is used to map the physical RAM page numbers to and from physical addresses.
Word | Meaning |
---|---|
0 | Logical address the page is currently mapped to, or ‘DuffEntry’ if unmapped |
1 | PPL (“Page protection level”) and additional flags (see below table) |
2 | Physical memory pool (actually, DANode pointer). Invalid if PMP flag not set. |
3 | Page index in physical memory pool. Invalid if PMP flag not set. |
PPL/page flags:
Bit(s) | Meaning |
---|---|
0-14 | PPL, cacheable/noncacheable, flags, etc. Same as bits 0-14 of the Memory Page Access Flags. |
15 | “Unavailable” flag. Used to mark pages that have been requested by a dynamic area PreGrow handler, but haven’t yet been moved. |
16-19 | “Temporary count of uncacheability”, used when pages are made temporarily uncacheable via OS_Memory 0 |
20 | Bit 20 of Memory Page Access Flags |
21 | “Required” flag. Used to mark pages that have been specifically requested by dynamic areas. This guarantees that the page won’t be used for another purpose until the dynamic area releases it, e.g. for hardware IO buffers. |
The above flags are all defined in s.ChangeDyn, at the DynamicAreaSWI code.
Older kernels (prior to the introduction of physical memory pools) only used two words per CAM entry, and had different flag allocations.