diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 50cce1a41a6..396aad9240e 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -180,6 +180,20 @@ config SRAM_OFFSET If unsure, leave at the default value 0. +menu "Linker Sections" + +config LINKER_USE_BOOT_SECTION + bool "Enable Usage of Boot Linker Section" + help + If enabled, the symbols which are needed for the boot process + will be put into another linker section reserved for these + symbols. + + Requires that boot sections exist in the architecture, SoC, + board or custom linker script. + +endmenu # "Linker Sections" + endmenu menu "Compiler Options" diff --git a/include/linker/linker-defs.h b/include/linker/linker-defs.h index 8a79a7f3983..7c032162ffa 100644 --- a/include/linker/linker-defs.h +++ b/include/linker/linker-defs.h @@ -317,6 +317,30 @@ extern char __tls_end[]; extern char __tls_size[]; #endif /* CONFIG_THREAD_LOCAL_STORAGE */ +#ifdef CONFIG_LINKER_USE_BOOT_SECTION +/* lnkr_boot_start[] and lnkr_boot_end[] + * must encapsulate all the boot sections. + */ +extern char lnkr_boot_start[]; +extern char lnkr_boot_end[]; + +extern char lnkr_boot_text_start[]; +extern char lnkr_boot_text_end[]; +extern char lnkr_boot_text_size[]; +extern char lnkr_boot_data_start[]; +extern char lnkr_boot_data_end[]; +extern char lnkr_boot_data_size[]; +extern char lnkr_boot_rodata_start[]; +extern char lnkr_boot_rodata_end[]; +extern char lnkr_boot_rodata_size[]; +extern char lnkr_boot_bss_start[]; +extern char lnkr_boot_bss_end[]; +extern char lnkr_boot_bss_size[]; +extern char lnkr_boot_noinit_start[]; +extern char lnkr_boot_noinit_end[]; +extern char lnkr_boot_noinit_size[]; +#endif /* CONFIG_LINKER_USE_BOOT_SECTION */ + #endif /* ! _ASMLANGUAGE */ #endif /* ZEPHYR_INCLUDE_LINKER_LINKER_DEFS_H_ */ diff --git a/include/linker/section_tags.h b/include/linker/section_tags.h index 86e383e7a0c..51134117149 100644 --- a/include/linker/section_tags.h +++ b/include/linker/section_tags.h @@ -52,6 +52,20 @@ #define __kstackmem __noinit #endif /* CONFIG_KERNEL_COHERENCE */ +#if defined(CONFIG_LINKER_USE_BOOT_SECTION) +#define __boot_func Z_GENERIC_DOT_SECTION(BOOT_TEXT_SECTION_NAME) +#define __boot_data Z_GENERIC_DOT_SECTION(BOOT_DATA_SECTION_NAME) +#define __boot_rodata Z_GENERIC_DOT_SECTION(BOOT_RODATA_SECTION_NAME) +#define __boot_bss Z_GENERIC_DOT_SECTION(BOOT_BSS_SECTION_NAME) +#define __boot_noinit Z_GENERIC_DOT_SECTION(BOOT_NOINIT_SECTION_NAME) +#else +#define __boot_func +#define __boot_data +#define __boot_rodata +#define __boot_bss +#define __boot_noinit __noinit +#endif /* CONFIG_LINKER_USE_BOOT_SECTION */ + #endif /* !_ASMLANGUAGE */ #endif /* ZEPHYR_INCLUDE_LINKER_SECTION_TAGS_H_ */ diff --git a/include/linker/sections.h b/include/linker/sections.h index 57b81031599..4ec09ce77e1 100644 --- a/include/linker/sections.h +++ b/include/linker/sections.h @@ -67,6 +67,14 @@ #define _NOCACHE_SECTION_NAME nocache #endif +#if defined(CONFIG_LINKER_USE_BOOT_SECTION) +#define BOOT_TEXT_SECTION_NAME boot_text +#define BOOT_BSS_SECTION_NAME boot_bss +#define BOOT_RODATA_SECTION_NAME boot_rodata +#define BOOT_DATA_SECTION_NAME boot_data +#define BOOT_NOINIT_SECTION_NAME boot_noinit +#endif + /* Short section references for use in ASM files */ #if defined(_ASMLANGUAGE) /* Various text section names */ @@ -77,6 +85,21 @@ #define RODATA rodata #define DATA data #define NOINIT noinit + +#if defined(CONFIG_LINKER_USE_BOOT_SECTION) +#define BOOT_TEXT BOOT_TEXT_SECTION_NAME +#define BOOT_BSS BOOT_BSS_SECTION_NAME +#define BOOT_RODATA BOOT_RODATA_SECTION_NAME +#define BOOT_DATA BOOT_DATA_SECTION_NAME +#define BOOT_NOINIT BOOT_NOINIT_SECTION_NAME +#else +#define BOOT_TEXT TEXT +#define BOOT_BSS BSS +#define BOOT_RODATA RODATA +#define BOOT_DATA DATA +#define BOOT_NOINIT NOINIT +#endif /* CONFIG_LINKER_USE_BOOT_SECTION */ + #endif /* _ASMLANGUAGE */ #include diff --git a/kernel/include/kernel_internal.h b/kernel/include/kernel_internal.h index 807d29c7e2b..6e8bbeac170 100644 --- a/kernel/include/kernel_internal.h +++ b/kernel/include/kernel_internal.h @@ -35,6 +35,16 @@ static inline void z_data_copy(void) /* Do nothing */ } #endif + +#ifdef CONFIG_LINKER_USE_BOOT_SECTION +void z_bss_zero_boot(void); +#else +static inline void z_bss_zero_boot(void) +{ + /* Do nothing */ +} +#endif + FUNC_NORETURN void z_cstart(void); void z_device_state_init(void); diff --git a/kernel/init.c b/kernel/init.c index b9ab4deeefc..ce230a8ae96 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -109,6 +109,24 @@ void z_bss_zero(void) #endif } +#ifdef CONFIG_LINKER_USE_BOOT_SECTION +/** + * @brief Clear BSS within the bot region + * + * This routine clears the BSS within the boot region. + * This is separate from z_bss_zero() as boot region may + * contain symbols required for the boot process before + * paging is initialized. + */ +__boot_func +void z_bss_zero_boot(void) +{ + (void)memset(&lnkr_boot_bss_start, 0, + (uintptr_t)&lnkr_boot_bss_end + - (uintptr_t)&lnkr_boot_bss_start); +} +#endif /* CONFIG_LINKER_USE_BOOT_SECTION */ + #ifdef CONFIG_STACK_CANARIES extern volatile uintptr_t __stack_chk_guard; #endif /* CONFIG_STACK_CANARIES */