considering some new design ideas

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2018-11-30 00:00:00 +00:00
parent 271e7c6371
commit 1accb2c98b
3 changed files with 197 additions and 226 deletions

View File

@@ -8,16 +8,15 @@ import common
from cli_function import Argument from cli_function import Argument
class Main(common.BuildCliFunction): class Main(common.BuildCliFunction):
def do_get_arguments(self): def __init__(self):
return [ super().__init__()
Argument( self.add_argument(
'extra_scons_args', 'extra_scons_args',
metavar='extra-scons-args', metavar='extra-scons-args',
nargs='*', nargs='*',
) )
]
def do_main(self, **kwargs): def build(self, **kwargs):
build_dir = self.get_build_dir(**kwargs) build_dir = self.get_build_dir(**kwargs)
binaries_dir = os.path.join(kwargs['gem5_system_dir'], 'binaries') binaries_dir = os.path.join(kwargs['gem5_system_dir'], 'binaries')
disks_dir = os.path.join(kwargs['gem5_system_dir'], 'disks') disks_dir = os.path.join(kwargs['gem5_system_dir'], 'disks')

View File

@@ -7,13 +7,19 @@ import os
class Argument: class Argument:
def __init__( def __init__(
self, self,
longname, long_or_short_1,
shortname=None, long_or_short_2=None,
default=None, default=None,
help=None, help=None,
nargs=None, nargs=None,
**kwargs **kwargs
): ):
if long_or_short_2 is None:
shortname = None
longname = long_or_short_1
else:
shortname = long_or_short_1
longname = long_or_short_2
self.args = [] self.args = []
# argparse is crappy and cannot tell us if arguments were given or not. # argparse is crappy and cannot tell us if arguments were given or not.
# We need that information to decide if the config file should override argparse or not. # We need that information to decide if the config file should override argparse or not.
@@ -83,25 +89,23 @@ class CliFunction:
:type arguments: Dict :type arguments: Dict
''' '''
arguments = self._get_arguments()
args_with_defaults = args.copy() args_with_defaults = args.copy()
# Add missing args from config file. # Add missing args from config file.
if 'config_file' in args_with_defaults and args_with_defaults['config_file'] is not None: if 'config_file' in args_with_defaults and args_with_defaults['config_file'] is not None:
config_file = args_with_defaults['config_file'] config_file = args_with_defaults['config_file']
else: else:
config_file = self.default_config config_file = self._config_file
if os.path.exists(config_file): if os.path.exists(config_file):
all_keys = {argument.key for argument in arguments}
config_configs = {} config_configs = {}
config = imp.load_source('config', config_file) config = imp.load_source('config', config_file)
config.set_args(config_configs) config.set_args(config_configs)
for key in config_configs: for key in config_configs:
if key not in all_keys: if key not in self._all_keys:
raise Exception('Unknown key in config file: ' + key) raise Exception('Unknown key in config file: ' + key)
if (not key in args_with_defaults) or args_with_defaults[key] is None: if (not key in args_with_defaults) or args_with_defaults[key] is None:
args_with_defaults[key] = config_configs[key] args_with_defaults[key] = config_configs[key]
# Add missing args from hard-coded defaults. # Add missing args from hard-coded defaults.
for argument in arguments: for argument in self._arguments:
key = argument.key key = argument.key
if (not key in args_with_defaults) or args_with_defaults[key] is None: if (not key in args_with_defaults) or args_with_defaults[key] is None:
if argument.optional: if argument.optional:
@@ -110,24 +114,26 @@ class CliFunction:
raise Exception('Value not given for mandatory argument: ' + key) raise Exception('Value not given for mandatory argument: ' + key)
return self.main(**args_with_defaults) return self.main(**args_with_defaults)
def __init__(self): def __init__(self, config_file=None):
self.default_config = 'config.py' self._all_keys = set()
self._arguments = []
def _get_arguments(self): self.description = None
''' self._config_file = config_file
Define the arguments that the function takes. if self._config_file is not None:
self.add_argument(
:rtype: List[Argument] '--config-file',
''' default=self._config_file,
args = self.get_arguments()
config_file = self.get_config_file()
if config_file is not None:
args.append(Argument(
longname='--config-file',
default=config_file,
help='Path to the configuration file to use' help='Path to the configuration file to use'
)) )
return args
def add_argument(
self,
*args,
**kwargs
):
argument = Argument(*args, **kwargs)
self._arguments.append(argument)
self._all_keys.add(argument.key)
def cli(self, args=None): def cli(self, args=None):
''' '''
@@ -135,36 +141,14 @@ class CliFunction:
to get all arguments. to get all arguments.
''' '''
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description=self.get_description(), description=self.description,
formatter_class=argparse.RawTextHelpFormatter, formatter_class=argparse.RawTextHelpFormatter,
) )
for argument in self._get_arguments(): for argument in self._arguments:
parser.add_argument(*argument.args, **argument.kwargs) parser.add_argument(*argument.args, **argument.kwargs)
args = parser.parse_args(args=args) args = parser.parse_args(args=args)
return self(**vars(args)) return self(**vars(args))
def get_arguments(self):
'''
Define the arguments that the function takes.
:rtype: List[Argument]
'''
raise NotImplementedError
def get_config_file(self):
'''
:rtype: Union[None,str]
'''
return None
def get_description(self):
'''
argparse.ArgumentParser() description.
:rtype: Union[Any,str]
'''
return None
def main(self, arguments): def main(self, arguments):
''' '''
Do the main function call work. Do the main function call work.
@@ -175,15 +159,18 @@ class CliFunction:
if __name__ == '__main__': if __name__ == '__main__':
class OneCliFunction(CliFunction): class OneCliFunction(CliFunction):
def get_arguments(self): def __init__(self):
return [ super().__init__(config_file='cli_function_config_file.py')
Argument(shortname='-a', longname='--asdf', default='A', help='Help for asdf'), self.add_argument('-a', '--asdf', default='A', help='Help for asdf'),
Argument(shortname='-q', longname='--qwer', default='Q', help='Help for qwer'), self.add_argument('-q', '--qwer', default='Q', help='Help for qwer'),
Argument(shortname='-b', longname='--bool', default=True, help='Help for bool'), self.add_argument('-b', '--bool', default=True, help='Help for bool'),
Argument(longname='pos-mandatory', help='Help for pos-mandatory', type=int), self.add_argument('pos-mandatory', help='Help for pos-mandatory', type=int),
Argument(longname='pos-optional', default=0, help='Help for pos-optional', type=int), self.add_argument('pos-optional', default=0, help='Help for pos-optional', type=int),
Argument(longname='args-star', help='Help for args-star', nargs='*'), self.add_argument('args-star', help='Help for args-star', nargs='*'),
] self.description = '''\
Description of this
amazing function!
'''
def main(self, **kwargs): def main(self, **kwargs):
return \ return \
kwargs['asdf'], \ kwargs['asdf'], \
@@ -192,13 +179,6 @@ if __name__ == '__main__':
kwargs['pos_optional'], \ kwargs['pos_optional'], \
kwargs['pos_mandatory'], \ kwargs['pos_mandatory'], \
kwargs['args_star'] kwargs['args_star']
def get_config_file(self):
return 'test_config.py'
def get_description(self):
return '''\
Description of this
amazing function!
'''
# Code calls. # Code calls.
assert OneCliFunction()(pos_mandatory=1) == ('A', 'Q', True, 0, 1, []) assert OneCliFunction()(pos_mandatory=1) == ('A', 'Q', True, 0, 1, [])

