Memory management
Memory capabilities provide access to general-purpose memory to the bearer, and from these capabilities, various kernel objects may be allocated, such as address spaces and page tables, tasks, IPC objects, and so on.
On startup, after loading the kernel and the user init program, all remaining general purpose memory is enumerated and provided to the user init program in the form of these Memory capabilities. The user init program may allocate resources from their Memory capabilities, subdivide them into further Memory capabilities, or transfer them to other processes.
Allocating objects
Objects are allocated via Memory::ALLOC. Some objects have a fixed size,
such as Tasks, while others accept a size parameter that governs the size of the
resulting object. For example, a CSpace has a radix parameter that determines
the number of available capability slots.
Reference counts
Objects allocated from memory capabilities have reference counts. Copying or destroying the capability associated with an object generally updates its reference count. The maximum number of references to any kernel object is 256, further attempts to copy capabilities that reference such objects will result in ERANGE errors.
Overhead
Each memory area stores a bitmap of allocations and a list of reference counts, as well as some metadata. The overhead is subtracted from the total amount of available memory in a Memory capability.
Contiguous allocations
Over time, a Memory capability can become fragmented, and allocations are not guaranteed to occupy continuous ranges of physical memory.
If contiguous allocations are required, for example to establish a large area for DMA, it is recommended to allocate a new Memory capability and then allocate Pages from that capability. Allocations on a new Memory capability are guaranteed to be contiguous until the first object is freed, after which point the allocations may be non-contiguous.
Object sizes
The amount of memory required for a kernel object is either a fixed size, or is a function of its initialization parameters. The semantics for memory allocation are described on each allocatable capability’s page in the documentation.
By scrutinizing these semantics, userspace programs may reckon the amount of
memory available in a Memory capability before and after any allocation. This
information may also be queried at runtime via Memory::GET_FREE_PAGES.