Zephyr API Documentation  3.7.0
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
Kernel Memory Management Internal APIs

Macros

#define K_MEM_VIRT_OFFSET
 Address offset of permanent virtual mapping from physical address.
 
#define K_MEM_PHYS_ADDR(virt)   ((virt) - K_MEM_VIRT_OFFSET)
 Get physical address from virtual address.
 
#define K_MEM_VIRT_ADDR(phys)   ((phys) + K_MEM_VIRT_OFFSET)
 Get virtual address from physical address.
 

Functions

static uintptr_t k_mem_phys_addr (void *virt)
 Get physical address from virtual address.
 
static void * k_mem_virt_addr (uintptr_t phys)
 Get virtual address from physical address.
 
void k_mem_map_phys_bare (uint8_t **virt_ptr, uintptr_t phys, size_t size, uint32_t flags)
 Map a physical memory region into the kernel's virtual address space.
 
void k_mem_unmap_phys_bare (uint8_t *virt, size_t size)
 Unmap a virtual memory region from kernel's virtual address space.
 
void * k_mem_map_phys_guard (uintptr_t phys, size_t size, uint32_t flags, bool is_anon)
 Map memory into virtual address space with guard pages.
 
void k_mem_unmap_phys_guard (void *addr, size_t size, bool is_anon)
 Un-map memory mapped via k_mem_map_phys_guard().
 

Detailed Description

Macro Definition Documentation

◆ K_MEM_PHYS_ADDR

#define K_MEM_PHYS_ADDR (   virt)    ((virt) - K_MEM_VIRT_OFFSET)

#include <zephyr/kernel/internal/mm.h>

Get physical address from virtual address.

This only works in the kernel's permanent mapping of RAM.

Parameters
virtVirtual address
Returns
Physical address.

◆ K_MEM_VIRT_ADDR

#define K_MEM_VIRT_ADDR (   phys)    ((phys) + K_MEM_VIRT_OFFSET)

#include <zephyr/kernel/internal/mm.h>

Get virtual address from physical address.

This only works in the kernel's permanent mapping of RAM.

Parameters
physPhysical address
Returns
Virtual address.

◆ K_MEM_VIRT_OFFSET

#define K_MEM_VIRT_OFFSET

#include <zephyr/kernel/internal/mm.h>

