Deferred system RAM
Deferred system RAM allows you to add one or more contiguous regions of the physical address space to the System RAM managed by the Virtual Memory Manager (VMM) at runtime. This is useful in scenarios where initializing a large amount of ECC (error correction code) memory significantly lengthens boot time of the first process (and therefore, subsequent processes). Instead, you can initialize a smaller amount of ECC RAM to boot the kernel and run essential processes, and defer the ECC initialization of the remaining RAM afterwards.
Using deferred system RAM can take a significant amount of time and interfere with other VMM-based operations (e.g., mmap()). Therefore, you should minimize or avoid VMM-based and time-sensitive operations when using this functionality.
- readable, writable, and cacheable
- cache-coherent
- initialized and ready for immediate use
- suitable for use as a DMA source or destination by all DMA-capable devices under the control of QNX
_mem_pmem_add and mem_pmem_add_t
To add RAM using the deferred system RAM mechanism, you must send a mem_pmem_add_t structure to the memory manager server via the MEMMGR_COID connection. The RAM shouldn't have any mappings to it at the time it's added.
The syntax for _mem_pmem_add and mem_pmem_add_t is as follows:
struct _mem_pmem_add {
_Uint16t type;
_Uint16t zero1;
_Uint32t zero2;
_Uint64t addr;
_Uint64t len;
};
typedef union {
struct _mem_pmem_add i;
} mem_pmem_add_t;
- type
- The message type; set to _MEM_PMEM_ADD.
- zero1, zero2
- Unused; set to zero.
- addr
- The base address of the region of RAM to be added. This must be a
zone-aligned value, where a zone (also referred to as a contiguous
physical memory block) is 16 MiB (16 * 1024 * 1024).Note:QNX only supports physical addresses in the range [0, 16TiB[.
- len
- The length of the region of RAM to be added. This must be an integral multiple of a zone.
Deferred system RAM uses the contiguous physical address range to be added, where:
- The ability check is done on the unrounded range.
- The address range is rounded before it's considered for adding to system RAM,
where
end = start + len. Ifendisn't the address of the highest byte of a page, then roundenddown to the next lower page address by clearing the bottom 12 bits, and then subtracting 1. Ifstartis not a page-aligned address, it's rounded up to the next higher page-aligned address.
If the region is successfully added, the return value is 0 (EOK).
Example
The following example demonstrates how to use the deferred system RAM functionality by:
- initializing the message by setting it to 0, or using a designated initializer.
- initializing the type, addr, and
len fields such that:
- the type is _MEM_PMEM_ADD.
- the len is a multiple of the size of a zone.
- sending the message to the memory manager via MEMMGR_COID.
- returning errors returned by MsgSend_r().
#include <sys/memmsg.h>
int deferred_sysram_add_ram(const uint64_t base_addr, const uint64_t len)
{
// Note that everything else in the struct will be zeroed
const mem_pmem_add_t msg = {
.i.type = _MEM_PMEM_ADD,
.i.addr = base_addr,
.i.len = len,
};
const int rv = MsgSend_r(MEMMGR_COID, &msg, sizeof(msg), NULL, 0);
return rv;
}
Using deferred system RAM at startup
The following steps show you how to use deferred system RAM with your program:
- Before making any changes, observe the contents of the asinfo
section:
/ # pidin syspage=asinfo Header size=0x000000f0, Total Size=0x00000980, Version=2.0, #Cpu=2, Type=4352 Section:asinfo offset:0x000005c0 size:0x00000240 elsize:0x00000018 0000) 0000000000000000-000000000000ffff o:ffff /io 0018) 0000000000000000-000fffffffffffff o:ffff /memory 0030) 0000000000000000-00000000ffffffff o:0018 /memory/below4G 0048) 0000000000000000-0000000000ffffff o:0018 /memory/isa 0060) 0000000006000000-00000000ffefffff o:0018 /memory/device 0078) 00000000fff00000-00000000ffffffff o:0018 /memory/rom 0090) 0000000000000000-000000000009fbff o:0048 /memory/isa/ram 00a8) 0000000000100000-0000000000ffffff o:0048 /memory/isa/ram 00c0) 0000000001000000-0000000005ffffff o:0030 /memory/below4G/ram 00d8) 0000000006000000-00000000bffdffff o:0060 /memory/device/ram 00f0) 0000000100000000-000000023fffffff o:0018 /memory/ram 0108) 00000000000f5a60-00000000000f5a73 o:0018 /memory/acpi_rsdp 0120) 00000000fee00000-00000000fee003ef o:0018 /memory/lapic 0138) 0000000000835348-0000000000e2e043 o:0018 /memory/imagefs 0150) 0000000000800200-0000000000835347 o:0018 /memory/startup 0168) 0000000000835348-0000000000e2e043 o:0018 /memory/bootram 0180) 0000000000001000-000000000009efff o:0090 /memory/isa/ram/sysram 0198) 0000000000100000-000000000010ffff o:00a8 /memory/isa/ram/sysram 01b0) 0000000000117000-0000000000117fff o:00a8 /memory/isa/ram/sysram 01c8) 000000000011f000-0000000000834fff o:00a8 /memory/isa/ram/sysram 01e0) 0000000000e2f000-0000000000ffffff o:00a8 /memory/isa/ram/sysram 01f8) 0000000001000000-0000000005ffffff o:00c0 /memory/below4G/ram/sysram 0210) 0000000006000000-00000000bffdffff o:00d8 /memory/device/ram/sysram 0228) 0000000100000000-0000000239fc2fff o:00f0 /memory/ram/sysram - Check how much memory is
free:
/ # ls -ld /proc dr-xr-xr-x 2 root root 8478986240 2026-05-11 14:38 proc / #In this example, 8478986240 bytes are free (i.e., just under 8 GB).
- Add the following -R option to the startup command line to set aside a
4G contiguous region of system RAM that has a physical start address that is
16MB aligned. Create an asinfo entry for it named
extra_ram:-R 4G,16M,extra_ram - Reboot your system and show the contents of the asinfo
section again:
/ # pidin syspage=asinfo Header size=0x000000f0, Total Size=0x00000998, Version=2.0, #Cpu=2, Type=4352 Section:asinfo offset:0x000005c0 size:0x00000258 elsize:0x00000018 0000) 0000000000000000-000000000000ffff o:ffff /io 0018) 0000000000000000-000fffffffffffff o:ffff /memory 0030) 0000000000000000-00000000ffffffff o:0018 /memory/below4G 0048) 0000000000000000-0000000000ffffff o:0018 /memory/isa 0060) 0000000006000000-00000000ffefffff o:0018 /memory/device 0078) 00000000fff00000-00000000ffffffff o:0018 /memory/rom 0090) 0000000000000000-000000000009fbff o:0048 /memory/isa/ram 00a8) 0000000000100000-0000000000ffffff o:0048 /memory/isa/ram 00c0) 0000000001000000-0000000005ffffff o:0030 /memory/below4G/ram 00d8) 0000000006000000-00000000bffdffff o:0060 /memory/device/ram 00f0) 0000000100000000-000000023fffffff o:0018 /memory/ram 0108) 00000000000f5a60-00000000000f5a73 o:0018 /memory/acpi_rsdp 0120) 00000000fee00000-00000000fee003ef o:0018 /memory/lapic 0138) 0000000000835348-0000000000e2e043 o:0018 /memory/imagefs 0150) 0000000000800200-0000000000835347 o:0018 /memory/startup 0168) 0000000000835348-0000000000e2e043 o:0018 /memory/bootram 0180) 0000000140000000-000000023fffffff o:00f0 /memory/ram/extra_ram 0198) 0000000000001000-000000000009efff o:0090 /memory/isa/ram/sysram 01b0) 0000000000100000-000000000010ffff o:00a8 /memory/isa/ram/sysram 01c8) 0000000000117000-0000000000117fff o:00a8 /memory/isa/ram/sysram 01e0) 000000000011f000-0000000000834fff o:00a8 /memory/isa/ram/sysram 01f8) 0000000000e2f000-0000000000ffffff o:00a8 /memory/isa/ram/sysram 0210) 0000000001000000-0000000005ffffff o:00c0 /memory/below4G/ram/sysram 0228) 0000000006000000-00000000b9fa2fff o:00d8 /memory/device/ram/sysram 0240) 0000000100000000-000000013fffffff o:00f0 /memory/ram/sysramNote the asinfo at offset
(0x0000'0002'3fff'ffff - 0x0000'0001'4000'0000 + 1) / 1024 / 1024 / 1024 = 4 GB0x0180with the nameextra_ram. The range starts at physical address0x0000'0001'4000'0000, which is a multiple of 16MB (i.e.,0x0100'0000), and ends at0x0000'0002'3fff'ffff. Therefore, the range is 4 GB, where:Notice that there's less system RAM available:/ # ls -ld /proc dr-xr-xr-x 2 root root 4184031232 2026-05-11 14:40 proc / # - Run your program that adds
extra_ramas deferred system RAM. For this example, the program is namedadd_deferred_sysram, and it exits with 0 only on success:/ # add_deferred_sysram / # echo $? 0 / #Notice that after running your program, more system RAM is available:/ # ls -ld /proc dr-xr-xr-x 2 root root 8478998528 2026-05-11 14:41 proc / #
