kernel: mmu: install demand mappings for the on-demand linker sections
This sets initial unpaged mappings for __ondemand_func code and __ondemand_rodata variables. To achieve this, we have to augment the backing store API. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
parent
cbbd8579b8
commit
1e4fd23e58
4 changed files with 55 additions and 0 deletions
|
@ -262,6 +262,7 @@ config LINKER_USE_PINNED_SECTION
|
||||||
|
|
||||||
config LINKER_USE_ONDEMAND_SECTION
|
config LINKER_USE_ONDEMAND_SECTION
|
||||||
bool "Use Evictable Linker Section"
|
bool "Use Evictable Linker Section"
|
||||||
|
depends on DEMAND_MAPPING
|
||||||
depends on !LINKER_USE_PINNED_SECTION
|
depends on !LINKER_USE_PINNED_SECTION
|
||||||
depends on !ARCH_MAPS_ALL_RAM
|
depends on !ARCH_MAPS_ALL_RAM
|
||||||
help
|
help
|
||||||
|
|
|
@ -179,6 +179,11 @@ which must be implemented:
|
||||||
free a backing store location (the ``location`` token) which can
|
free a backing store location (the ``location`` token) which can
|
||||||
then be used for subsequent page out operation.
|
then be used for subsequent page out operation.
|
||||||
|
|
||||||
|
* :c:func:`k_mem_paging_backing_store_location_query()` is called to obtain
|
||||||
|
the ``location`` token corresponding to storage content to be virtually
|
||||||
|
mapped and paged-in on demand. Most useful with
|
||||||
|
:kconfig:option:`CONFIG_DEMAND_MAPPING`.
|
||||||
|
|
||||||
* :c:func:`k_mem_paging_backing_store_page_in()` copies a data page
|
* :c:func:`k_mem_paging_backing_store_page_in()` copies a data page
|
||||||
from the backing store location associated with the provided
|
from the backing store location associated with the provided
|
||||||
``location`` token to the page pointed by ``K_MEM_SCRATCH_PAGE``.
|
``location`` token to the page pointed by ``K_MEM_SCRATCH_PAGE``.
|
||||||
|
|
|
@ -349,6 +349,22 @@ int k_mem_paging_backing_store_location_get(struct k_mem_page_frame *pf,
|
||||||
*/
|
*/
|
||||||
void k_mem_paging_backing_store_location_free(uintptr_t location);
|
void k_mem_paging_backing_store_location_free(uintptr_t location);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain persistent location token for on-demand content
|
||||||
|
*
|
||||||
|
* Unlike k_mem_paging_backing_store_location_get() this does not allocate
|
||||||
|
* any backing store space. Instead, it returns a location token corresponding
|
||||||
|
* to some fixed storage content to be paged in on demand. This is expected
|
||||||
|
* to be used in conjonction with CONFIG_LINKER_USE_ONDEMAND_SECTION and the
|
||||||
|
* K_MEM_MAP_UNPAGED flag to create demand mappings at boot time. This may
|
||||||
|
* also be used e.g. to implement file-based mmap().
|
||||||
|
*
|
||||||
|
* @param addr Virtual address to obtain a location token for
|
||||||
|
* @param [out] location storage location token
|
||||||
|
* @return 0 for success or negative error code
|
||||||
|
*/
|
||||||
|
int k_mem_paging_backing_store_location_query(void *addr, uintptr_t *location);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy a data page from K_MEM_SCRATCH_PAGE to the specified location
|
* Copy a data page from K_MEM_SCRATCH_PAGE to the specified location
|
||||||
*
|
*
|
||||||
|
|
33
kernel/mmu.c
33
kernel/mmu.c
|
@ -1050,6 +1050,34 @@ static void mark_linker_section_pinned(void *start_addr, void *end_addr,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_LINKER_USE_BOOT_SECTION) || CONFIG_LINKER_USE_PINNED_SECTION */
|
#endif /* CONFIG_LINKER_USE_BOOT_SECTION) || CONFIG_LINKER_USE_PINNED_SECTION */
|
||||||
|
|
||||||
|
#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
|
||||||
|
static void z_paging_ondemand_section_map(void)
|
||||||
|
{
|
||||||
|
uint8_t *addr;
|
||||||
|
size_t size;
|
||||||
|
uintptr_t location;
|
||||||
|
uint32_t flags;
|
||||||
|
|
||||||
|
size = (uintptr_t)lnkr_ondemand_text_size;
|
||||||
|
flags = K_MEM_MAP_UNPAGED | K_MEM_PERM_EXEC | K_MEM_CACHE_WB;
|
||||||
|
VIRT_FOREACH(lnkr_ondemand_text_start, size, addr) {
|
||||||
|
k_mem_paging_backing_store_location_query(addr, &location);
|
||||||
|
arch_mem_map(addr, location, CONFIG_MMU_PAGE_SIZE, flags);
|
||||||
|
sys_bitarray_set_region(&virt_region_bitmap, 1,
|
||||||
|
virt_to_bitmap_offset(addr, CONFIG_MMU_PAGE_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
size = (uintptr_t)lnkr_ondemand_rodata_size;
|
||||||
|
flags = K_MEM_MAP_UNPAGED | K_MEM_CACHE_WB;
|
||||||
|
VIRT_FOREACH(lnkr_ondemand_rodata_start, size, addr) {
|
||||||
|
k_mem_paging_backing_store_location_query(addr, &location);
|
||||||
|
arch_mem_map(addr, location, CONFIG_MMU_PAGE_SIZE, flags);
|
||||||
|
sys_bitarray_set_region(&virt_region_bitmap, 1,
|
||||||
|
virt_to_bitmap_offset(addr, CONFIG_MMU_PAGE_SIZE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_LINKER_USE_ONDEMAND_SECTION */
|
||||||
|
|
||||||
void z_mem_manage_init(void)
|
void z_mem_manage_init(void)
|
||||||
{
|
{
|
||||||
uintptr_t phys;
|
uintptr_t phys;
|
||||||
|
@ -1126,6 +1154,11 @@ void z_mem_manage_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DEMAND_PAGING */
|
#endif /* CONFIG_DEMAND_PAGING */
|
||||||
|
|
||||||
|
#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
|
||||||
|
z_paging_ondemand_section_map();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if __ASSERT_ON
|
#if __ASSERT_ON
|
||||||
page_frames_initialized = true;
|
page_frames_initialized = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue