Files
linux-kernel-module-cheat/build-baremetal
Ciro Santilli 六四事件 法轮功 26cab92bfc baremetal: allow arbitrary exit status with the magic string
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 ;-)
2019-05-06 00:00:01 +00:00

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()