298
common.py
View File

@@ -2,7 +2,6 @@
import argparse import argparse
import base64 import base64
import cli_function
import collections import collections
import copy import copy
import datetime import datetime
@@ -24,77 +23,86 @@ import time
import urllib import urllib
import urllib.request import urllib.request
import cli_function
common = sys.modules[__name__] common = sys.modules[__name__]
repo_short_id = 'lkmc'
# Fixed parameters that don't depend on CLI arguments.
consts = {}
consts['repo_short_id'] = 'lkmc'
# https://stackoverflow.com/questions/20010199/how-to-determine-if-a-process-runs-inside-lxc-docker # https://stackoverflow.com/questions/20010199/how-to-determine-if-a-process-runs-inside-lxc-docker
in_docker = os.path.exists('/.dockerenv') consts['in_docker'] = os.path.exists('/.dockerenv')
root_dir = os.path.dirname(os.path.abspath(__file__)) consts['root_dir'] = os.path.dirname(os.path.abspath(__file__))
data_dir = os.path.join(root_dir, 'data') consts['data_dir'] = os.path.join(consts['root_dir'], 'data')
p9_dir = os.path.join(data_dir, '9p') consts['p9_dir'] = os.path.join(consts['data_dir'], '9p')
gem5_non_default_src_root_dir = os.path.join(data_dir, 'gem5') consts['gem5_non_default_src_root_dir'] = os.path.join(consts['data_dir'], 'gem5')
if in_docker: if consts['in_docker']:
out_dir = os.path.join(root_dir, 'out.docker') consts['out_dir'] = os.path.join(consts['root_dir'], 'out.docker')
else: else:
out_dir = os.path.join(root_dir, 'out') consts['out_dir'] = os.path.join(consts['root_dir'], 'out')
bench_boot = os.path.join(out_dir, 'bench-boot.txt') consts['bench_boot'] = os.path.join(consts['out_dir'], 'bench-boot.txt')
packages_dir = os.path.join(root_dir, 'buildroot_packages') consts['packages_dir'] = os.path.join(consts['root_dir'], 'buildroot_packages')
kernel_modules_subdir = 'kernel_modules' consts['kernel_modules_subdir'] = 'kernel_modules'
kernel_modules_src_dir = os.path.join(common.root_dir, common.kernel_modules_subdir) consts['kernel_modules_src_dir'] = os.path.join(consts['root_dir'], consts['kernel_modules_subdir'])
userland_subdir = 'userland' consts['userland_subdir'] = 'userland'
userland_src_dir = os.path.join(common.root_dir, common.userland_subdir) consts['userland_src_dir'] = os.path.join(consts['root_dir'], consts['userland_subdir'])
userland_build_ext = '.out' consts['userland_build_ext'] = '.out'
include_subdir = 'include' consts['include_subdir'] = 'include'
include_src_dir = os.path.join(common.root_dir, common.include_subdir) consts['include_src_dir'] = os.path.join(consts['root_dir'], consts['include_subdir'])
submodules_dir = os.path.join(root_dir, 'submodules') consts['submodules_dir'] = os.path.join(consts['root_dir'], 'submodules')
buildroot_src_dir = os.path.join(submodules_dir, 'buildroot') consts['buildroot_src_dir'] = os.path.join(consts['submodules_dir'], 'buildroot')
crosstool_ng_src_dir = os.path.join(submodules_dir, 'crosstool-ng') consts['crosstool_ng_src_dir'] = os.path.join(consts['submodules_dir'], 'crosstool-ng')
crosstool_ng_supported_archs = set(['arm', 'aarch64']) consts['crosstool_ng_supported_archs'] = set(['arm', 'aarch64'])
linux_src_dir = os.path.join(submodules_dir, 'linux') consts['linux_src_dir'] = os.path.join(consts['submodules_dir'], 'linux')
linux_config_dir = os.path.join(common.root_dir, 'linux_config') consts['linux_config_dir'] = os.path.join(consts['root_dir'], 'linux_config')
rootfs_overlay_dir = os.path.join(common.root_dir, 'rootfs_overlay') consts['rootfs_overlay_dir'] = os.path.join(consts['root_dir'], 'rootfs_overlay')
extract_vmlinux = os.path.join(linux_src_dir, 'scripts', 'extract-vmlinux') consts['extract_vmlinux'] = os.path.join(consts['linux_src_dir'], 'scripts', 'extract-vmlinux')
qemu_src_dir = os.path.join(submodules_dir, 'qemu') consts['qemu_src_dir'] = os.path.join(consts['submodules_dir'], 'qemu')
parsec_benchmark_src_dir = os.path.join(submodules_dir, 'parsec-benchmark') consts['parsec_benchmark_src_dir'] = os.path.join(consts['submodules_dir'], 'parsec-benchmark')
ccache_dir = os.path.join('/usr', 'lib', 'ccache') consts['ccache_dir'] = os.path.join('/usr', 'lib', 'ccache')
default_build_id = 'default' consts['default_build_id'] = 'default'
arch_short_to_long_dict = collections.OrderedDict([ consts['arch_short_to_long_dict'] = collections.OrderedDict([
('x', 'x86_64'), ('x', 'x86_64'),
('a', 'arm'), ('a', 'arm'),
('A', 'aarch64'), ('A', 'aarch64'),
]) ])
all_archs = [arch_short_to_long_dict[k] for k in arch_short_to_long_dict] consts['all_archs'] = [consts['arch_short_to_long_dict'][k] for k in consts['arch_short_to_long_dict']]
arch_choices = [] consts['arch_choices'] = []
for key in common.arch_short_to_long_dict: for key in consts['arch_short_to_long_dict']:
arch_choices.append(key) consts['arch_choices'].append(key)
arch_choices.append(common.arch_short_to_long_dict[key]) consts['arch_choices'].append(consts['arch_short_to_long_dict'][key])
default_arch = 'x86_64' consts['default_arch'] = 'x86_64'
gem5_cpt_prefix = '^cpt\.' consts['gem5_cpt_prefix'] = '^cpt\.'
sha = subprocess.check_output(['git', '-C', root_dir, 'log', '-1', '--format=%H']).decode().rstrip() consts['sha'] = subprocess.check_output(['git', '-C', consts['root_dir'], 'log', '-1', '--format=%H']).decode().rstrip()
release_dir = os.path.join(common.out_dir, 'release') consts['release_dir'] = os.path.join(consts['out_dir'], 'release')
release_zip_file = os.path.join(common.release_dir, 'lkmc-{}.zip'.format(common.sha)) consts['release_zip_file'] = os.path.join(consts['release_dir'], 'lkmc-{}.zip'.format(consts['sha']))
github_repo_id = 'cirosantilli/linux-kernel-module-cheat' consts['github_repo_id'] = 'cirosantilli/linux-kernel-module-cheat'
asm_ext = '.S' consts['asm_ext'] = '.S'
c_ext = '.c' consts['c_ext'] = '.c'
header_ext = '.h' consts['header_ext'] = '.h'
kernel_module_ext = '.ko' consts['kernel_module_ext'] = '.ko'
obj_ext = '.o' consts['obj_ext'] = '.o'
config_file = os.path.join(data_dir, 'config') consts['config_file'] = os.path.join(consts['data_dir'], 'config.py')
command_prefix = '+ ' consts['command_prefix'] = '+ '
magic_fail_string = b'lkmc_test_fail' consts['magic_fail_string'] = b'lkmc_test_fail'
class LkmcCliFunction(cli_function.CliFunction): class LkmcCliFunction(cli_function.CliFunction):
''' '''
Common functionality shared across our CLI functions: Common functionality shared across our CLI functions:
* command timing * command timing
* some common flags, e.g.: --arch, --dry-run * some common flags, e.g.: --arch, --dry-run, --verbose
''' '''
def get_arguments(self): def __init__(self):
return [ super().__init__(config_file=common.consts['config_file'])
cli_function.Argument( self.add_argument(
longname='--dry-run', '-a', '--arch', choices=common.arch_choices, default=common.default_arch,
default=False, help='CPU architecture. Default: %(default)s'
help='''\ )
self.add_argument(
'--dry-run',
default=False,
help='''\
Print the commands that would be run, but don't run them. Print the commands that would be run, but don't run them.
We aim display every command that modifies the filesystem state, and generate We aim display every command that modifies the filesystem state, and generate
@@ -102,14 +110,15 @@ Bash equivalents even for actions taken directly in Python without shelling out.
mkdir are generally omitted since those are obvious mkdir are generally omitted since those are obvious
''' '''
) )
] self.add_argument(
'-v', '--verbose', default=False, action='store_true',
help='Show full compilation commands when they are not shown by default.'
)
def main(self, **kwargs): def main(self, **kwargs):
''' '''
Parse CLI, and to the build based on it. Time the main of the derived class.
The actual build work is done by timed_main in implementing classes.
''' '''
if not kwargs['dry_run']: if not kwargs['dry_run']:
start_time = time.time() start_time = time.time()
@@ -128,40 +137,33 @@ class BuildCliFunction(LkmcCliFunction):
* `--clean` to clean the build directory * `--clean` to clean the build directory
* `--nproc` to set he number of build threads * `--nproc` to set he number of build threads
''' '''
def __init__(self):
super().__init__()
self.add_argument(
'--clean',
default=False,
help='Clean the build instead of building.',
),
self.add_argument(
'-j',
'--nproc',
default=multiprocessing.cpu_count(),
type=int,
help='Number of processors to use for the build. Default: use all cores.',
)
def clean(self, **kwargs): def clean(self, **kwargs):
build_dir = self.get_build_dir(kwargs) build_dir = self.get_build_dir(kwargs)
if build_dir is not None: if build_dir is not None:
common.rmrf(build_dir) common.rmrf(build_dir)
def get_arguments(self): def build(self, **kwargs):
return super().get_arguments() + [
cli_function.Argument(
longname='--clean',
default=False,
help='Clean the build instead of building.',
),
cli_function.Argument(
shortname='-j',
longname='--nproc',
default=multiprocessing.cpu_count(),
type=int,
help='Number of processors to use for the build. Default: use all cores.',
),
] + self.do_get_arguments()
def do_get_arguments(self):
return []
def do_main(self, **kwargs):
''' '''
Do the actual main build work. Do the actual main build work.
''' '''
raise NotImplementedError() raise NotImplementedError()
def get_build_dir(self, **kwargs): def get_build_dir(self, **kwargs):
'''
Build directory, gets cleaned by --clean if not None.
'''
return None return None
def timed_main(self, **kwargs): def timed_main(self, **kwargs):
@@ -173,12 +175,12 @@ class BuildCliFunction(LkmcCliFunction):
if kwargs['clean']: if kwargs['clean']:
self.clean(kwargs) self.clean(kwargs)
else: else:
self.do_main(**kwargs) self.build(**kwargs)
class Newline: class Newline:
''' '''
Singleton class. Can be used in print_cmd to print out nicer command lines Singleton class. Can be used in print_cmd to print out nicer command lines
with -key on the same line as "-key value". with --key on the same line as "--key value".
''' '''
pass pass
@@ -277,12 +279,7 @@ def get_argparse(default_args=None):
default_args = {} default_args = {}
if argparse_args is None: if argparse_args is None:
argparse_args = {} argparse_args = {}
common.add_dry_run_argument(parser)
emulator_group = parser.add_mutually_exclusive_group(required=False) emulator_group = parser.add_mutually_exclusive_group(required=False)
parser.add_argument(
'-a', '--arch', choices=common.arch_choices, default=common.default_arch,
help='CPU architecture. Default: %(default)s'
)
parser.add_argument( parser.add_argument(
'-b', '--baremetal', '-b', '--baremetal',
help='''\ help='''\
@@ -396,10 +393,6 @@ to allow overriding configs from the CLI.
parser.add_argument( parser.add_argument(
'--userland-build-id', default=None '--userland-build-id', default=None
) )
parser.add_argument(
'-v', '--verbose', default=False, action='store_true',
help='Show full compilation commands when they are not shown by default.'
)
def get_elf_entry(elf_file_path): def get_elf_entry(elf_file_path):
readelf_header = subprocess.check_output([ readelf_header = subprocess.check_output([
@@ -448,7 +441,7 @@ def get_toolchain_prefix(tool, allowed_toolchains=None):
'host': (host_exists, host_full_prefix), 'host': (host_exists, host_full_prefix),
} }
if allowed_toolchains is None: if allowed_toolchains is None:
if common.baremetal is None: if common['baremetal'] is None:
allowed_toolchains = ['buildroot', 'crosstool-ng', 'host'] allowed_toolchains = ['buildroot', 'crosstool-ng', 'host']
else: else:
allowed_toolchains = ['crosstool-ng', 'buildroot', 'host'] allowed_toolchains = ['crosstool-ng', 'buildroot', 'host']
@@ -700,15 +693,14 @@ def run_cmd(
else: else:
return 0 return 0
def setup(parser): def calculate_kwargs(**kwargs):
''' '''
Parse the command line arguments, and setup several variables based on them. Update the kwargs from the command line with derived arguments.
Typically done after getting inputs from the command line arguments.
''' '''
if args.qemu or not args.gem5: if args.qemu or not args.gem5:
common.emulator = 'qemu' common['emulator'] = 'qemu'
else: else:
common.emulator = 'gem5' common['emulator'] = 'gem5'
if args.arch in common.arch_short_to_long_dict: if args.arch in common.arch_short_to_long_dict:
args.arch = common.arch_short_to_long_dict[args.arch] args.arch = common.arch_short_to_long_dict[args.arch]
if args.gem5_build_id is None: if args.gem5_build_id is None:
@@ -723,56 +715,56 @@ def setup(parser):
common.userland_build_id_given = True common.userland_build_id_given = True
if args.gem5_worktree is not None and not gem5_build_id_given: if args.gem5_worktree is not None and not gem5_build_id_given:
args.gem5_build_id = args.gem5_worktree args.gem5_build_id = args.gem5_worktree
common.machine = args.machine common['machine'] = args.machine
common.setup_dry_run_arguments(args) common.setup_dry_run_arguments(args)
common.is_arm = False common.is_arm = False
if args.arch == 'arm': if args.arch == 'arm':
common.armv = 7 common['armv'] = 7
common.gem5_arch = 'ARM' common.gem5_arch = 'ARM'
common.mcpu = 'cortex-a15' common['mcpu'] = 'cortex-a15'
common.buildroot_toolchain_prefix = 'arm-buildroot-linux-uclibcgnueabihf' common.buildroot_toolchain_prefix = 'arm-buildroot-linux-uclibcgnueabihf'
common.crosstool_ng_toolchain_prefix = 'arm-unknown-eabi' common.crosstool_ng_toolchain_prefix = 'arm-unknown-eabi'
common.ubuntu_toolchain_prefix = 'arm-linux-gnueabihf' common.ubuntu_toolchain_prefix = 'arm-linux-gnueabihf'
if common.emulator == 'gem5': if common['emulator'] == 'gem5':
if common.machine is None: if common['machine'] is None:
common.machine = 'VExpress_GEM5_V1' common['machine'] = 'VExpress_GEM5_V1'
else: else:
if common.machine is None: if common['machine'] is None:
common.machine = 'virt' common['machine'] = 'virt'
common.is_arm = True common.is_arm = True
elif args.arch == 'aarch64': elif args.arch == 'aarch64':
common.armv = 8 common['armv'] = 8
common.gem5_arch = 'ARM' common.gem5_arch = 'ARM'
common.mcpu = 'cortex-a57' common['mcpu'] = 'cortex-a57'
common.buildroot_toolchain_prefix = 'aarch64-buildroot-linux-uclibc' common.buildroot_toolchain_prefix = 'aarch64-buildroot-linux-uclibc'
common.crosstool_ng_toolchain_prefix = 'aarch64-unknown-elf' common.crosstool_ng_toolchain_prefix = 'aarch64-unknown-elf'
common.ubuntu_toolchain_prefix = 'aarch64-linux-gnu' common.ubuntu_toolchain_prefix = 'aarch64-linux-gnu'
if common.emulator == 'gem5': if common['emulator'] == 'gem5':
if common.machine is None: if common['machine'] is None:
common.machine = 'VExpress_GEM5_V1' common['machine'] = 'VExpress_GEM5_V1'
else: else:
if common.machine is None: if common['machine'] is None:
common.machine = 'virt' common['machine'] = 'virt'
common.is_arm = True common.is_arm = True
elif args.arch == 'x86_64': elif args.arch == 'x86_64':
common.crosstool_ng_toolchain_prefix = 'x86_64-unknown-elf' common.crosstool_ng_toolchain_prefix = 'x86_64-unknown-elf'
common.gem5_arch = 'X86' common.gem5_arch = 'X86'
common.buildroot_toolchain_prefix = 'x86_64-buildroot-linux-uclibc' common.buildroot_toolchain_prefix = 'x86_64-buildroot-linux-uclibc'
common.ubuntu_toolchain_prefix = 'x86_64-linux-gnu' common.ubuntu_toolchain_prefix = 'x86_64-linux-gnu'
if common.emulator == 'gem5': if common['emulator'] == 'gem5':
if common.machine is None: if common['machine'] is None:
common.machine = 'TODO' common['machine'] = 'TODO'
else: else:
if common.machine is None: if common['machine'] is None:
common.machine = 'pc' common['machine'] = 'pc'
common.buildroot_out_dir = os.path.join(common.out_dir, 'buildroot') common.buildroot_out_dir = os.path.join(consts['out_dir'], 'buildroot')
common.buildroot_build_dir = os.path.join(common.buildroot_out_dir, 'build', args.buildroot_build_id, args.arch) common.buildroot_build_dir = os.path.join(common.buildroot_out_dir, 'build', args.buildroot_build_id, args.arch)
common.buildroot_download_dir = os.path.join(common.buildroot_out_dir, 'download') common.buildroot_download_dir = os.path.join(common.buildroot_out_dir, 'download')
common.buildroot_config_file = os.path.join(common.buildroot_build_dir, '.config') common.buildroot_config_file = os.path.join(common.buildroot_build_dir, '.config')
common.buildroot_build_build_dir = os.path.join(common.buildroot_build_dir, 'build') common.buildroot_build_build_dir = os.path.join(common.buildroot_build_dir, 'build')
common.buildroot_linux_build_dir = os.path.join(common.buildroot_build_build_dir, 'linux-custom') common.buildroot_linux_build_dir = os.path.join(common.buildroot_build_build_dir, 'linux-custom')
common.buildroot_vmlinux = os.path.join(common.buildroot_linux_build_dir, "vmlinux") common.buildroot_vmlinux = os.path.join(common.buildroot_linux_build_dir, "vmlinux")
common.qemu_build_dir = os.path.join(common.out_dir, 'qemu', args.qemu_build_id) common.qemu_build_dir = os.path.join(consts['out_dir'], 'qemu', args.qemu_build_id)
common.qemu_executable_basename = 'qemu-system-{}'.format(args.arch) common.qemu_executable_basename = 'qemu-system-{}'.format(args.arch)
common.qemu_executable = os.path.join(common.qemu_build_dir, '{}-softmmu'.format(args.arch), common.qemu_executable_basename) common.qemu_executable = os.path.join(common.qemu_build_dir, '{}-softmmu'.format(args.arch), common.qemu_executable_basename)
common.qemu_img_basename = 'qemu-img' common.qemu_img_basename = 'qemu-img'
@@ -783,10 +775,10 @@ def setup(parser):
common.buildroot_images_dir = os.path.join(common.buildroot_build_dir, 'images') common.buildroot_images_dir = os.path.join(common.buildroot_build_dir, 'images')
common.buildroot_rootfs_raw_file = os.path.join(common.buildroot_images_dir, 'rootfs.ext2') common.buildroot_rootfs_raw_file = os.path.join(common.buildroot_images_dir, 'rootfs.ext2')
common.buildroot_qcow2_file = common.buildroot_rootfs_raw_file + '.qcow2' common.buildroot_qcow2_file = common.buildroot_rootfs_raw_file + '.qcow2'
common.staging_dir = os.path.join(common.out_dir, 'staging', args.arch) common.staging_dir = os.path.join(consts['out_dir'], 'staging', args.arch)
common.buildroot_staging_dir = os.path.join(common.buildroot_build_dir, 'staging') common.buildroot_staging_dir = os.path.join(common.buildroot_build_dir, 'staging')
common.target_dir = os.path.join(common.buildroot_build_dir, 'target') common.target_dir = os.path.join(common.buildroot_build_dir, 'target')
common.run_dir_base = os.path.join(common.out_dir, 'run') common.run_dir_base = os.path.join(consts['out_dir'], 'run')
common.gem5_run_dir = os.path.join(common.run_dir_base, 'gem5', args.arch, str(args.run_id)) common.gem5_run_dir = os.path.join(common.run_dir_base, 'gem5', args.arch, str(args.run_id))
common.m5out_dir = os.path.join(common.gem5_run_dir, 'm5out') common.m5out_dir = os.path.join(common.gem5_run_dir, 'm5out')
common.stats_file = os.path.join(common.m5out_dir, 'stats.txt') common.stats_file = os.path.join(common.m5out_dir, 'stats.txt')
@@ -801,7 +793,7 @@ def setup(parser):
common.qemu_termout_file = os.path.join(common.qemu_run_dir, 'termout.txt') common.qemu_termout_file = os.path.join(common.qemu_run_dir, 'termout.txt')
common.qemu_rrfile = os.path.join(common.qemu_run_dir, 'rrfile') common.qemu_rrfile = os.path.join(common.qemu_run_dir, 'rrfile')
common.qemu_guest_terminal_file = os.path.join(common.m5out_dir, qemu_termout_file) common.qemu_guest_terminal_file = os.path.join(common.m5out_dir, qemu_termout_file)
common.gem5_out_dir = os.path.join(common.out_dir, 'gem5') common.gem5_out_dir = os.path.join(consts['out_dir'], 'gem5')
if args.gem5_build_dir is None: if args.gem5_build_dir is None:
common.gem5_build_dir = os.path.join(common.gem5_out_dir, args.gem5_build_id, args.gem5_build_type) common.gem5_build_dir = os.path.join(common.gem5_out_dir, args.gem5_build_id, args.gem5_build_type)
else: else:
@@ -811,7 +803,7 @@ def setup(parser):
common.gem5_build_build_dir = os.path.join(common.gem5_build_dir, 'build') common.gem5_build_build_dir = os.path.join(common.gem5_build_dir, 'build')
common.gem5_executable = os.path.join(common.gem5_build_build_dir, gem5_arch, 'gem5.{}'.format(args.gem5_build_type)) common.gem5_executable = os.path.join(common.gem5_build_build_dir, gem5_arch, 'gem5.{}'.format(args.gem5_build_type))
common.gem5_system_dir = os.path.join(common.gem5_build_dir, 'system') common.gem5_system_dir = os.path.join(common.gem5_build_dir, 'system')
common.crosstool_ng_out_dir = os.path.join(common.out_dir, 'crosstool-ng') common.crosstool_ng_out_dir = os.path.join(consts['out_dir'], 'crosstool-ng')
common.crosstool_ng_buildid_dir = os.path.join(common.crosstool_ng_out_dir, 'build', args.crosstool_ng_build_id) common.crosstool_ng_buildid_dir = os.path.join(common.crosstool_ng_out_dir, 'build', args.crosstool_ng_build_id)
common.crosstool_ng_install_dir = os.path.join(common.crosstool_ng_buildid_dir, 'install', args.arch) common.crosstool_ng_install_dir = os.path.join(common.crosstool_ng_buildid_dir, 'install', args.arch)
common.crosstool_ng_bin_dir = os.path.join(common.crosstool_ng_install_dir, 'bin') common.crosstool_ng_bin_dir = os.path.join(common.crosstool_ng_install_dir, 'bin')
@@ -831,15 +823,15 @@ def setup(parser):
else: else:
common.gem5_src_dir = common.gem5_default_src_dir common.gem5_src_dir = common.gem5_default_src_dir
common.gem5_m5_src_dir = os.path.join(common.gem5_src_dir, 'util', 'm5') common.gem5_m5_src_dir = os.path.join(common.gem5_src_dir, 'util', 'm5')
common.gem5_m5_build_dir = os.path.join(common.out_dir, 'util', 'm5') common.gem5_m5_build_dir = os.path.join(consts['out_dir'], 'util', 'm5')
if common.emulator == 'gem5': if common['emulator'] == 'gem5':
common.executable = common.gem5_executable common['executable'] = common.gem5_executable
common.run_dir = common.gem5_run_dir common.run_dir = common.gem5_run_dir
common.termout_file = common.gem5_termout_file common.termout_file = common.gem5_termout_file
common.guest_terminal_file = gem5_guest_terminal_file common.guest_terminal_file = gem5_guest_terminal_file
common.trace_txt_file = gem5_trace_txt_file common.trace_txt_file = gem5_trace_txt_file
else: else:
common.executable = common.qemu_executable common['executable'] = common.qemu_executable
common.run_dir = common.qemu_run_dir common.run_dir = common.qemu_run_dir
common.termout_file = common.qemu_termout_file common.termout_file = common.qemu_termout_file
common.guest_terminal_file = qemu_guest_terminal_file common.guest_terminal_file = qemu_guest_terminal_file
@@ -851,7 +843,7 @@ def setup(parser):
# Linux # Linux
common.linux_buildroot_build_dir = os.path.join(common.buildroot_build_build_dir, 'linux-custom') common.linux_buildroot_build_dir = os.path.join(common.buildroot_build_build_dir, 'linux-custom')
common.linux_build_dir = os.path.join(common.out_dir, 'linux', args.linux_build_id, args.arch) common.linux_build_dir = os.path.join(consts['out_dir'], 'linux', args.linux_build_id, args.arch)
common.lkmc_vmlinux = os.path.join(common.linux_build_dir, "vmlinux") common.lkmc_vmlinux = os.path.join(common.linux_build_dir, "vmlinux")
if args.arch == 'arm': if args.arch == 'arm':
common.linux_arch = 'arm' common.linux_arch = 'arm'
@@ -865,20 +857,20 @@ def setup(parser):
common.lkmc_linux_image = os.path.join(common.linux_build_dir, common.linux_image_prefix) common.lkmc_linux_image = os.path.join(common.linux_build_dir, common.linux_image_prefix)
common.buildroot_linux_image = os.path.join(common.buildroot_linux_build_dir, linux_image_prefix) common.buildroot_linux_image = os.path.join(common.buildroot_linux_build_dir, linux_image_prefix)
if args.buildroot_linux: if args.buildroot_linux:
common.vmlinux = common.buildroot_vmlinux common['vmlinux'] = common.buildroot_vmlinux
common.linux_image = common.buildroot_linux_image common.linux_image = common.buildroot_linux_image
else: else:
common.vmlinux = common.lkmc_vmlinux common['vmlinux'] = common.lkmc_vmlinux
common.linux_image = common.lkmc_linux_image common.linux_image = common.lkmc_linux_image
# Kernel modules. # Kernel modules.
common.kernel_modules_build_base_dir = os.path.join(common.out_dir, 'kernel_modules') common.kernel_modules_build_base_dir = os.path.join(consts['out_dir'], 'kernel_modules')
common.kernel_modules_build_dir = os.path.join(common.kernel_modules_build_base_dir, args.arch) common.kernel_modules_build_dir = os.path.join(common.kernel_modules_build_base_dir, args.arch)
common.kernel_modules_build_subdir = os.path.join(common.kernel_modules_build_dir, kernel_modules_subdir) common.kernel_modules_build_subdir = os.path.join(common.kernel_modules_build_dir, kernel_modules_subdir)
common.kernel_modules_build_host_dir = os.path.join(common.kernel_modules_build_base_dir, 'host') common.kernel_modules_build_host_dir = os.path.join(common.kernel_modules_build_base_dir, 'host')
common.kernel_modules_build_host_subdir = os.path.join(common.kernel_modules_build_host_dir, kernel_modules_subdir) common.kernel_modules_build_host_subdir = os.path.join(common.kernel_modules_build_host_dir, kernel_modules_subdir)
common.userland_build_dir = os.path.join(common.out_dir, 'userland', args.userland_build_id, args.arch) common.userland_build_dir = os.path.join(consts['out_dir'], 'userland', args.userland_build_id, args.arch)
common.out_rootfs_overlay_dir = os.path.join(common.out_dir, 'rootfs_overlay', args.arch) common.out_rootfs_overlay_dir = os.path.join(consts['out_dir'], 'rootfs_overlay', args.arch)
common.out_rootfs_overlay_bin_dir = os.path.join(common.out_rootfs_overlay_dir, 'bin') common.out_rootfs_overlay_bin_dir = os.path.join(common.out_rootfs_overlay_dir, 'bin')
# Ports # Ports
@@ -887,7 +879,7 @@ def setup(parser):
args.port_offset = int(args.run_id) args.port_offset = int(args.run_id)
except ValueError: except ValueError:
args.port_offset = 0 args.port_offset = 0
if common.emulator == 'gem5': if common['emulator'] == 'gem5':
common.gem5_telnet_port = 3456 + args.port_offset common.gem5_telnet_port = 3456 + args.port_offset
common.gdb_port = 7000 + args.port_offset common.gdb_port = 7000 + args.port_offset
else: else:
@@ -901,20 +893,20 @@ def setup(parser):
common.qemu_background_serial_file = os.path.join(common.qemu_run_dir, 'background.log') common.qemu_background_serial_file = os.path.join(common.qemu_run_dir, 'background.log')
# Baremetal. # Baremetal.
common.baremetal = args.baremetal common['baremetal'] = args.baremetal
common.baremetal_lib_basename = 'lib' common.baremetal_lib_basename = 'lib'
common.baremetal_src_dir = os.path.join(common.root_dir, 'baremetal') common.baremetal_src_dir = os.path.join(consts['root_dir'], 'baremetal')
common.baremetal_src_lib_dir = os.path.join(common.baremetal_src_dir, common.baremetal_lib_basename) common.baremetal_src_lib_dir = os.path.join(common.baremetal_src_dir, common.baremetal_lib_basename)
if common.emulator == 'gem5': if common['emulator'] == 'gem5':
common.simulator_name = 'gem5' common.simulator_name = 'gem5'
else: else:
common.simulator_name = 'qemu' common.simulator_name = 'qemu'
common.baremetal_build_dir = os.path.join(out_dir, 'baremetal', args.arch, common.simulator_name, common.machine) common.baremetal_build_dir = os.path.join(out_dir, 'baremetal', args.arch, common.simulator_name, common['machine'])
common.baremetal_build_lib_dir = os.path.join(common.baremetal_build_dir, common.baremetal_lib_basename) common.baremetal_build_lib_dir = os.path.join(common.baremetal_build_dir, common.baremetal_lib_basename)
common.baremetal_build_ext = '.elf' common.baremetal_build_ext = '.elf'
# Docker # Docker
common.docker_build_dir = os.path.join(common.out_dir, 'docker', args.arch) common.docker_build_dir = os.path.join(consts['out_dir'], 'docker', args.arch)
common.docker_tar_dir = os.path.join(common.docker_build_dir, 'export') common.docker_tar_dir = os.path.join(common.docker_build_dir, 'export')
common.docker_tar_file = os.path.join(common.docker_build_dir, 'export.tar') common.docker_tar_file = os.path.join(common.docker_build_dir, 'export.tar')
common.docker_rootfs_raw_file = os.path.join(common.docker_build_dir, 'export.ext2') common.docker_rootfs_raw_file = os.path.join(common.docker_build_dir, 'export.ext2')
@@ -927,20 +919,20 @@ def setup(parser):
common.qcow2_file = common.buildroot_qcow2_file common.qcow2_file = common.buildroot_qcow2_file
# Image. # Image.
if common.baremetal is None: if common['baremetal'] is None:
if common.emulator == 'gem5': if common['emulator'] == 'gem5':
common.image = common.vmlinux common['image'] = common['vmlinux']
common.disk_image = common.rootfs_raw_file common.disk_image = common.rootfs_raw_file
else: else:
common.image = common.linux_image common['image'] = common.linux_image
common.disk_image = common.qcow2_file common.disk_image = common.qcow2_file
else: else:
common.disk_image = common.gem5_fake_iso common.disk_image = common.gem5_fake_iso
if common.baremetal == 'all': if common['baremetal'] == 'all':
path = common.baremetal path = common['baremetal']
else: else:
path = common.resolve_executable( path = common.resolve_executable(
common.baremetal, common['baremetal'],
common.baremetal_src_dir, common.baremetal_src_dir,
common.baremetal_build_dir, common.baremetal_build_dir,
common.baremetal_build_ext, common.baremetal_build_ext,
@@ -954,7 +946,7 @@ def setup(parser):
if os.path.exists(source_path): if os.path.exists(source_path):
common.source_path = source_path common.source_path = source_path
break break
common.image = path common['image'] = path
return args return args
def resolve_executable(in_path, magic_in_dir, magic_out_dir, out_ext): def resolve_executable(in_path, magic_in_dir, magic_out_dir, out_ext):