mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-03 04:53:01 +00:00
This commit standardizes and simplifies the way we enforce linker section alignment, to comply with minimum alignment requirement for MPU, if we build Zephyr with MPU support: - it enforces alignment with the minimum MPU granularity at the beginning and end of linker sections that require to be protected by MPU, - it enforces alignment with size if required by the MPU architecture. Particularly for the Application Memory section, the commit simplifies how the proper alignment is enforced, removing the need of calculating the alignment with a post-linker python script. It also removes the need for an additional section for padding. For the Application Shared Memory section(s), the commit enforces minimum alignment besides the requirement for alignment with size (for the respective MPUs) and fixes a bug where the app_data_align was erronously used in the scipts for auto-generating the linker scripts. Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
112 lines
3.6 KiB
Python
112 lines
3.6 KiB
Python
#!/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 */
|
|
MPU_ALIGN(data_smem_{0}b_end - data_smem_{0});
|
|
data_smem_{0} = .;
|
|
KEEP(*(SORT(data_smem_{0}*)))
|
|
MPU_ALIGN(data_smem_{0}b_end - data_smem_{0});
|
|
data_smem_{0}b_end = .;
|
|
"""
|
|
linker_start_seq = """
|
|
SECTION_PROLOGUE(_APP_SMEM_SECTION_NAME, (OPTIONAL),)
|
|
{
|
|
APP_SHARED_ALIGN;
|
|
_image_ram_start = .;
|
|
_app_smem_start = .;
|
|
"""
|
|
|
|
linker_end_seq = """
|
|
_app_smem_end = .;
|
|
APP_SHARED_ALIGN;
|
|
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
|
"""
|
|
|
|
size_cal_string = """
|
|
data_smem_{0}_size = 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 = linker_start_seq
|
|
size_string = ''
|
|
for partition in full_list_of_partitions:
|
|
string += print_template.format(partition)
|
|
size_string += size_cal_string.format(partition)
|
|
|
|
string += linker_end_seq
|
|
string += size_string
|
|
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()
|