| #!/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); |
| . = ALIGN( 1 << LOG2CEIL(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() |