userspace: app_shared_mem: Fixed incorrect implementation.
This feature was failing on a default ARM core MPU. The linker script that was getting created was not able to align the required partitions at prebuilt time. The old implementation relied on the prebuilt to finish then extract the size information which was then used to align the regions. This fails because the size of the alignment and the fill in the linker needs to be available at prebuilt time else it cant manage the final elf file generation. We cant have 2 different sizes of prebuilt and final elf file. This implementation will get the alignment requirements met at prebuilt time. Signed-off-by: Adithya Baglody <adithya.nagaraj.baglody@intel.com>
This commit is contained in:
parent
38323783f0
commit
c69fb0d016
|
@ -700,6 +700,7 @@ add_custom_target(
|
||||||
linker_script
|
linker_script
|
||||||
DEPENDS
|
DEPENDS
|
||||||
${ALIGN_SIZING_DEP} ${PRIV_STACK_DEP}
|
${ALIGN_SIZING_DEP} ${PRIV_STACK_DEP}
|
||||||
|
${APP_SMEM_DEP}
|
||||||
linker.cmd
|
linker.cmd
|
||||||
offsets_h
|
offsets_h
|
||||||
)
|
)
|
||||||
|
@ -1016,20 +1017,22 @@ configure_file(
|
||||||
if(CONFIG_CPU_HAS_MPU AND CONFIG_USERSPACE)
|
if(CONFIG_CPU_HAS_MPU AND CONFIG_USERSPACE)
|
||||||
|
|
||||||
if(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT AND CONFIG_APP_SHARED_MEM)
|
if(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT AND CONFIG_APP_SHARED_MEM)
|
||||||
set(GEN_APP_SMEM $ENV{ZEPHYR_BASE}/scripts/gen_app_smem.py)
|
|
||||||
set(APP_SMEM_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem.ld")
|
set(APP_SMEM_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem.ld")
|
||||||
set(OBJ_FILE_DIR "${PROJECT_BINARY_DIR}/../")
|
set(OBJ_FILE_DIR "${PROJECT_BINARY_DIR}/../")
|
||||||
|
|
||||||
add_custom_target(
|
add_custom_target(
|
||||||
${APP_SMEM_DEP} ALL
|
${APP_SMEM_DEP} ALL
|
||||||
DEPENDS zephyr_prebuilt
|
DEPENDS app
|
||||||
|
DEPENDS ${PRIV_STACK_DEP}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ${APP_SMEM_DEP}
|
TARGET ${APP_SMEM_DEP}
|
||||||
COMMAND ${PYTHON_EXECUTABLE} ${GEN_APP_SMEM}
|
COMMAND ${PYTHON_EXECUTABLE}
|
||||||
|
${ZEPHYR_BASE}/scripts/gen_app_partitions.py
|
||||||
-d ${OBJ_FILE_DIR}
|
-d ${OBJ_FILE_DIR}
|
||||||
-o ${APP_SMEM_LD}
|
-o ${APP_SMEM_LD}
|
||||||
|
$<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose>
|
||||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/
|
||||||
COMMENT "Generating power of 2 aligned app_smem linker section"
|
COMMENT "Generating power of 2 aligned app_smem linker section"
|
||||||
)
|
)
|
||||||
|
@ -1145,7 +1148,7 @@ if(GKOF OR GKSF)
|
||||||
add_executable( kernel_elf misc/empty_file.c ${GKSF})
|
add_executable( kernel_elf misc/empty_file.c ${GKSF})
|
||||||
target_link_libraries(kernel_elf ${GKOF} ${TOPT} ${PROJECT_BINARY_DIR}/linker_pass_final.cmd ${zephyr_lnk})
|
target_link_libraries(kernel_elf ${GKOF} ${TOPT} ${PROJECT_BINARY_DIR}/linker_pass_final.cmd ${zephyr_lnk})
|
||||||
set_property(TARGET kernel_elf PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_pass_final.cmd)
|
set_property(TARGET kernel_elf PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_pass_final.cmd)
|
||||||
add_dependencies( kernel_elf ${ALIGN_SIZING_DEP} ${PRIV_STACK_DEP} ${APP_SMEM_DEP} linker_pass_final_script)
|
add_dependencies( kernel_elf ${ALIGN_SIZING_DEP} ${PRIV_STACK_DEP} linker_pass_final_script)
|
||||||
else()
|
else()
|
||||||
set(logical_target_for_zephyr_elf zephyr_prebuilt)
|
set(logical_target_for_zephyr_elf zephyr_prebuilt)
|
||||||
# Use the prebuilt elf as the final elf since we don't have a
|
# Use the prebuilt elf as the final elf since we don't have a
|
||||||
|
|
91
scripts/gen_app_partitions.py
Normal file
91
scripts/gen_app_partitions.py
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import string
|
||||||
|
from elf_helper import ElfHelper
|
||||||
|
from elftools.elf.elffile import ELFFile
|
||||||
|
|
||||||
|
|
||||||
|
# This script will create linker comands for power of two aligned MPU
|
||||||
|
# when APP_SHARED_MEM is enabled.
|
||||||
|
print_template = """
|
||||||
|
/* Auto generated code do not modify */
|
||||||
|
. = ALIGN( 1 << LOG2CEIL(data_smem_{0}b_end - data_smem_{0}));
|
||||||
|
data_smem_{0} = .;
|
||||||
|
KEEP(*(SORT(data_smem_{0}*)))
|
||||||
|
. = ALIGN(_app_data_align);
|
||||||
|
data_smem_{0}b_end = .;
|
||||||
|
. = ALIGN( 1 << LOG2CEIL(data_smem_{0}b_end - data_smem_{0}));
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def find_partitions(filename, full_list_of_partitions, partitions_source_file):
|
||||||
|
with open(filename, 'rb') as f:
|
||||||
|
full_lib = ELFFile( f)
|
||||||
|
if (not full_lib):
|
||||||
|
print("Error parsing file: ",filename)
|
||||||
|
os.exit(1)
|
||||||
|
|
||||||
|
sections = [ x for x in full_lib.iter_sections()]
|
||||||
|
for section in sections:
|
||||||
|
if ("smem" in section.name and not ".rel" in section.name):
|
||||||
|
partition_name = section.name.split("data_smem_")[1]
|
||||||
|
if partition_name not in full_list_of_partitions:
|
||||||
|
full_list_of_partitions.append(partition_name)
|
||||||
|
if args.verbose:
|
||||||
|
partitions_source_file.update({partition_name: filename})
|
||||||
|
|
||||||
|
return( full_list_of_partitions, partitions_source_file)
|
||||||
|
|
||||||
|
def cleanup_remove_bss_regions(full_list_of_partitions):
|
||||||
|
for partition in full_list_of_partitions:
|
||||||
|
if (partition+"b" in full_list_of_partitions):
|
||||||
|
full_list_of_partitions.remove(partition+"b")
|
||||||
|
return full_list_of_partitions
|
||||||
|
|
||||||
|
def generate_final_linker(linker_file, full_list_of_partitions):
|
||||||
|
string= ''
|
||||||
|
for partition in full_list_of_partitions:
|
||||||
|
string += print_template.format(partition)
|
||||||
|
|
||||||
|
with open(linker_file, "w") as fw:
|
||||||
|
fw.write(string)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
global args
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description=__doc__,
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||||
|
parser.add_argument("-d", "--directory", required=True,
|
||||||
|
help="Root build directory")
|
||||||
|
parser.add_argument("-o", "--output", required=False,
|
||||||
|
help="Output ld file")
|
||||||
|
parser.add_argument("-v", "--verbose", action="count", default =0,
|
||||||
|
help="Verbose Output")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parse_args()
|
||||||
|
root_directory = args.directory
|
||||||
|
linker_file = args.output
|
||||||
|
full_list_of_partitions = []
|
||||||
|
partitions_source_file= {}
|
||||||
|
|
||||||
|
for dirpath, dirs, files in os.walk(root_directory):
|
||||||
|
for filename in files:
|
||||||
|
if re.match(".*\.obj$",filename):
|
||||||
|
fullname = os.path.join(dirpath, filename)
|
||||||
|
full_list_of_partitions, partitions_source_file = find_partitions(fullname, full_list_of_partitions, partitions_source_file)
|
||||||
|
|
||||||
|
full_list_of_partitions = cleanup_remove_bss_regions(full_list_of_partitions)
|
||||||
|
generate_final_linker(linker_file, full_list_of_partitions)
|
||||||
|
if args.verbose:
|
||||||
|
print("Partitions retrieved: PARTITION, FILENAME")
|
||||||
|
print([key + " "+ partitions_source_file[key] for key in full_list_of_partitions])
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in a new issue