Value:
((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \
(CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_OFFSET))

Address offset of permanent virtual mapping from physical address.

This is the offset to subtract from a virtual address mapped in the kernel's permanent mapping of RAM, to obtain its physical address.

virt_addr = phys_addr + K_MEM_VIRT_OFFSET

This only works for virtual addresses within the interval [CONFIG_KERNEL_VM_BASE, CONFIG_KERNEL_VM_BASE + (CONFIG_SRAM_SIZE * 1024)).

These macros are intended for assembly, linker code, and static initializers. Use with care.

Note that when demand paging is active, these will only work with page frames that are pinned to their virtual mapping at boot.

TODO: This will likely need to move to an arch API or need additional constraints defined.

Function Documentation

◆ k_mem_map_phys_bare()

void k_mem_map_phys_bare ( uint8_t **  virt_ptr,
uintptr_t  phys,
size_t  size,
uint32_t  flags 
)

#include <zephyr/kernel/internal/mm.h>

Map a physical memory region into the kernel's virtual address space.

This function is intended for mapping memory-mapped I/O regions into the virtual address space. Given a physical address and a size, return a linear address representing the base of where the physical region is mapped in the virtual address space for the Zephyr kernel.

The memory mapped via this function must be unmapped using k_mem_unmap_phys_bare().

This function alters the active page tables in the area reserved for the kernel. This function will choose the virtual address and return it to the caller.

Portable code should never assume that phys_addr and linear_addr will be equal.

Caching and access properties are controlled by the 'flags' parameter. Unused bits in 'flags' are reserved for future expansion. A caching mode must be selected. By default, the region is read-only with user access and code execution forbidden. This policy is changed by passing K_MEM_CACHE_* and K_MEM_PERM_* macros into the 'flags' parameter.

If there is insufficient virtual address space for the mapping this will generate a kernel panic.

This API is only available if CONFIG_MMU is enabled.

It is highly discouraged to use this function to map system RAM page frames. It may conflict with anonymous memory mappings and demand paging and produce undefined behavior. Do not use this for RAM unless you know exactly what you are doing. If you need a chunk of memory, use k_mem_map(). If you need a contiguous buffer of physical memory, statically declare it and pin it at build time, it will be mapped when the system boots.

This API is part of infrastructure still under development and may change.

Parameters
[out]virt_ptrOutput virtual address storage location
[in]physPhysical address base of the memory region
[in]sizeSize of the memory region
[in]flagsCaching mode and access flags, see K_MAP_* macros

◆ k_mem_map_phys_guard()

void * k_mem_map_phys_guard ( uintptr_t  phys,
size_t  size,
uint32_t  flags,
bool  is_anon 
)

#include <zephyr/kernel/internal/mm.h>

Map memory into virtual address space with guard pages.

This maps memory into virtual address space with a preceding and a succeeding guard pages. The memory mapped via this function must be unmapped using k_mem_unmap_phys_guard().

This function maps a contiguous physical memory region into kernel's virtual address space with a preceding and a succeeding guard pages. Given a physical address and a size, return a linear address representing the base of where the physical region is mapped in the virtual address space for the Zephyr kernel.

This function alters the active page tables in the area reserved for the kernel. This function will choose the virtual address and return it to the caller.

If user thread access control needs to be managed in any way, do not enable K_MEM_PERM_USER flags here; instead manage the region's permissions with memory domain APIs after the mapping has been established. Setting K_MEM_PERM_USER here will allow all user threads to access this memory which is usually undesirable.

Unless K_MEM_MAP_UNINIT is used, the returned memory will be zeroed.

The returned virtual memory pointer will be page-aligned. The size parameter, and any base address for re-mapping purposes must be page- aligned.

Note that the allocation includes two guard pages immediately before and after the requested region. The total size of the allocation will be the requested size plus the size of these two guard pages.

Many K_MEM_MAP_* flags have been implemented to alter the behavior of this function, with details in the documentation for these flags.

See also
k_mem_map() for additional information if called via that.
Parameters
physPhysical address base of the memory region if not requesting anonymous memory. Must be page-aligned.
sizeSize of the memory mapping. This must be page-aligned.
flagsK_MEM_PERM_*, K_MEM_MAP_* control flags.
is_anonTrue is requesting mapping with anonymous memory.
Returns
The mapped memory location, or NULL if insufficient virtual address space, insufficient physical memory to establish the mapping, or insufficient memory for paging structures.

◆ k_mem_phys_addr()

static uintptr_t k_mem_phys_addr ( void *  virt)
inlinestatic

#include <zephyr/kernel/internal/mm.h>

Get physical address from virtual address.

This only works in the kernel's permanent mapping of RAM.

Just like K_MEM_PHYS_ADDR() but with type safety and assertions.

Parameters
virtVirtual address
Returns
Physical address.

◆ k_mem_unmap_phys_bare()

void k_mem_unmap_phys_bare ( uint8_t virt,
size_t  size 
)

#include <zephyr/kernel/internal/mm.h>

Unmap a virtual memory region from kernel's virtual address space.

This function is intended to be used by drivers and early boot routines where temporary memory mappings need to be made. This allows these memory mappings to be discarded once they are no longer needed.

This function alters the active page tables in the area reserved for the kernel.

This will align the input parameters to page boundaries so that this can be used with the virtual address as returned by k_mem_map_phys_bare().

This API is only available if CONFIG_MMU is enabled.

It is highly discouraged to use this function to unmap memory mappings. It may conflict with anonymous memory mappings and demand paging and produce undefined behavior. Do not use this unless you know exactly what you are doing.

This API is part of infrastructure still under development and may change.

Parameters
virtStarting address of the virtual address region to be unmapped.
sizeSize of the virtual address region

◆ k_mem_unmap_phys_guard()

void k_mem_unmap_phys_guard ( void *  addr,
size_t  size,
bool  is_anon 
)

#include <zephyr/kernel/internal/mm.h>

Un-map memory mapped via k_mem_map_phys_guard().

This removes the memory mappings for the provided page-aligned region, and the two guard pages surrounding the region.

This function alters the active page tables in the area reserved for the kernel.

See also
k_mem_unmap() for additional information if called via that.
Note
Calling this function on a region which was not mapped via k_mem_map_phys_guard() to begin with is undefined behavior.
Parameters
addrPage-aligned memory region base virtual address
sizePage-aligned memory region size
is_anonTrue if the mapped memory is from anonymous memory.

◆ k_mem_virt_addr()

static void * k_mem_virt_addr ( uintptr_t  phys)
inlinestatic

#include <zephyr/kernel/internal/mm.h>

Get virtual address from physical address.

This only works in the kernel's permanent mapping of RAM.

Just like K_MEM_VIRT_ADDR() but with type safety and assertions.

Parameters
physPhysical address
Returns
Virtual address.