mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-25 03:01:36 +01:00
test-baremetal: fix missing setting x0 return value Examples were just returning on ret without setting x0, which led to failures... those were not noticed because of how broken the testing system was ;-)
164 lines
6.7 KiB
Python
Executable File
164 lines
6.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import os
|
|
|
|
import common
|
|
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')
|
|
|
|
def build(self):
|
|
build_dir = self.get_build_dir()
|
|
bootloader_obj = os.path.join(
|
|
self.env['baremetal_build_lib_dir'],
|
|
'bootloader{}'.format(self.env['obj_ext'])
|
|
)
|
|
common_obj = 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']
|
|
)
|
|
common_objs = [common_obj, syscalls_obj]
|
|
cflags = [
|
|
'-I', self.env['baremetal_source_lib_dir'], LF,
|
|
'-I', self.env['root_dir'], LF,
|
|
'-O{}'.format(self.env['optimization_level']), LF,
|
|
'-ggdb3', LF,
|
|
'-mcpu={}'.format(self.env['mcpu']), LF,
|
|
'-nostartfiles', LF,
|
|
]
|
|
if self.env['arch'] == 'arm':
|
|
cflags.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,
|
|
])
|
|
cflags_after = ['-lm']
|
|
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'])
|
|
cflags.extend([
|
|
'-D', 'GEM5'.format(uart_address), LF,
|
|
'-DLKMC_M5OPS_ENABLE=1', LF,
|
|
])
|
|
else:
|
|
entry_address = 0x40000000
|
|
uart_address = 0x09000000
|
|
os.makedirs(build_dir, exist_ok=True)
|
|
os.makedirs(self.env['baremetal_build_lib_dir'], exist_ok=True)
|
|
src = os.path.join(
|
|
self.env['baremetal_source_lib_dir'],
|
|
'{}{}'.format(
|
|
self.env['arch'],
|
|
self.env['asm_ext']
|
|
)
|
|
)
|
|
cflags.extend(self.sh.shlex_split(self.env['ccflags']))
|
|
if self.need_rebuild([src], bootloader_obj):
|
|
self.sh.run_cmd(
|
|
[self.env['gcc'], LF] +
|
|
cflags +
|
|
[
|
|
'-c', LF,
|
|
'-o', bootloader_obj, LF,
|
|
src, LF,
|
|
] +
|
|
cflags_after
|
|
)
|
|
for src, obj in [
|
|
(self.env['common_c'], common_obj),
|
|
(syscalls_src, syscalls_obj),
|
|
]:
|
|
if self.need_rebuild([src, self.env['common_h']], obj):
|
|
self.sh.run_cmd(
|
|
[self.env['gcc'], LF] +
|
|
cflags +
|
|
[
|
|
'-D', 'UART0_ADDR={:#x}'.format(uart_address), LF,
|
|
'-c', LF,
|
|
'-o', obj, LF,
|
|
src, LF,
|
|
] +
|
|
cflags_after
|
|
)
|
|
for subpath in [
|
|
'',
|
|
'interactive',
|
|
self.env['baremetal_source_arch_subpath'],
|
|
os.path.join(self.env['baremetal_source_arch_subpath'], 'no_bootloader'),
|
|
]:
|
|
in_dir = os.path.join(self.env['baremetal_source_dir'], subpath)
|
|
if os.path.isdir(in_dir):
|
|
out_dir = os.path.join(self.env['baremetal_build_dir'], subpath)
|
|
os.makedirs(out_dir, exist_ok=True)
|
|
common_objs_bootloader = common_objs.copy()
|
|
if os.path.basename(subpath) != 'no_bootloader':
|
|
common_objs_bootloader.append(bootloader_obj)
|
|
for in_basename in sorted(os.listdir(in_dir)):
|
|
in_path = os.path.join(in_dir, in_basename)
|
|
in_name, in_ext = os.path.splitext(in_basename)
|
|
if (
|
|
os.path.isfile(in_path) and
|
|
in_ext in (self.env['c_ext'], self.env['asm_ext'])
|
|
):
|
|
out = os.path.join(out_dir, in_name + self.env['baremetal_build_ext'])
|
|
print(out)
|
|
if self.need_rebuild(
|
|
common_objs_bootloader + [self.env['baremetal_link_script'] + self.env['common_h']],
|
|
out
|
|
):
|
|
self.sh.run_cmd(
|
|
[self.env['gcc'], LF] +
|
|
cflags +
|
|
[
|
|
'-Wl,--section-start=.text={:#x}'.format(entry_address), LF,
|
|
'-o', out, LF,
|
|
'-T', self.env['baremetal_link_script'], LF,
|
|
] +
|
|
[
|
|
os.path.join(self.env['baremetal_source_dir'], in_path), LF,
|
|
] +
|
|
self.sh.add_newlines(common_objs_bootloader) +
|
|
cflags_after
|
|
)
|
|
|
|
def get_build_dir(self):
|
|
return self.env['baremetal_build_dir']
|
|
|
|
if __name__ == '__main__':
|
|
Main().cli()
|