Files
linux-kernel-module-cheat/build-baremetal
Ciro Santilli 六四事件 法轮功 a8b6f758ba split --prebuilt and --host into --gcc-which and --qemu-which
Only one --host exists at ./build-modules, since that can select the host
kernel, which is independent from the toolchain.

Document that user mode simulation stopped working.
2019-02-16 00:00:00 +00:00

174 lines
6.6 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']
)
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_basename_noext = 'common'
common_src = os.path.join(self.env['root_dir'], common_basename_noext + self.env['c_ext'])
common_obj = os.path.join(self.env['baremetal_build_lib_dir'], 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,
'-O0', LF,
'-ggdb3', LF,
'-mcpu={}'.format(self.env['mcpu']), LF,
'-nostartfiles', LF,
]
gcc = self.get_toolchain_tool('gcc')
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])
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']))
if self.need_rebuild([src], bootloader_obj):
self.sh.run_cmd(
[gcc, LF] +
cflags +
[
'-c', LF,
'-o', bootloader_obj, LF,
src, LF,
]
)
for src, obj in [
(common_src, common_obj),
(syscalls_src, syscalls_obj),
]:
if self.need_rebuild([src], obj):
self.sh.run_cmd(
[gcc, LF] +
cflags +
[
'-c', LF,
'-D', 'UART0_ADDR={:#x}'.format(uart_address), LF,
'-o', obj, LF,
src, LF,
]
)
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,
)
if os.path.isdir(os.path.join(self.env['baremetal_source_arch_dir'])):
self._build_dir(
self.env['baremetal_source_arch_subpath'],
gcc=gcc,
cflags=cflags,
entry_address=entry_address,
bootloader_obj=bootloader_obj,
common_objs=common_objs,
)
arch_dir = os.path.join('arch', self.env['arch'], 'no_bootloader')
if os.path.isdir(os.path.join(self.env['baremetal_source_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_build_dir(self):
return self.env['baremetal_build_dir']
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(self.env['baremetal_source_dir'], subpath)
out_dir = os.path.join(self.env['baremetal_build_dir'], subpath)
os.makedirs(out_dir, exist_ok=True)
common_objs = common_objs.copy()
if bootloader:
common_objs.append(bootloader_obj)
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 (self.env['c_ext'], self.env['asm_ext']):
in_name = os.path.splitext(in_basename)[0]
main_obj = os.path.join(self.env['baremetal_build_dir'], subpath, '{}{}'.format(in_name, self.env['obj_ext']))
src = os.path.join(self.env['baremetal_source_dir'], in_path)
if self.need_rebuild([src], main_obj):
self.sh.run_cmd(
[gcc, LF] +
cflags +
[
'-c', LF,
'-o', main_obj, LF,
src, LF,
]
)
objs = common_objs + [main_obj]
out = os.path.join(self.env['baremetal_build_dir'], subpath, in_name + self.env['baremetal_build_ext'])
link_script = os.path.join(self.env['baremetal_source_dir'], 'link.ld')
if self.need_rebuild(objs + [link_script], out):
self.sh.run_cmd(
[gcc, LF] +
cflags +
[
'-Wl,--section-start=.text={:#x}'.format(entry_address), LF,
'-o', out, LF,
'-T', link_script, LF,
] +
self.sh.add_newlines(objs)
)
if __name__ == '__main__':
Main().cli()