kernel: generate placeholders for kobj tables before final build
Due to the use of gperf to generate hash table for kobjects, the addresses of these kobjects cannot change during the last few phases of linking (especially between zephyr_prebuilt.elf and zephyr.elf). Because of this, the gperf generated data needs to be placed at the end of memory to avoid pushing symbols around in memory. This prevents moving these generated blocks to earlier sections, for example, pinned data section needed for demand paging. So create placeholders for use in intermediate linking to reserve space for these generated blocks. Due to uncertainty on the size of these blocks, more space is being reserved which could result in wasted space. Though, this retains the use of hash table for faster lookup. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
317dcd908f
commit
1117169980
19 changed files with 488 additions and 97 deletions
|
@ -24,3 +24,5 @@ SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),)
|
|||
#include <snippets-noinit.ld>
|
||||
|
||||
} GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
|
||||
#include "kobject-priv-stacks.ld"
|
||||
|
|
75
include/linker/kobject-data.ld
Normal file
75
include/linker/kobject-data.ld
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2017,2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
|
||||
z_kobject_data_begin = .;
|
||||
SECTION_DATA_PROLOGUE(kobject_data,,)
|
||||
{
|
||||
|
||||
#if !defined(LINKER_ZEPHYR_PREBUILT) && \
|
||||
!defined(LINKER_ZEPHYR_FINAL)
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_OBJECTS
|
||||
PROVIDE(_thread_idx_map = .);
|
||||
. += CONFIG_MAX_THREAD_BYTES;
|
||||
#endif
|
||||
|
||||
#endif /* !LINKER_ZEPHYR_PREBUILT && !LINKER_ZEPHYR_FINAL */
|
||||
|
||||
/* During LINKER_KOBJECT_PREBUILT and LINKER_ZEPHYR_PREBUILT,
|
||||
* space needs to be reserved for the rodata that will be
|
||||
* produced by gperf during the final stages of linking.
|
||||
* The alignment and size are produced by
|
||||
* scripts/gen_kobject_placeholders.py. These are here
|
||||
* so the addresses to kobjects would remain the same
|
||||
* during the final stages of linking (LINKER_ZEPHYR_FINAL).
|
||||
*/
|
||||
|
||||
#if defined(LINKER_ZEPHYR_PREBUILT)
|
||||
#include <linker-kobject-prebuilt-data.h>
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_OBJECTS
|
||||
/* This is produced by gperf. Put a place holder here
|
||||
* to avoid compilation error.
|
||||
*/
|
||||
PROVIDE(_thread_idx_map = .);
|
||||
#endif
|
||||
#ifdef KOBJECT_DATA_ALIGN
|
||||
. = ALIGN(KOBJECT_DATA_ALIGN);
|
||||
. += KOBJECT_DATA_SZ;
|
||||
#endif
|
||||
#endif /* LINKER_ZEPHYR_PREBUILT */
|
||||
|
||||
#if defined(LINKER_ZEPHYR_FINAL)
|
||||
#include <linker-kobject-prebuilt-data.h>
|
||||
#ifdef KOBJECT_DATA_ALIGN
|
||||
. = ALIGN(KOBJECT_DATA_ALIGN);
|
||||
|
||||
_kobject_data_area_start = .;
|
||||
#endif
|
||||
|
||||
*(".kobject_data.data*")
|
||||
|
||||
#ifdef KOBJECT_DATA_ALIGN
|
||||
_kobject_data_area_end = .;
|
||||
_kobject_data_area_used = _kobject_data_area_end - _kobject_data_area_start;
|
||||
|
||||
ASSERT(_kobject_data_area_used <= KOBJECT_DATA_SZ,
|
||||
"scripts/gen_kobject_placeholders.py did not reserve enough space \
|
||||
for kobject data."
|
||||
);
|
||||
|
||||
/* Padding is needed to preserve kobject addresses
|
||||
* if we have reserved more space than needed.
|
||||
*/
|
||||
. = MAX(., _kobject_data_area_start + KOBJECT_DATA_SZ);
|
||||
#endif /* KOBJECT_DATA_ALIGN */
|
||||
#endif /* LINKER_ZEPHYR_FINAL */
|
||||
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
|
||||
#endif /* CONFIG_USERSPACE */
|
58
include/linker/kobject-priv-stacks.ld
Normal file
58
include/linker/kobject-priv-stacks.ld
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2017,2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
#ifdef CONFIG_GEN_PRIV_STACKS
|
||||
SECTION_DATA_PROLOGUE(priv_stacks_noinit,,)
|
||||
{
|
||||
z_priv_stacks_ram_start = .;
|
||||
|
||||
/* During LINKER_KOBJECT_PREBUILT and LINKER_ZEPHYR_PREBUILT,
|
||||
* space needs to be reserved for the rodata that will be
|
||||
* produced by gperf during the final stages of linking.
|
||||
* The alignment and size are produced by
|
||||
* scripts/gen_kobject_placeholders.py. These are here
|
||||
* so the addresses to kobjects would remain the same
|
||||
* during the final stages of linking (LINKER_ZEPHYR_FINAL).
|
||||
*/
|
||||
|
||||
#if defined(LINKER_ZEPHYR_PREBUILT)
|
||||
#include <linker-kobject-prebuilt-priv-stacks.h>
|
||||
#ifdef KOBJECT_PRIV_STACKS_ALIGN
|
||||
. = ALIGN(KOBJECT_PRIV_STACKS_ALIGN);
|
||||
. += KOBJECT_PRIV_STACKS_SZ;
|
||||
#endif
|
||||
#endif /* LINKER_ZEPHYR_PREBUILT */
|
||||
|
||||
#if defined(LINKER_ZEPHYR_FINAL)
|
||||
#include <linker-kobject-prebuilt-priv-stacks.h>
|
||||
#ifdef KOBJECT_PRIV_STACKS_ALIGN
|
||||
. = ALIGN(KOBJECT_PRIV_STACKS_ALIGN);
|
||||
#endif
|
||||
*(".priv_stacks.noinit")
|
||||
#endif /* LINKER_ZEPHYR_FINAL */
|
||||
|
||||
z_priv_stacks_ram_end = .;
|
||||
|
||||
#if defined(LINKER_ZEPHYR_FINAL)
|
||||
#ifdef KOBJECT_PRIV_STACKS_ALIGN
|
||||
z_priv_stacks_ram_used = z_priv_stacks_ram_end - z_priv_stacks_ram_start;
|
||||
|
||||
ASSERT(z_priv_stacks_ram_used <= KOBJECT_PRIV_STACKS_SZ,
|
||||
"scripts/gen_kobject_placeholders.py did not reserve enough space \
|
||||
for priviledged stacks."
|
||||
);
|
||||
|
||||
/* Padding is needed to preserve kobject addresses
|
||||
* if we have reserved more space than needed.
|
||||
*/
|
||||
. = MAX(., z_priv_stacks_ram_start + KOBJECT_PRIV_STACKS_SZ);
|
||||
#endif /* KOBJECT_PRIV_STACKS_ALIGN */
|
||||
#endif /* LINKER_ZEPHYR_FINAL */
|
||||
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
#endif /* CONFIG_GEN_PRIV_STACKS */
|
||||
#endif /* CONFIG_USERSPACE */
|
|
@ -1,13 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
* Copyright (c) 2017,2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
/* Kept in RAM on non-XIP */
|
||||
#ifdef CONFIG_XIP
|
||||
*(".kobject_data.rodata*")
|
||||
#endif
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
/* During LINKER_KOBJECT_PREBUILT and LINKER_ZEPHYR_PREBUILT,
|
||||
* space needs to be reserved for the rodata that will be
|
||||
* produced by gperf during the final stages of linking.
|
||||
* The alignment and size are produced by
|
||||
* scripts/gen_kobject_placeholders.py. These are here
|
||||
* so the addresses to kobjects would remain the same
|
||||
* during the final stages of linking (LINKER_ZEPHYR_FINAL).
|
||||
*/
|
||||
|
||||
#if defined(LINKER_ZEPHYR_PREBUILT)
|
||||
#include <linker-kobject-prebuilt-rodata.h>
|
||||
#ifdef KOBJECT_RODATA_ALIGN
|
||||
. = ALIGN(KOBJECT_RODATA_ALIGN);
|
||||
|
||||
_kobject_rodata_area_start = .;
|
||||
|
||||
. += KOBJECT_RODATA_SZ;
|
||||
|
||||
_kobject_rodata_area_end = .;
|
||||
#endif
|
||||
#endif /* LINKER_ZEPHYR_PREBUILT */
|
||||
|
||||
#if defined(LINKER_ZEPHYR_FINAL)
|
||||
#include <linker-kobject-prebuilt-rodata.h>
|
||||
#ifdef KOBJECT_RODATA_ALIGN
|
||||
. = ALIGN(KOBJECT_RODATA_ALIGN);
|
||||
|
||||
_kobject_rodata_area_start = .;
|
||||
#endif
|
||||
|
||||
*(".kobject_data.rodata*")
|
||||
|
||||
#ifdef KOBJECT_RODATA_ALIGN
|
||||
_kobject_rodata_area_end = .;
|
||||
_kobject_rodata_area_used = _kobject_rodata_area_end - _kobject_rodata_area_start;
|
||||
|
||||
ASSERT(_kobject_rodata_area_used <= KOBJECT_RODATA_SZ,
|
||||
"scripts/gen_kobject_placeholders.py did not reserve enough space \
|
||||
for kobject rodata."
|
||||
);
|
||||
|
||||
/* Padding is needed to preserve kobject addresses
|
||||
* if we have reserved more space than needed.
|
||||
*/
|
||||
. = MAX(., _kobject_rodata_area_start + KOBJECT_RODATA_SZ);
|
||||
#endif /* KOBJECT_RODATA_ALIGN */
|
||||
#endif /* LINKER_ZEPHYR_FINAL */
|
||||
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
z_kobject_data_begin = .;
|
||||
/* Constraints:
|
||||
*
|
||||
* - changes to the size of this section between build phases
|
||||
* *must not* shift the memory address of any kernel obejcts,
|
||||
* since it contains a hashtable of the memory addresses of those
|
||||
* kernel objects
|
||||
*
|
||||
* - It is OK if this section itself is shifted in between builds; for
|
||||
* example some arches may precede this section with generated MMU
|
||||
* page tables which are also unpredictable in size.
|
||||
*
|
||||
* The size of the
|
||||
* gperf tables is both a function of the number of kernel objects,
|
||||
* *and* the specific memory addresses being hashed. It is not something
|
||||
* that can be predicted without actually building and compling it.
|
||||
*/
|
||||
SECTION_DATA_PROLOGUE(kobject_data,,)
|
||||
{
|
||||
*(".kobject_data.data*")
|
||||
|
||||
#ifndef LINKER_ZEPHYR_FINAL
|
||||
#ifdef CONFIG_DYNAMIC_OBJECTS
|
||||
PROVIDE(_thread_idx_map = .);
|
||||
. += CONFIG_MAX_THREAD_BYTES;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This is also unpredictable in size, and has the same constraints.
|
||||
* On XIP systems this will get put at the very end of ROM.
|
||||
*/
|
||||
#ifndef CONFIG_XIP
|
||||
*(".kobject_data.rodata*")
|
||||
#endif
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
|
||||
#ifdef CONFIG_GEN_PRIV_STACKS
|
||||
SECTION_DATA_PROLOGUE(priv_stacks_noinit,,)
|
||||
{
|
||||
z_priv_stacks_ram_start = .;
|
||||
*(".priv_stacks.noinit")
|
||||
z_priv_stacks_ram_end = .;
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
#endif /* CONFIG_GEN_PRIV_STACKS */
|
||||
#endif /* CONFIG_USERSPACE */
|
Loading…
Add table
Add a link
Reference in a new issue