123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- #!/usr/bin/env python3
- import os
- import common
- class BaremetalComponent(self.Component):
- def do_build(self, args):
- self.assert_crosstool_ng_supports_arch(kwargs['arch'])
- build_dir = self.get_build_dir(args)
- bootloader_obj = os.path.join(kwargs['baremetal_build_lib_dir'], 'bootloader{}'.format(kwargs['obj_ext']))
- common_basename_noext = 'common'
- common_src = os.path.join(kwargs['root_dir'], common_basename_noext + kwargs['c_ext'])
- common_obj = os.path.join(kwargs['baremetal_build_lib_dir'], common_basename_noext + kwargs['obj_ext'])
- syscalls_basename_noext = 'syscalls'
- syscalls_src = os.path.join(kwargs['baremetal_src_lib_dir'], syscalls_basename_noext + kwargs['c_ext'])
- syscalls_obj = os.path.join(kwargs['baremetal_build_lib_dir'], syscalls_basename_noext + kwargs['obj_ext'])
- common_objs = [common_obj, syscalls_obj]
- cflags = [
- '-I', kwargs['baremetal_src_lib_dir'], LF,
- '-I', kwargs['root_dir'], LF,
- '-O0', LF,
- '-ggdb3', LF,
- '-mcpu={}'.format(kwargs['mcpu']), LF,
- '-nostartfiles', LF,
- ]
- if kwargs['prebuilt']:
- gcc = 'arm-none-eabi-gcc'
- else:
- os.environ['PATH'] = kwargs['crosstool_ng_bin_dir'] + os.environ['PATH']
- gcc = self.get_toolchain_tool('gcc', allowed_toolchains=['crosstool-ng'])
- if kwargs['emulator'] == 'gem5':
- if kwargs['machine'] == 'VExpress_GEM5_V1':
- entry_address = 0x80000000
- uart_address = 0x1c090000
- elif kwargs['machine'] == 'RealViewPBX':
- entry_address = 0x10000
- uart_address = 0x10009000
- else:
- raise Exception('unknown machine: ' + kwargs['machine'])
- cflags.extend(['-D', 'GEM5'.format(uart_address), LF])
- else:
- entry_address = 0x40000000
- uart_address = 0x09000000
- os.makedirs(build_dir, exist_ok=True)
- os.makedirs(kwargs['baremetal_build_lib_dir'], exist_ok=True)
- src = os.path.join(kwargs['baremetal_src_lib_dir'], '{}{}'.format(kwargs['arch'], kwargs['asm_ext']))
- if self.need_rebuild([src], bootloader_obj):
- self.sh.run_cmd(
- [gcc, LF] +
- cflags +
- [
- '-c', LF,
- '-o', bootloader_obj, LF,
- src, LF,
- ]
- )
- for src, obj in [
- (common_src, common_obj),
- (syscalls_src, syscalls_obj),
- ]:
- if self.need_rebuild([src], obj):
- self.sh.run_cmd(
- [gcc, LF] +
- cflags +
- [
- '-c', LF,
- '-D', 'UART0_ADDR={:#x}'.format(uart_address), LF,
- '-o', obj, LF,
- src, LF,
- ]
- )
- self._build_dir(
- '',
- gcc=gcc,
- cflags=cflags,
- entry_address=entry_address,
- bootloader_obj=bootloader_obj,
- common_objs=common_objs,
- )
- self._build_dir(
- 'interactive',
- gcc=gcc,
- cflags=cflags,
- entry_address=entry_address,
- bootloader_obj=bootloader_obj,
- common_objs=common_objs,
- )
- arch_dir = os.path.join('arch', kwargs['arch'])
- if os.path.isdir(os.path.join(kwargs['baremetal_src_dir'], arch_dir)):
- self._build_dir(
- arch_dir,
- gcc=gcc,
- cflags=cflags,
- entry_address=entry_address,
- bootloader_obj=bootloader_obj,
- common_objs=common_objs,
- )
- arch_dir = os.path.join('arch', kwargs['arch'], 'no_bootloader')
- if os.path.isdir(os.path.join(kwargs['baremetal_src_dir'], arch_dir)):
- self._build_dir(
- arch_dir,
- gcc=gcc,
- cflags=cflags,
- entry_address=entry_address,
- bootloader_obj=bootloader_obj,
- common_objs=common_objs,
- bootloader=False,
- )
- def get_argparse_args(self):
- return {
- 'description': '''\
- Build the baremetal examples with crosstool-NG.
- '''
- }
- def get_build_dir(self, args):
- return kwargs['baremetal_build_dir']
- def get_default_args(self):
- return {'baremetal': 'all'}
- def _build_dir(
- self,
- subpath,
- gcc,
- cflags,
- entry_address,
- bootloader_obj,
- common_objs,
- 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(kwargs['baremetal_src_dir'], subpath)
- out_dir = os.path.join(kwargs['baremetal_build_dir'], subpath)
- os.makedirs(out_dir, exist_ok=True)
- common_objs = common_objs.copy()
- if bootloader:
- common_objs.append(bootloader_obj)
- 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 (kwargs['c_ext'], kwargs['asm_ext']):
- in_name = os.path.splitext(in_basename)[0]
- main_obj = os.path.join(kwargs['baremetal_build_dir'], subpath, '{}{}'.format(in_name, kwargs['obj_ext']))
- src = os.path.join(kwargs['baremetal_src_dir'], in_path)
- if self.need_rebuild([src], main_obj):
- self.sh.run_cmd(
- [gcc, LF] +
- cflags +
- [
- '-c', LF,
- '-o', main_obj, LF,
- src, LF,
- ]
- )
- objs = common_objs + [main_obj]
- out = os.path.join(kwargs['baremetal_build_dir'], subpath, in_name + kwargs['baremetal_build_ext'])
- link_script = os.path.join(kwargs['baremetal_src_dir'], 'link.ld')
- if self.need_rebuild(objs + [link_script], out):
- self.sh.run_cmd(
- [gcc, LF] +
- cflags +
- [
- '-Wl,--section-start=.text={:#x}'.format(entry_address), LF,
- '-o', out, LF,
- '-T', link_script, LF,
- ] +
- self.sh.add_newlines(objs)
- )
- if __name__ == '__main__':
- BaremetalComponent().build()
|