#!/usr/bin/env python3 import glob import multiprocessing import os import shutil import sys import time import common def build_dir(subpath, gcc, cflags, entry_address, bootloader_obj, common_obj, bootloader=True): """ Build all .c and .S files in a given subpath of the baremetal source directory non recursively. Place outputs on the same subpath or the output directory. """ in_dir = os.path.join(common.baremetal_src_dir, subpath) out_dir = os.path.join(common.baremetal_out_dir, subpath) os.makedirs(out_dir, exist_ok=True) if bootloader: bootloader_cmd = [bootloader_obj] else: bootloader_cmd = [] for in_basename in os.listdir(in_dir): in_path = os.path.join(in_dir, in_basename) if os.path.isfile(in_path) and os.path.splitext(in_basename)[1] in (common.c_ext, common.asm_ext): in_name = os.path.splitext(in_basename)[0] main_obj = os.path.join(common.baremetal_out_dir, subpath, '{}{}'.format(in_name, common.obj_ext)) assert common.run_cmd( [gcc] + cflags + [ '-c', '-o', main_obj, os.path.join(common.baremetal_src_dir, in_path), ] ) == 0 assert common.run_cmd( [gcc] + cflags + [ '-Wl,--section-start=.text={:#x}'.format(entry_address), '-o', os.path.join(common.baremetal_out_dir, subpath, in_name + common.baremetal_out_ext), '-T', os.path.join(common.baremetal_src_dir, 'link.ld'), ] + bootloader_cmd + [ common_obj, main_obj, ] ) == 0 def get_argparse(): parser = common.get_argparse(argparse_args={ 'description': 'Build the baremetal examples with crosstool-NG' }) common.add_build_arguments(parser) return parser def main(args, extra_args=None): if args.clean: common.rmrf(common.baremetal_out_dir) else: common.raise_no_x86(args.arch) bootloader_obj = os.path.join(common.baremetal_out_lib_dir, 'bootloader{}'.format(common.obj_ext)) common_obj = os.path.join(common.baremetal_out_lib_dir, 'common{}'.format(common.obj_ext)) cflags = [ '-ggdb3', '-mcpu={}'.format(common.mcpu), '-nostartfiles', '-O0', ] if args.prebuilt: gcc = 'arm-none-eabi-gcc' else: os.environ['PATH'] = common.crosstool_ng_bin_dir + os.environ['PATH'] gcc = common.get_toolchain_tool('gcc', allowed_toolchains=['crosstool-ng']) if args.gem5: if common.machine == 'VExpress_GEM5_V1': entry_address = 0x80000000 uart_address = 0x1c090000 elif common.machine == 'RealViewPBX': entry_address = 0x10000 uart_address = 0x10009000 else: raise Exception('unknown machine: ' + common.machine) else: entry_address = 0x40000000 uart_address = 0x09000000 os.makedirs(common.baremetal_out_dir, exist_ok=True) os.makedirs(common.baremetal_out_lib_dir, exist_ok=True) assert common.run_cmd( [gcc] + cflags + [ '-c', '-o', bootloader_obj, os.path.join(common.baremetal_src_lib_dir, '{}{}'.format(args.arch, common.asm_ext)), ] ) == 0 assert common.run_cmd( [gcc] + cflags + [ '-c', '-D', 'UART0_ADDR={:#x}'.format(uart_address), '-o', common_obj, os.path.join(common.baremetal_src_lib_dir, 'common' + common.c_ext), ] ) == 0 build_dir( '', gcc=gcc, cflags=cflags, entry_address=entry_address, bootloader_obj=bootloader_obj, common_obj=common_obj, ) build_dir( 'interactive', gcc=gcc, cflags=cflags, entry_address=entry_address, bootloader_obj=bootloader_obj, common_obj=common_obj, ) arch_dir = os.path.join('arch', args.arch) if os.path.isdir(os.path.join(common.baremetal_src_dir, arch_dir)): build_dir( arch_dir, gcc=gcc, cflags=cflags, entry_address=entry_address, bootloader_obj=bootloader_obj, common_obj=common_obj, ) arch_dir = os.path.join('arch', args.arch, 'no_bootloader') if os.path.isdir(os.path.join(common.baremetal_src_dir, arch_dir)): build_dir( arch_dir, gcc=gcc, cflags=cflags, entry_address=entry_address, bootloader_obj=bootloader_obj, common_obj=common_obj, bootloader=False, ) return 0 if __name__ == '__main__': parser = common.get_argparse( default_args={'baremetal': 'all'}, ) common.add_build_arguments(parser) args = common.setup(parser) start_time = time.time() exit_status = main(args) end_time = time.time() common.print_time(end_time - start_time) sys.exit(exit_status)