mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-22 17:55:57 +01:00
--quit-after-boot: fix for gem5, update path to gem5.sh Improve the printing of results and errors: - remove newlines from IDs at the end for ./test-boot - remove newlines from progress for __call__ commands and don't print executed commands at all, otherwise there are too many lines per test and it is hard to tell what is going on - print backtraces for any exception in the threads (bugs while developing this code) Tests across different archs and emulators are still not running in parallel, which is a huge loss. TODO. thread_pool: introduce with API. This was motivate by test-boot, I've had enough of doing separate error handling for each loop type! Greatly dries up the code, awesome. common: make --all-emulators work properly with native hopefully for the last time, ./test-baremetal was still failing. gem5: don't pass --command-line for baremetal. Maybe later we can use it to actually pass command line arguments to main()? To be seen.
146 lines
5.8 KiB
Python
Executable File
146 lines
5.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import os
|
|
|
|
import common
|
|
import thread_pool
|
|
from shell_helpers import LF
|
|
|
|
class Main(common.BuildCliFunction):
|
|
def __init__(self):
|
|
super().__init__(
|
|
defaults={
|
|
'gcc_which':'crosstool-ng',
|
|
},
|
|
description='''\
|
|
Build the baremetal examples with crosstool-NG.
|
|
''',
|
|
supported_archs=common.consts['crosstool_ng_supported_archs']
|
|
)
|
|
self._add_argument('--ccflags')
|
|
self._add_argument('--force-rebuild')
|
|
self._add_argument('--optimization-level')
|
|
self.add_argument(
|
|
'targets',
|
|
default=[],
|
|
help='Analogous to ./build-userland target selection',
|
|
nargs='*',
|
|
)
|
|
|
|
def build(self):
|
|
build_dir = self.get_build_dir()
|
|
extra_obj_baremetal_bootloader = os.path.join(
|
|
self.env['baremetal_build_lib_dir'],
|
|
'bootloader{}'.format(self.env['obj_ext'])
|
|
)
|
|
extra_obj_lkmc_common = os.path.join(
|
|
self.env['baremetal_build_lib_dir'],
|
|
self.env['common_basename_noext'] + self.env['obj_ext']
|
|
)
|
|
syscalls_basename_noext = 'syscalls'
|
|
syscalls_src = os.path.join(
|
|
self.env['baremetal_source_lib_dir'],
|
|
syscalls_basename_noext + self.env['c_ext']
|
|
)
|
|
syscalls_obj = os.path.join(
|
|
self.env['baremetal_build_lib_dir'],
|
|
syscalls_basename_noext + self.env['obj_ext']
|
|
)
|
|
cc_flags = [
|
|
'-I', self.env['root_dir'], LF,
|
|
'-O{}'.format(self.env['optimization_level']), LF,
|
|
'-mcpu={}'.format(self.env['mcpu']), LF,
|
|
'-nostartfiles', LF,
|
|
]
|
|
if self.env['arch'] == 'arm':
|
|
cc_flags.extend([
|
|
'-mhard-float', LF,
|
|
# This uses the soft float ABI for calling functions from objets in Newlib which
|
|
# our crosstool-NG config compiles with soft floats, while emiting hard float
|
|
# from C and allowing us to use it from assembly, e.g. for the VMRS instruction:
|
|
# which would otherwise fail "with selected processor does not support XXX in ARM mode"
|
|
# Bibliography:
|
|
# - https://stackoverflow.com/questions/9753749/arm-compilation-error-vfp-registered-used-by-executable-not-object-file
|
|
# - https://stackoverflow.com/questions/41131432/cross-compiling-error-selected-processor-does-not-support-fmrx-r3-fpexc-in/41131782#41131782
|
|
# - https://embeddedartistry.com/blog/2017/10/9/r1q7pksku2q3gww9rpqef0dnskphtc
|
|
'-mfloat-abi=softfp', LF,
|
|
'-mfpu=crypto-neon-fp-armv8', LF,
|
|
])
|
|
if self.env['emulator'] == 'gem5':
|
|
if self.env['machine'] == 'VExpress_GEM5_V1':
|
|
entry_address = 0x80000000
|
|
uart_address = 0x1c090000
|
|
elif self.env['machine'] == 'RealViewPBX':
|
|
entry_address = 0x10000
|
|
uart_address = 0x10009000
|
|
else:
|
|
raise Exception('unknown machine: ' + self.env['machine'])
|
|
cc_flags.extend([
|
|
'-DLKMC_GEM5=1', LF,
|
|
'-DLKMC_M5OPS_ENABLE=1', LF,
|
|
])
|
|
else:
|
|
entry_address = 0x40000000
|
|
uart_address = 0x09000000
|
|
cc_flags.extend(['-D', 'LKMC_UART0_ADDR={:#x}'.format(uart_address), LF])
|
|
cc_flags.extend(self.sh.shlex_split(self.env['ccflags']))
|
|
bootloader_src = os.path.join(
|
|
self.env['baremetal_source_lib_dir'],
|
|
'{}{}'.format(
|
|
self.env['arch'],
|
|
self.env['asm_ext']
|
|
)
|
|
)
|
|
for in_path, out_path in [
|
|
(bootloader_src, extra_obj_baremetal_bootloader),
|
|
(self.env['common_c'], extra_obj_lkmc_common),
|
|
(syscalls_src, syscalls_obj),
|
|
]:
|
|
self._build_one(
|
|
in_path=in_path,
|
|
out_path=out_path,
|
|
cc_flags=cc_flags,
|
|
extra_deps=[self.env['common_h']],
|
|
link=False,
|
|
)
|
|
cc_flags.extend([
|
|
'-Wl,--section-start=.text={:#x}'.format(entry_address), LF,
|
|
'-T', self.env['baremetal_link_script'], LF,
|
|
])
|
|
with thread_pool.ThreadPool(
|
|
self._build_one,
|
|
nthreads=self.env['nproc'],
|
|
submit_raise_exit=self.env['quit_on_fail'],
|
|
) as my_thread_pool:
|
|
for target in self.env['targets']:
|
|
for path, in_dirnames, in_filenames in self.sh.walk(target):
|
|
for in_filename in in_filenames:
|
|
in_ext = os.path.splitext(in_filename)[1]
|
|
if not in_ext in self.env['build_in_exts']:
|
|
continue
|
|
in_path = os.path.join(path, in_filename)
|
|
my_thread_pool.submit({
|
|
'cc_flags': cc_flags,
|
|
'extra_deps': [
|
|
self.env['baremetal_link_script'],
|
|
self.env['common_h']
|
|
],
|
|
'extra_objs': [syscalls_obj],
|
|
'extra_objs_baremetal_bootloader': [extra_obj_baremetal_bootloader],
|
|
'extra_objs_lkmc_common': [extra_obj_lkmc_common],
|
|
'in_path': in_path,
|
|
'out_path': self.resolve_baremetal_executable(in_path),
|
|
})
|
|
return self._handle_thread_pool_errors(my_thread_pool)
|
|
|
|
def get_build_dir(self):
|
|
return self.env['baremetal_build_dir']
|
|
|
|
def setup_one(self):
|
|
self.env['targets'] = self.resolve_targets(
|
|
self.env['baremetal_source_dir'],
|
|
self.env['targets']
|
|
)
|
|
|
|
if __name__ == '__main__':
|
|
Main().cli()
|