Skip to content

Commit 961c15c

Browse files
committed
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 <tim2.lin@ite.corp-partner.google.com>
1 parent feae716 commit 961c15c

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

kernel/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ target_link_libraries(kernel zephyr_interface)
195195

196196
endif()
197197

198+
# Optionally build kernel sources without LTO
199+
if(CONFIG_KERNEL_NO_LTO)
200+
include(${CMAKE_CURRENT_LIST_DIR}/kernel_no_lto.cmake)
201+
endif()
202+
198203
add_dependencies(kernel zephyr_generated_headers)
199204

200205
unset(libkernel)

kernel/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,19 @@ endif # BOOTARGS
11381138

11391139
endmenu
11401140

1141+
config KERNEL_NO_LTO
1142+
bool "Build selected kernel core files without LTO"
1143+
depends on LTO
1144+
depends on XIP
1145+
help
1146+
Some SoCs require kernel code to be placed in RAM, which makes link-time
1147+
optimization (LTO) unsuitable for these files (-fno-lto). Disabling LTO
1148+
allows the affected code to be linked as separate objects and placed in
1149+
specific memory regions.
1150+
1151+
Running kernel code from RAM can improve execution performance, especially
1152+
for timing-critical routines or context switch paths.
1153+
11411154
rsource "Kconfig.device"
11421155
rsource "Kconfig.vm"
11431156
rsource "Kconfig.init"

kernel/kernel_no_lto.cmake

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright (c) 2025 ITE Corporation. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# Optional script to disable LTO for kernel files
5+
6+
message(STATUS "[no-LTO] Building kernel files without LTO")
7+
8+
# Retrieve all source files from the kernel library target
9+
if(TARGET kernel)
10+
get_property(KERNEL_SRCS TARGET kernel PROPERTY SOURCES)
11+
else()
12+
message(WARNING "[no-LTO] kernel target not found, skipping")
13+
return()
14+
endif()
15+
16+
# Check if there is a permitted kernel file that can enable LTO
17+
if(COMMAND kernel_lto_allow_list)
18+
kernel_lto_allow_list(ADDITIONAL_ALLOWLIST)
19+
endif()
20+
21+
# Default LTO allowlist
22+
set(DEFAULT_LTO_ALLOWLIST init.c errno.c fatal.c)
23+
# Append LTO allowlist
24+
list(APPEND DEFAULT_LTO_ALLOWLIST ${ADDITIONAL_ALLOWLIST})
25+
# Setting LTO allowlist
26+
set(LTO_ALLOWLIST ${DEFAULT_LTO_ALLOWLIST})
27+
28+
# Apply -fno-lto to all C source files, except for some initialization files
29+
# (e.g. init.c, errno.c, fatal.c) and those that are less critical to be
30+
# executed in RAM. These files can be excluded from -fno-lto by using
31+
# ADDITIONAL_ALLOWLIST.
32+
foreach(src ${KERNEL_SRCS})
33+
if(src MATCHES "\\.c$")
34+
35+
# Skip if filename matches any in allowlist
36+
set(skip FALSE)
37+
foreach(allow ${LTO_ALLOWLIST})
38+
get_filename_component(basename ${src} NAME)
39+
if("${basename}" STREQUAL "${allow}")
40+
set(skip TRUE)
41+
break()
42+
endif()
43+
endforeach()
44+
45+
if(NOT skip)
46+
set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS "-fno-lto -g")
47+
endif()
48+
49+
endif()
50+
endforeach()

0 commit comments

Comments
 (0)