Files
linux-kernel-module-cheat/build-baremetal
Ciro Santilli 六四事件 法轮功 26b890f42f Factor common userland and baremetal C functions
This allows add.c to run unmodified on both!

For that to work, use int main on baremetal, and pass the return value to
the final exit.
2018-11-15 20:07:47 +00:00

175 lines
6.6 KiB
Python
Executable File

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