From adac9231a9d3f5fb4de51a46263e0b1d62055430 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Tue, 11 Nov 2025 08:00:21 +0800 Subject: [PATCH 1/2] kernel: Add Kconfig option to disable LTO for kernel sources Some SoCs require kernel code to be placed in RAM, which makes link-time optimization (LTO) unsuitable for these files. Disabling LTO allows the affected code to be linked as separate objects and placed in specific memory regions. Running kernel code from RAM can improve execution performance, especially for timing-critical routines or context switch paths. Signed-off-by: Tim Lin --- kernel/CMakeLists.txt | 5 +++++ kernel/Kconfig | 22 ++++++++++++++++++++ kernel/kernel_no_lto.cmake | 42 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 kernel/kernel_no_lto.cmake diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 8906da2f62725..b9e0574ba3694 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -195,6 +195,11 @@ target_link_libraries(kernel zephyr_interface) endif() +# Optionally build kernel sources without LTO +if(CONFIG_KERNEL_NO_LTO) + include(${CMAKE_CURRENT_LIST_DIR}/kernel_no_lto.cmake) +endif() + add_dependencies(kernel zephyr_generated_headers) unset(libkernel) diff --git a/kernel/Kconfig b/kernel/Kconfig index 9e3be0b12abe4..09b3233fbb295 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1138,6 +1138,28 @@ endif # BOOTARGS endmenu +config KERNEL_NO_LTO + bool "Build selected kernel core files without LTO" + depends on LTO + help + Some SoCs require kernel code to be placed in RAM, which makes link-time + optimization (LTO) unsuitable for these files (-fno-lto). Disabling LTO + allows the affected code to be linked as separate objects and placed in + specific memory regions. + + Running kernel code from RAM can improve execution performance, especially + for timing-critical routines or context switch paths. + +if KERNEL_NO_LTO +config KERNEL_LTO_ALLOWLIST + string "List of kernel source files to keep LTO" + help + List of kernel source filenames that should retain LTO even when + CONFIG_KERNEL_NO_LTO is enabled. + Example: CONFIG_KERNEL_LTO_ALLOWLIST="init.c errno.c fatal.c" + +endif # KERNEL_NO_LTO + rsource "Kconfig.device" rsource "Kconfig.vm" rsource "Kconfig.init" diff --git a/kernel/kernel_no_lto.cmake b/kernel/kernel_no_lto.cmake new file mode 100644 index 0000000000000..6a0a7346203f9 --- /dev/null +++ b/kernel/kernel_no_lto.cmake @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Optional script to disable LTO for kernel files + +message(STATUS "[no-LTO] Building kernel files without LTO") + +# Retrieve all source files from the kernel library target +if(TARGET kernel) + get_property(KERNEL_SRCS TARGET kernel PROPERTY SOURCES) +else() + message(WARNING "[no-LTO] kernel target not found, skipping") + return() +endif() + +# Split allowlist string into list +if(DEFINED CONFIG_KERNEL_LTO_ALLOWLIST) + separate_arguments(LTO_ALLOWLIST NATIVE_COMMAND "${CONFIG_KERNEL_LTO_ALLOWLIST}") +endif() + +# Apply -fno-lto to all C source files, except for some initialization files +# (e.g. init.c, errno.c, fatal.c) and those that are less critical to be +# placed in RAM. These files can be excluded from -fno-lto by using +# CONFIG_KERNEL_LTO_ALLOWLIST. +foreach(src ${KERNEL_SRCS}) + if(src MATCHES "\\.c$") + + # Skip if filename matches any in allowlist + set(skip FALSE) + foreach(allow ${LTO_ALLOWLIST}) + get_filename_component(basename ${src} NAME) + if("${basename}" STREQUAL "${allow}") + set(skip TRUE) + break() + endif() + endforeach() + + if(NOT skip) + set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS "-fno-lto -g") + endif() + + endif() +endforeach() From 7171255d3135edc544438094d95ff99538a8f2d9 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Tue, 11 Nov 2025 08:51:52 +0800 Subject: [PATCH 2/2] soc: it8xxx2: Select KERNEL_NO_LTO only when LTO is enabled Select KERNEL_NO_LTO only when LTO is enabled. This ensures proper handling when kernel code is placed in RAM. Signed-off-by: Tim Lin --- soc/ite/ec/it8xxx2/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/ite/ec/it8xxx2/Kconfig b/soc/ite/ec/it8xxx2/Kconfig index 5531371682b57..a520104126ff9 100644 --- a/soc/ite/ec/it8xxx2/Kconfig +++ b/soc/ite/ec/it8xxx2/Kconfig @@ -228,6 +228,7 @@ config SOC_IT8XXX2_KERNEL_IN_RAM bool "Place kernel handling code in RAM" select SOC_IT8XXX2_USE_ILM select SOC_IT8XXX2_LIBRARY_TO_RAM + select KERNEL_NO_LTO if LTO help Place kernel handling code in ILM. This can significantly improve performance.