The latest development version of this page may be more current than this released 1.14.1 version.

Memory Domain

The memory domain APIs are used by unprivileged threads to share data to the threads in the same memory domain and protect sensitive data from threads outside their domain. Memory domains are not only used for improving security, but are also useful for debugging (unexpected access would cause an exception).

Since architectures generally have constraints on how many partitions can be defined, and the size/alignment of each partition, users may need to group related data together using linker sections.

Concepts

A memory domain contains some number of memory partitions. A memory partition is a memory region (might be RAM, peripheral registers, or flash, for example) with specific attributes (access permission, e.g. privileged read/write, unprivileged read-only, or execute never). Memory partitions are defined by a set of underlying MPU regions or MMU tables. A thread belongs to a single memory domain at any point in time but a memory domain may contain multiple threads. Threads in the same memory domain have the same access permissions to the memory partitions belonging to the memory domain. New threads will inherit any memory domain configuration from the parent thread.

Implementation

Create a Memory Domain

A memory domain is defined using a variable of type struct k_mem_domain. It must then be initialized by calling k_mem_domain_init().

The following code defines and initializes an empty memory domain.

struct k_mem_domain app0_domain;

k_mem_domain_init(&app0_domain, 0, NULL);

Add Memory Partitions into a Memory Domain

There are two ways to add memory partitions into a memory domain.

This first code sample shows how to add memory partitions while creating a memory domain.

/* the start address of the MPU region needs to align with its size */
u8_t __aligned(32) app0_buf[32];
u8_t __aligned(32) app1_buf[32];

K_MEM_PARTITION_DEFINE(app0_part0, app0_buf, sizeof(app0_buf),
                       K_MEM_PARTITION_P_RW_U_RW);

K_MEM_PARTITION_DEFINE(app0_part1, app1_buf, sizeof(app1_buf),
                       K_MEM_PARTITION_P_RW_U_RO);

struct k_mem_partition *app0_parts[] = {
    app0_part0,
    app0_part1
};

k_mem_domain_init(&app0_domain, ARRAY_SIZE(app0_parts), app0_parts);

This second code sample shows how to add memory partitions into an initialized memory domain one by one.

/* the start address of the MPU region needs to align with its size */
u8_t __aligned(32) app0_buf[32];
u8_t __aligned(32) app1_buf[32];

K_MEM_PARTITION_DEFINE(app0_part0, app0_buf, sizeof(app0_buf),
                       K_MEM_PARTITION_P_RW_U_RW);

K_MEM_PARTITION_DEFINE(app0_part1, app1_buf, sizeof(app1_buf),
                       K_MEM_PARTITION_P_RW_U_RO);

k_mem_domain_add_partition(&app0_domain, &app0_part0);
k_mem_domain_add_partition(&app0_domain, &app0_part1);

Note

The maximum number of memory partitions is limited by the maximum number of MPU regions or the maximum number of MMU tables.

Add Threads into a Memory Domain

Adding threads into a memory domain grants threads permission to access the memory partitions in the memory domain.

The following code shows how to add threads into a memory domain.

k_mem_domain_add_thread(&app0_domain, app_thread_id);

Remove a Memory Partition from a Memory Domain

The following code shows how to remove a memory partition from a memory domain.

k_mem_domain_remove_partition(&app0_domain, &app0_part1);

The k_mem_domain_remove_partition() API finds the memory partition that matches the given parameter and removes that partition from the memory domain.

Remove a Thread from the Memory Domain

The following code shows how to remove a thread from the memory domain.

k_mem_domain_remove_thread(app_thread_id);

Destroy a Memory Domain

The following code shows how to destroy a memory domain.

k_mem_domain_destroy(&app0_domain);

Available Partition Attributes

When defining a partition, we need to set access permission attributes to the partition. Since the access control of memory partitions relies on either an MPU or MMU, the available partition attributes would be architecture dependent.

The complete list of available partition attributes for a specific architecture is found in the architecture-specific include file include/arch/<arch name>/arch.h, (for example, include/arch/arm/arch.h.) Some examples of partition attributes are:

/* Denote partition is privileged read/write, unprivileged read/write */
K_MEM_PARTITION_P_RW_U_RW
/* Denote partition is privileged read/write, unprivileged read-only */
K_MEM_PARTITION_P_RW_U_RO

Configuration Options

Related configuration options:

API Reference

The following memory domain APIs are provided by include/kernel.h:

group mem_domain_apis

Defines

K_MEM_PARTITION_DEFINE(name, start, size, attr)

Used to declare a memory partition.

Functions

void k_mem_domain_init(struct k_mem_domain *domain, u8_t num_parts, struct k_mem_partition *parts[])

Initialize a memory domain.

Initialize a memory domain with given name and memory partitions.

Parameters
  • domain: The memory domain to be initialized.
  • num_parts: The number of array items of “parts” parameter.
  • parts: An array of pointers to the memory partitions. Can be NULL if num_parts is zero.

void k_mem_domain_destroy(struct k_mem_domain *domain)

Destroy a memory domain.

Destroy a memory domain.

Parameters
  • domain: The memory domain to be destroyed.

void k_mem_domain_add_partition(struct k_mem_domain *domain, struct k_mem_partition *part)

Add a memory partition into a memory domain.

Add a memory partition into a memory domain.

Parameters
  • domain: The memory domain to be added a memory partition.
  • part: The memory partition to be added

void k_mem_domain_remove_partition(struct k_mem_domain *domain, struct k_mem_partition *part)

Remove a memory partition from a memory domain.

Remove a memory partition from a memory domain.

Parameters
  • domain: The memory domain to be removed a memory partition.
  • part: The memory partition to be removed

void k_mem_domain_add_thread(struct k_mem_domain *domain, k_tid_t thread)

Add a thread into a memory domain.

Add a thread into a memory domain.

Parameters
  • domain: The memory domain that the thread is going to be added into.
  • thread: ID of thread going to be added into the memory domain.

void k_mem_domain_remove_thread(k_tid_t thread)

Remove a thread from its memory domain.

Remove a thread from its memory domain.

Parameters
  • thread: ID of thread going to be removed from its memory domain.