| # Copyright (c) 2021 Intel Corporation |
| # |
| # SPDX-License-Identifier: Apache-2.0 |
| |
| menu "Virtual Memory Support" |
| |
| config KERNEL_VM_SUPPORT |
| bool |
| help |
| Hidden option to enable virtual memory Kconfigs. |
| |
| if KERNEL_VM_SUPPORT |
| |
| DT_CHOSEN_Z_SRAM := zephyr,sram |
| |
| config KERNEL_VM_BASE |
| hex "Virtual address space base address" |
| default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_SRAM)) |
| help |
| Define the base of the kernel's address space. |
| |
| By default, this is the same as the DT_CHOSEN_Z_SRAM physical base SRAM |
| address from DTS, in which case RAM will be identity-mapped. Some |
| architectures may require RAM to be mapped in this way; they may have |
| just one RAM region and doing this makes linking much simpler, as |
| at least when the kernel boots all virtual RAM addresses are the same |
| as their physical address (demand paging at runtime may later modify |
| this for non-pinned page frames). |
| |
| Otherwise, if RAM isn't identity-mapped: |
| 1. It is the architecture's responsibility to transition the |
| instruction pointer to virtual addresses at early boot before |
| entering the kernel at z_cstart(). |
| 2. The underlying architecture may impose constraints on the bounds of |
| the kernel's address space, such as not overlapping physical RAM |
| regions if RAM is not identity-mapped, or the virtual and physical |
| base addresses being aligned to some common value (which allows |
| double-linking of paging structures to make the instruction pointer |
| transition simpler). |
| |
| Zephyr does not implement a split address space and if multiple |
| page tables are in use, they all have the same virtual-to-physical |
| mappings (with potentially different permissions). |
| |
| config KERNEL_VM_OFFSET |
| hex "Kernel offset within address space" |
| default 0 |
| help |
| Offset that the kernel image begins within its address space, |
| if this is not the same offset from the beginning of RAM. |
| |
| Some care may need to be taken in selecting this value. In certain |
| build-time cases, or when a physical address cannot be looked up |
| in page tables, the equation: |
| |
| virt = phys + ((KERNEL_VM_BASE + KERNEL_VM_OFFSET) - |
| (SRAM_BASE_ADDRESS + SRAM_OFFSET)) |
| |
| Will be used to convert between physical and virtual addresses for |
| memory that is mapped at boot. |
| |
| This uncommon and is only necessary if the beginning of VM and |
| physical memory have dissimilar alignment. |
| |
| config KERNEL_VM_SIZE |
| hex "Size of kernel address space in bytes" |
| default 0x800000 |
| help |
| Size of the kernel's address space. Constraining this helps control |
| how much total memory can be used for page tables. |
| |
| The difference between KERNEL_VM_BASE and KERNEL_VM_SIZE indicates the |
| size of the virtual region for runtime memory mappings. This is needed |
| for mapping driver MMIO regions, as well as special RAM mapping use-cases |
| such as VSDO pages, memory mapped thread stacks, and anonymous memory |
| mappings. The kernel itself will be mapped in here as well at boot. |
| |
| Systems with very large amounts of memory (such as 512M or more) |
| will want to use a 64-bit build of Zephyr, there are no plans to |
| implement a notion of "high" memory in Zephyr to work around physical |
| RAM size larger than the defined bounds of the virtual address space. |
| |
| config KERNEL_DIRECT_MAP |
| bool "Memory region direct-map support" |
| depends on MMU |
| help |
| This enables the direct-map support, namely the region can be 1:1 |
| mapping between virtual address and physical address. |
| |
| If the specific memory region is in the virtual memory space and |
| there isn't overlap with the existed mappings, it will reserve the |
| region from the virtual memory space and do the mapping, otherwise |
| it will fail. And any attempt across the boundary of the virtual |
| memory space will fail. |
| |
| Note that this is for compatibility and portable apps shouldn't |
| be using it. |
| |
| endif # KERNEL_VM_SUPPORT |
| |
| menuconfig MMU |
| bool "MMU features" |
| depends on CPU_HAS_MMU |
| select KERNEL_VM_SUPPORT |
| help |
| This option is enabled when the CPU's memory management unit is active |
| and the arch_mem_map() API is available. |
| |
| if MMU |
| config MMU_PAGE_SIZE |
| hex "Size of smallest granularity MMU page" |
| default 0x1000 |
| help |
| Size of memory pages. Varies per MMU but 4K is common. For MMUs that |
| support multiple page sizes, put the smallest one here. |
| |
| menuconfig DEMAND_PAGING |
| bool "Demand paging [EXPERIMENTAL]" |
| depends on ARCH_HAS_DEMAND_PAGING |
| help |
| Enable demand paging. Requires architecture support in how the kernel |
| is linked and the implementation of an eviction algorithm and a |
| backing store for evicted pages. |
| |
| if DEMAND_PAGING |
| config DEMAND_MAPPING |
| bool "Allow on-demand memory mappings" |
| depends on ARCH_HAS_DEMAND_MAPPING |
| default y |
| help |
| When this is enabled, RAM-based memory mappings don't actually |
| allocate memory at mem_map time. They are made to be populated |
| at access time using the demand paging mechanism instead. |
| |
| config DEMAND_PAGING_ALLOW_IRQ |
| bool "Allow interrupts during page-ins/outs" |
| help |
| Allow interrupts to be serviced while pages are being evicted or |
| retrieved from the backing store. This is much better for system |
| latency, but any code running in interrupt context that page faults |
| will cause a kernel panic. Such code must work with exclusively pinned |
| code and data pages. |
| |
| The scheduler is still disabled during this operation. |
| |
| If this option is disabled, the page fault servicing logic |
| runs with interrupts disabled for the entire operation. However, |
| ISRs may also page fault. |
| |
| config DEMAND_PAGING_PAGE_FRAMES_RESERVE |
| int "Number of page frames reserved for paging" |
| default 32 if !LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT |
| default 0 |
| help |
| This sets the number of page frames that will be reserved for |
| paging that do not count towards free memory. This is to |
| ensure that there are some page frames available for paging |
| code and data. Otherwise, it would be possible to exhaust |
| all page frames via anonymous memory mappings. |
| |
| config DEMAND_PAGING_STATS |
| bool "Gather Demand Paging Statistics" |
| help |
| This enables gathering various statistics related to demand paging, |
| e.g. number of pagefaults. This is useful for tuning eviction |
| algorithms and optimizing backing store. |
| |
| Should say N in production system as this is not without cost. |
| |
| config DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS |
| bool "Use Timing Functions to Gather Demand Paging Statistics" |
| select TIMING_FUNCTIONS_NEED_AT_BOOT |
| help |
| Use timing functions to gather various demand paging statistics. |
| |
| config DEMAND_PAGING_THREAD_STATS |
| bool "Gather per Thread Demand Paging Statistics" |
| depends on DEMAND_PAGING_STATS |
| help |
| This enables gathering per thread statistics related to demand |
| paging. |
| |
| Should say N in production system as this is not without cost. |
| |
| config DEMAND_PAGING_TIMING_HISTOGRAM |
| bool "Gather Demand Paging Execution Timing Histogram" |
| depends on DEMAND_PAGING_STATS |
| help |
| This gathers the histogram of execution time on page eviction |
| selection, and backing store page in and page out. |
| |
| Should say N in production system as this is not without cost. |
| |
| config DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS |
| int "Number of bins (buckets) in Demand Paging Timing Histogram" |
| depends on DEMAND_PAGING_TIMING_HISTOGRAM |
| default 10 |
| help |
| Defines the number of bins (buckets) in the histogram used for |
| gathering execution timing information for demand paging. |
| |
| This requires k_mem_paging_eviction_histogram_bounds[] and |
| k_mem_paging_backing_store_histogram_bounds[] to define |
| the upper bounds for each bin. See kernel/statistics.c for |
| information. |
| |
| endif # DEMAND_PAGING |
| endif # MMU |
| |
| config KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK |
| bool |
| help |
| Use custom memory range check functions instead of the generic |
| checks in k_mem_phys_addr() and k_mem_virt_addr(). |
| |
| sys_mm_is_phys_addr_in_range() and |
| sys_mm_is_virt_addr_in_range() must be implemented. |
| |
| endmenu # Virtual Memory Support |