# Kconfig - kernel configuration options # # Copyright (c) 2014-2015 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # menu "General Kernel Options" module = KERNEL module-str = kernel source "subsys/logging/Kconfig.template.log_config" config MULTITHREADING bool "Multi-threading" default y help If disabled, only the main thread is available, so a main() function must be provided. Interrupts are available. Kernel objects will most probably not behave as expected, especially with regards to pending, since the main thread cannot pend, it being the only thread in the system. Many drivers and subsystems will not work with this option; use only when you REALLY know what you are doing. config NUM_COOP_PRIORITIES int "Number of coop priorities" if MULTITHREADING default 1 if !MULTITHREADING default 16 range 0 128 help Number of cooperative priorities configured in the system. Gives access to priorities: K_PRIO_COOP(0) to K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1) or seen another way, priorities: -CONFIG_NUM_COOP_PRIORITIES to -1 This can be set to zero to disable cooperative scheduling. Cooperative threads always preempt preemptible threads. Each priority requires an extra 8 bytes of RAM. Each set of 32 extra total priorities require an extra 4 bytes and add one possible iteration to loops that search for the next thread to run. The total number of priorities is NUM_COOP_PRIORITIES + NUM_PREEMPT_PRIORITIES + 1 The extra one is for the idle thread, which must run at the lowest priority, and be the only thread at that priority. config NUM_PREEMPT_PRIORITIES int "Number of preemptible priorities" if MULTITHREADING default 0 if !MULTITHREADING default 15 range 0 128 help Number of preemptible priorities available in the system. Gives access to priorities 0 to CONFIG_NUM_PREEMPT_PRIORITIES - 1. This can be set to 0 to disable preemptible scheduling. Each priority requires an extra 8 bytes of RAM. Each set of 32 extra total priorities require an extra 4 bytes and add one possible iteration to loops that search for the next thread to run. The total number of priorities is NUM_COOP_PRIORITIES + NUM_PREEMPT_PRIORITIES + 1 The extra one is for the idle thread, which must run at the lowest priority, and be the only thread at that priority. config MAIN_THREAD_PRIORITY int "Priority of initialization/main thread" default -2 if !PREEMPT_ENABLED default 0 help Priority at which the initialization thread runs, including the start of the main() function. main() can then change its priority if desired. config COOP_ENABLED def_bool (NUM_COOP_PRIORITIES != 0) config PREEMPT_ENABLED def_bool (NUM_PREEMPT_PRIORITIES != 0) config PRIORITY_CEILING int "Priority inheritance ceiling" default 0 config NUM_METAIRQ_PRIORITIES int "Number of very-high priority 'preemptor' threads" default 0 help This defines a set of priorities at the (numerically) lowest end of the range which have "meta-irq" behavior. Runnable threads at these priorities will always be scheduled before threads at lower priorities, EVEN IF those threads are otherwise cooperative and/or have taken a scheduler lock. Making such a thread runnable in any way thus has the effect of "interrupting" the current task and running the meta-irq thread synchronously, like an exception or system call. The intent is to use these priorities to implement "interrupt bottom half" or "tasklet" behavior, allowing driver subsystems to return from interrupt context but be guaranteed that user code will not be executed (on the current CPU) until the remaining work is finished. As this breaks the "promise" of non-preemptibility granted by the current API for cooperative threads, this tool probably shouldn't be used from application code. config SCHED_DEADLINE bool "Enable earliest-deadline-first scheduling" help This enables a simple "earliest deadline first" scheduling mode where threads can set "deadline" deltas measured in k_cycle_get_32() units. Priority decisions within (!!) a single priority will choose the next expiring deadline and not simply the least recently added thread. config SCHED_CPU_MASK bool "Enable CPU mask affinity/pinning API" depends on SCHED_DUMB help When true, the app will have access to the z_thread_*_cpu_mask() APIs which control per-CPU affinity masks in SMP mode, allowing apps to pin threads to specific CPUs or disallow threads from running on given CPUs. Note that as currently implemented, this involves an inherent O(N) scaling in the number of idle-but-runnable threads, and thus works only with the DUMB scheduler (as SCALABLE and MULTIQ would see no benefit). Note that this setting does not technically depend on SMP and is implemented without it for testing purposes, but for obvious reasons makes sense as an application API only where there is more than one CPU. With one CPU, it's just a higher overhead version of k_thread_start/stop(). config MAIN_STACK_SIZE int "Size of stack for initialization and main thread" default 2048 if COVERAGE_GCOV default 512 if ZTEST default 1024 help When the initialization is complete, the thread executing it then executes the main() routine, so as to reuse the stack used by the initialization, which would be wasted RAM otherwise. After initialization is complete, the thread runs main(). config IDLE_STACK_SIZE int "Size of stack for idle thread" default 512 if COVERAGE_GCOV default 1024 if XTENSA default 512 if RISCV32 default 320 if ARC || (ARM && CPU_HAS_FPU) default 256 help Depending on the work that the idle task must do, most likely due to power management but possibly to other features like system event logging (e.g. logging when the system goes to sleep), the idle thread may need more stack space than the default value. config ISR_STACK_SIZE int "ISR and initialization stack size (in bytes)" default 2048 help This option specifies the size of the stack used by interrupt service routines (ISRs), and during kernel initialization. config THREAD_STACK_INFO bool "Thread stack info" help This option allows each thread to store the thread stack info into the k_thread data structure. config THREAD_CUSTOM_DATA bool "Thread custom data" help This option allows each thread to store 32 bits of custom data, which can be accessed using the k_thread_custom_data_xxx() APIs. config THREAD_USERSPACE_LOCAL_DATA bool depends on USERSPACE config THREAD_USERSPACE_LOCAL_DATA_ARCH_DEFER_SETUP bool depends on THREAD_USERSPACE_LOCAL_DATA default y if ARCH="arc" config ERRNO bool "Enable errno support" default y select THREAD_USERSPACE_LOCAL_DATA if USERSPACE help Enable per-thread errno in the kernel. Application and library code must include errno.h provided by the C library (libc) to use the errno symbol. The C library must access the per-thread errno via the _get_errno() symbol. config APPLICATION_MEMORY bool "Split kernel and application memory" help For all read-write memory sections (namely bss, noinit, data), separate them into application and kernel areas. The application area will have the project-level application objects and any libraries including the C library in it. choice SCHED_ALGORITHM prompt "Scheduler priority queue algorithm" default SCHED_DUMB help The kernel can be built with with several choices for the ready queue implementation, offering different choices between code size, constant factor runtime overhead and performance scaling when many threads are added. config SCHED_DUMB bool "Simple linked-list ready queue" help When selected, the scheduler ready queue will be implemented as a simple unordered list, with very fast constant time performance for single threads and very low code size. Choose this on systems with constrained code size that will never see more than a small number (3, maybe) of runnable threads in the queue at any given time. On most platforms (that are not otherwise using the red/black tree) this results in a savings of ~2k of code size. config SCHED_SCALABLE bool "Red/black tree ready queue" help When selected, the scheduler ready queue will be implemented as a red/black tree. This has rather slower constant-time insertion and removal overhead, and on most platforms (that are not otherwise using the rbtree somewhere) requires an extra ~2kb of code. But the resulting behavior will scale cleanly and quickly into the many thousands of threads. Use this on platforms where you may have many threads (very roughly: more than 20 or so) marked as runnable at a given time. Most applications don't want this. config SCHED_MULTIQ bool "Traditional multi-queue ready queue" depends on !SCHED_DEADLINE help When selected, the scheduler ready queue will be implemented as the classic/textbook array of lists, one per priority (max 32 priorities). This corresponds to the scheduler algorithm used in Zephyr versions prior to 1.12. It incurs only a tiny code size overhead vs. the "dumb" scheduler and runs in O(1) time in almost all circumstances with very low constant factor. But it requires a fairly large RAM budget to store those list heads, and the limited features make it incompatible with features like deadline scheduling that need to sort threads more finely, and SMP affinity which need to traverse the list of threads. Typical applications with small numbers of runnable threads probably want the DUMB scheduler. endchoice # SCHED_ALGORITHM choice WAITQ_ALGORITHM prompt "Wait queue priority algorithm" default WAITQ_DUMB help The wait_q abstraction used in IPC primitives to pend threads for later wakeup shares the same backend data structure choices as the scheduler, and can use the same options. config WAITQ_SCALABLE bool "Use scalable wait_q implementation" help When selected, the wait_q will be implemented with a balanced tree. Choose this if you expect to have many threads waiting on individual primitives. There is a ~2kb code size increase over WAITQ_DUMB (which may be shared with SCHED_SCALABLE) if the rbtree is not used elsewhere in the application, and pend/unpend operations on "small" queues will be somewhat slower (though this is not generally a performance path). config WAITQ_DUMB bool "Simple linked-list wait_q" help When selected, the wait_q will be implemented with a doubly-linked list. Choose this if you expect to have only a few threads blocked on any single IPC primitive. endchoice # WAITQ_ALGORITHM menu "Kernel Debugging and Metrics" config INIT_STACKS bool "Initialize stack areas" help This option instructs the kernel to initialize stack areas with a known value (0xaa) before they are first used, so that the high water mark can be easily determined. This applies to the stack areas for threads, as well as to the interrupt stack. config KERNEL_DEBUG bool "Kernel debugging" select INIT_STACKS help Enable kernel debugging. Note that debugging the kernel internals can be very verbose. config BOOT_BANNER bool "Boot banner" default y depends on CONSOLE_HAS_DRIVER select PRINTK select EARLY_CONSOLE help This option outputs a banner to the console device during boot up. config BOOT_DELAY int "Boot delay in milliseconds" default 0 help This option delays bootup for the specified amount of milliseconds. This is used to allow serial ports to get ready before starting to print information on them during boot, as some systems might boot to fast for a receiving endpoint to detect the new USB serial bus, enumerate it and get ready to receive before it actually gets data. A similar effect can be achieved by waiting for DCD on the serial port--however, not all serial ports have DCD. config INT_LATENCY_BENCHMARK bool "Interrupt latency metrics [EXPERIMENTAL]" depends on ARCH="x86" help This option enables the tracking of interrupt latency metrics; the exact set of metrics being tracked is board-dependent. Tracking begins when int_latency_init() is invoked by an application. The metrics are displayed (and a new sampling interval is started) each time int_latency_show() is called thereafter. config EXECUTION_BENCHMARKING bool "Timing metrics" help This option enables the tracking of various times inside the kernel the exact set of metrics being tracked is board-dependent. All timing measurements are enabled for X86 and ARM based architectures. In other architectures only a subset are enabled. config THREAD_MONITOR bool "Thread monitoring [EXPERIMENTAL]" help This option instructs the kernel to maintain a list of all threads (excluding those that have not yet started or have already terminated). config THREAD_NAME bool "Thread name [EXPERIMENTAL]" help This option allows to set a name for a thread. endmenu menu "Work Queue Options" config SYSTEM_WORKQUEUE_STACK_SIZE int "System workqueue stack size" default 1024 config SYSTEM_WORKQUEUE_PRIORITY int "System workqueue priority" default -2 if COOP_ENABLED && !PREEMPT_ENABLED default 0 if !COOP_ENABLED default -1 help By default, system work queue priority is the lowest cooperative priority. This means that any work handler, once started, won't be preempted by any other thread until finished. config OFFLOAD_WORKQUEUE_STACK_SIZE int "Workqueue stack size for thread offload requests" default 1024 config OFFLOAD_WORKQUEUE_PRIORITY int "Offload requests workqueue priority" default -1 endmenu menu "Atomic Operations" config ATOMIC_OPERATIONS_BUILTIN bool help Use the compiler builtin functions for atomic operations. This is the preferred method. However, support for all arches in GCC is incomplete. config ATOMIC_OPERATIONS_CUSTOM bool help Use when there isn't support for compiler built-ins, but you have written optimized assembly code under arch/ which implements these. config ATOMIC_OPERATIONS_C bool help Use atomic operations routines that are implemented entirely in C by locking interrupts. Selected by architectures which either do not have support for atomic operations in their instruction set, or haven't been implemented yet during bring-up, and also the compiler does not have support for the atomic __sync_* builtins. endmenu menu "Timer API Options" config TIMESLICING bool "Thread time slicing" default y depends on SYS_CLOCK_EXISTS && (NUM_PREEMPT_PRIORITIES != 0) help This option enables time slicing between preemptible threads of equal priority. config TIMESLICE_SIZE int "Time slice size (in ms)" default 0 range 0 2147483647 depends on TIMESLICING help This option specifies the maximum amount of time a thread can execute before other threads of equal priority are given an opportunity to run. A time slice size of zero means "no limit" (i.e. an infinitely large time slice). config TIMESLICE_PRIORITY int "Time slicing thread priority ceiling" default 0 range 0 NUM_PREEMPT_PRIORITIES depends on TIMESLICING help This option specifies the thread priority level at which time slicing takes effect; threads having a higher priority than this ceiling are not subject to time slicing. config POLL bool "Async I/O Framework" help Asynchronous notification framework. Enable the k_poll() and k_poll_signal_raise() APIs. The former can wait on multiple events concurrently, which can be either directly triggered or triggered by the availability of some kernel objects (semaphores and fifos). endmenu menu "Other Kernel Object Options" config NUM_MBOX_ASYNC_MSGS int "Maximum number of in-flight asynchronous mailbox messages" default 10 help This option specifies the total number of asynchronous mailbox messages that can exist simultaneously, across all mailboxes in the system. Setting this option to 0 disables support for asynchronous mailbox messages. config NUM_PIPE_ASYNC_MSGS int "Maximum number of in-flight asynchronous pipe messages" default 10 help This option specifies the total number of asynchronous pipe messages that can exist simultaneously, across all pipes in the system. Setting this option to 0 disables support for asynchronous pipe messages. config HEAP_MEM_POOL_SIZE int "Heap memory pool size (in bytes)" default 0 if !POSIX_MQUEUE default 1024 if POSIX_MQUEUE help This option specifies the size of the heap memory pool used when dynamically allocating memory using k_malloc(). Supported values are: 256, 1024, 4096, and 16384. A size of zero means that no heap memory pool is defined. endmenu config ARCH_HAS_CUSTOM_SWAP_TO_MAIN bool # hidden help It's possible that an architecture port cannot use _Swap() to swap to the _main() thread, but instead must do something custom. It must enable this option in that case. config SWAP_NONATOMIC bool help On some architectures, the _Swap() primitive cannot be made atomic with respect to the irq_lock being released. That is, interrupts may be received between the entry to _Swap and the completion of the context switch. There are a handful of workaround cases in the kernel that need to be enabled when this is true. Currently, this only happens on ARM when the PendSV exception priority sits below that of Zephyr-handled interrupts. config ARCH_HAS_CUSTOM_BUSY_WAIT bool # hidden help It's possible that an architecture port cannot or does not want to use the provided k_busy_wait(), but instead must do something custom. It must enable this option in that case. config SYS_CLOCK_TICKS_PER_SEC int "System tick frequency (in ticks/second)" default 100 help This option specifies the frequency of the system clock in Hz. Depending on the choice made, an amount of possibly expensive math must occur when converting ticks to milliseconds and vice-versa. Some values are optimized, and yield significantly less math. The optimal values from a computational point-of-view are 1000, 500, 250 and 125, since in these cases there is either no computation required, or it is all done via bit-shifting. These also give a granularity from 1ms to 8ms. Other good values are 100, 50, 25, 20 and 10. In this case, some math is required but is minimized. These are also values that necessitate a reduced number of clock interrupts per second, at the cost of granularity (10ms to 100ms). All other values require some extensive 64-bit math, and in some configurations even require calls to compiler built-in functions, and can require a non-trivial extra amount of stack space (e.g. around 80 bytes on x86). Note that when available and enabled, in "tickless" mode this config variable specifies the minimum available timing granularity, not necessarily the number or frequency of interrupts delivered to the kernel. config SYS_CLOCK_HW_CYCLES_PER_SEC int "System clock's h/w timer frequency" help This option specifies the frequency of the hardware timer used for the system clock (in Hz). This option is set by the SOC's or board's Kconfig file and the user should generally avoid modifying it via the menu configuration. config SYS_CLOCK_EXISTS def_bool (SYS_CLOCK_TICKS_PER_SEC != 0) # omit prompt to signify a "hidden" option help This option specifies that the kernel lacks timer support. config XIP bool "Execute in place" help This option allows the kernel to operate with its text and read-only sections residing in ROM (or similar read-only memory). Not all boards support this option so it must be used with care; you must also supply a linker command file when building your image. Enabling this option increases both the code and data footprint of the image. menu "Initialization Priorities" config KERNEL_INIT_PRIORITY_OBJECTS int "Kernel objects initialization priority" default 30 help Kernel objects use this priority for initialization. This priority needs to be higher than minimal default initialization priority. config KERNEL_INIT_PRIORITY_DEFAULT int "Default init priority" default 40 help Default minimal init priority for each init level. config KERNEL_INIT_PRIORITY_DEVICE int "Default init priority for device drivers" default 50 help Device driver, that depends on common components, such as interrupt controller, but does not depend on other devices, uses this init priority. config APPLICATION_INIT_PRIORITY int "Default init priority for application level drivers" default 90 help This priority level is for end-user drivers such as sensors and display which have no inward dependencies. endmenu menu "Security Options" config RETPOLINE bool "Build with retpolines enabled" default y if !X86_NO_SPECTRE_V2 # Currently only implemented for x86 depends on X86 help This is recommended on platforms with speculative executions, to protect against branch target injection (AKA Spectre-V2). Full description of how retpolines work can be found here[1]. [1] https://support.google.com/faqs/answer/7625886 config STACK_CANARIES bool "Compiler stack canaries" help This option enables compiler stack canaries. If stack canaries are supported by the compiler, it will emit extra code that inserts a canary value into the stack frame when a function is entered and validates this value upon exit. Stack corruption (such as that caused by buffer overflow) results in a fatal error condition for the running entity. Enabling this option can result in a significant increase in footprint and an associated decrease in performance. If stack canaries are not supported by the compiler an error will occur at build time. config EXECUTE_XOR_WRITE bool "Enable W^X for memory partitions" depends on USERSPACE depends on ARCH_HAS_EXECUTABLE_PAGE_BIT default y help When enabled, will enforce that a writable page isn't executable and vice versa. This might not be acceptable in all scenarios, so this option is given for those unafraid of shooting themselves in the foot. If unsure, say Y. config STACK_POINTER_RANDOM int "Initial stack pointer randomization bounds" depends on !STACK_GROWS_UP default 0 help This option performs a limited form of Address Space Layout Randomization by offsetting some random value to a thread's initial stack pointer upon creation. This hinders some types of security attacks by making the location of any given stack frame non-deterministic. This feature can waste up to the specified size in bytes the stack region, which is carved out of the total size of the stack region. A reasonable minimum value would be around 100 bytes if this can be spared. This is currently only implemented for systems whose stack pointers grow towards lower memory addresses. endmenu config MAX_DOMAIN_PARTITIONS int "Maximum number of partitions per memory domain" default 16 range 0 255 depends on USERSPACE help Configure the maximum number of partitions per memory domain. menu "SMP Options" config USE_SWITCH bool "Use new-style _arch_switch instead of __swap" depends on USE_SWITCH_SUPPORTED help The _arch_switch() API is a lower level context switching primitive than the original __swap mechanism. It is required for an SMP-aware scheduler, or if the architecture does not provide __swap. In uniprocess situations where the architecture provides both, _arch_switch incurs more somewhat overhead and may be slower. config USE_SWITCH_SUPPORTED bool help Indicates whether _arch_switch() API is supported by the currently enabled platform. This option should be selected by platforms that implement it. config SMP bool "Enable symmetric multithreading support" depends on USE_SWITCH help When true, kernel will be built with SMP support, allowing more than one CPU to schedule Zephyr tasks at a time. config MP_NUM_CPUS int "Number of CPUs/cores" default 1 help Number of multiprocessing-capable cores available to the multicpu API and SMP features. endmenu config TICKLESS_IDLE # NB: This option is deprecated, see TICKLESS_KERNEL and # https://github.com/zephyrproject-rtos/zephyr/pull/12234 bool "Tickless idle" default y if SYS_POWER_MANAGEMENT || TICKLESS_CAPABLE help This option suppresses periodic system clock interrupts whenever the kernel becomes idle. This permits the system to remain in a power saving state for extended periods without having to wake up to service each tick as it occurs. config TICKLESS_IDLE_THRESH int "Tickless idle threshold" default 3 depends on TICKLESS_IDLE help This option enables clock interrupt suppression when the kernel idles for only a short period of time. It specifies the minimum number of ticks that must occur before the next kernel timer expires in order for suppression to happen. config TICKLESS_KERNEL bool "Tickless kernel" default y if TICKLESS_CAPABLE help This option enables a fully event driven kernel. Periodic system clock interrupt generation would be stopped at all times. source "kernel/Kconfig.power_mgmt" endmenu