mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
baremetal: only rebuild required files based on mtime
Move multcore test up with bootloader.
This commit is contained in:
10
README.adoc
10
README.adoc
@@ -1589,7 +1589,9 @@ See also: https://github.com/cirosantilli/linux-kernel-module-cheat/issues/19
|
|||||||
|
|
||||||
The implementation is described at: https://stackoverflow.com/questions/46415059/how-to-observe-aarch64-system-registers-in-qemu/53043044#53043044
|
The implementation is described at: https://stackoverflow.com/questions/46415059/how-to-observe-aarch64-system-registers-in-qemu/53043044#53043044
|
||||||
|
|
||||||
=== GDB step debug multicore
|
=== GDB step debug multicore userland
|
||||||
|
|
||||||
|
For a more minimal baremetal multicore setup, see: <<arm-multicore>>.
|
||||||
|
|
||||||
We can set and get which cores the Linux kernel allows a program to run on with `sched_getaffinity` and `sched_setaffinity`:
|
We can set and get which cores the Linux kernel allows a program to run on with `sched_getaffinity` and `sched_setaffinity`:
|
||||||
|
|
||||||
@@ -10510,13 +10512,13 @@ output:
|
|||||||
|
|
||||||
==== ARM multicore
|
==== ARM multicore
|
||||||
|
|
||||||
TODO get working: CPU1 not waking up:
|
TODO get working: CPU 1 not waking up:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --arch aarch64 --baremetal arch/aarch64/no_bootloader/multicore
|
./run --arch aarch64 --baremetal arch/aarch64/multicore --cpus 2
|
||||||
....
|
....
|
||||||
|
|
||||||
Source: link:baremetal/arch/aarch64/no_bootloader/multicore.S[]
|
Source: link:baremetal/arch/aarch64/multicore.S[]
|
||||||
|
|
||||||
CPU 0 of this program enters a spinlock loop: it repeatedly checks if a given memory address is `1`.
|
CPU 0 of this program enters a spinlock loop: it repeatedly checks if a given memory address is `1`.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-multicore */
|
/* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-multicore */
|
||||||
|
|
||||||
.global mystart
|
.global main
|
||||||
mystart:
|
main:
|
||||||
/* Reset spinlock. */
|
/* Reset spinlock. */
|
||||||
mov x0, #0
|
mov x0, #0
|
||||||
ldr x1, =spinlock
|
ldr x1, =spinlock
|
||||||
@@ -21,15 +21,7 @@ mystart:
|
|||||||
ldr x0, spinlock
|
ldr x0, spinlock
|
||||||
cbz x0, 1b
|
cbz x0, 1b
|
||||||
|
|
||||||
/* Semihost exit. */
|
ret
|
||||||
mov x1, #0x26
|
|
||||||
movk x1, #2, lsl #16
|
|
||||||
str x1, [sp,#0]
|
|
||||||
mov x0, #0
|
|
||||||
str x0, [sp,#8]
|
|
||||||
mov x1, sp
|
|
||||||
mov w0, #0x18
|
|
||||||
hlt 0xf000
|
|
||||||
|
|
||||||
spinlock:
|
spinlock:
|
||||||
.skip 8
|
.skip 8
|
||||||
@@ -44,19 +44,22 @@ class BaremetalComponent(common.Component):
|
|||||||
uart_address = 0x09000000
|
uart_address = 0x09000000
|
||||||
os.makedirs(build_dir, exist_ok=True)
|
os.makedirs(build_dir, exist_ok=True)
|
||||||
os.makedirs(common.baremetal_build_lib_dir, exist_ok=True)
|
os.makedirs(common.baremetal_build_lib_dir, exist_ok=True)
|
||||||
|
src = os.path.join(common.baremetal_src_lib_dir, '{}{}'.format(args.arch, common.asm_ext))
|
||||||
|
if common.need_rebuild([src], bootloader_obj):
|
||||||
common.run_cmd(
|
common.run_cmd(
|
||||||
[gcc, common.Newline] +
|
[gcc, common.Newline] +
|
||||||
cflags +
|
cflags +
|
||||||
[
|
[
|
||||||
'-c', common.Newline,
|
'-c', common.Newline,
|
||||||
'-o', bootloader_obj, common.Newline,
|
'-o', bootloader_obj, common.Newline,
|
||||||
os.path.join(common.baremetal_src_lib_dir, '{}{}'.format(args.arch, common.asm_ext)), common.Newline,
|
src, common.Newline,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
for src, obj in [
|
for src, obj in [
|
||||||
(common_src, common_obj),
|
(common_src, common_obj),
|
||||||
(syscalls_src, syscalls_obj),
|
(syscalls_src, syscalls_obj),
|
||||||
]:
|
]:
|
||||||
|
if common.need_rebuild([src], obj):
|
||||||
common.run_cmd(
|
common.run_cmd(
|
||||||
[gcc, common.Newline] +
|
[gcc, common.Newline] +
|
||||||
cflags +
|
cflags +
|
||||||
@@ -137,37 +140,38 @@ Build the baremetal examples with crosstool-NG.
|
|||||||
in_dir = os.path.join(common.baremetal_src_dir, subpath)
|
in_dir = os.path.join(common.baremetal_src_dir, subpath)
|
||||||
out_dir = os.path.join(common.baremetal_build_dir, subpath)
|
out_dir = os.path.join(common.baremetal_build_dir, subpath)
|
||||||
os.makedirs(out_dir, exist_ok=True)
|
os.makedirs(out_dir, exist_ok=True)
|
||||||
|
common_objs = common_objs.copy()
|
||||||
if bootloader:
|
if bootloader:
|
||||||
bootloader_cmd = [bootloader_obj, common.Newline]
|
common_objs.append(bootloader_obj)
|
||||||
else:
|
|
||||||
bootloader_cmd = []
|
|
||||||
for in_basename in os.listdir(in_dir):
|
for in_basename in os.listdir(in_dir):
|
||||||
in_path = os.path.join(in_dir, in_basename)
|
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):
|
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]
|
in_name = os.path.splitext(in_basename)[0]
|
||||||
main_obj = os.path.join(common.baremetal_build_dir, subpath, '{}{}'.format(in_name, common.obj_ext))
|
main_obj = os.path.join(common.baremetal_build_dir, subpath, '{}{}'.format(in_name, common.obj_ext))
|
||||||
|
src = os.path.join(common.baremetal_src_dir, in_path)
|
||||||
|
if common.need_rebuild([src], main_obj):
|
||||||
common.run_cmd(
|
common.run_cmd(
|
||||||
[gcc, common.Newline] +
|
[gcc, common.Newline] +
|
||||||
cflags +
|
cflags +
|
||||||
[
|
[
|
||||||
'-c', common.Newline,
|
'-c', common.Newline,
|
||||||
'-o', main_obj, common.Newline,
|
'-o', main_obj, common.Newline,
|
||||||
os.path.join(common.baremetal_src_dir, in_path), common.Newline,
|
src, common.Newline,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
objs = common_objs + [main_obj]
|
||||||
|
out = os.path.join(common.baremetal_build_dir, subpath, in_name + common.baremetal_build_ext)
|
||||||
|
link_script = os.path.join(common.baremetal_src_dir, 'link.ld')
|
||||||
|
if common.need_rebuild(objs + [link_script], out):
|
||||||
common.run_cmd(
|
common.run_cmd(
|
||||||
[gcc, common.Newline] +
|
[gcc, common.Newline] +
|
||||||
cflags +
|
cflags +
|
||||||
[
|
[
|
||||||
'-Wl,--section-start=.text={:#x}'.format(entry_address), common.Newline,
|
'-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,
|
'-o', out, common.Newline,
|
||||||
'-T', os.path.join(common.baremetal_src_dir, 'link.ld'), common.Newline,
|
'-T', link_script, common.Newline,
|
||||||
] +
|
] +
|
||||||
bootloader_cmd +
|
common.add_newlines(objs)
|
||||||
common.add_newlines(common_objs) +
|
|
||||||
[
|
|
||||||
main_obj, common.Newline,
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
82
common.py
82
common.py
@@ -193,6 +193,39 @@ def write_string_to_file(path, string, mode='w'):
|
|||||||
with open(path, 'a') as f:
|
with open(path, 'a') as f:
|
||||||
f.write(string)
|
f.write(string)
|
||||||
|
|
||||||
|
def cmd_to_string(cmd, cwd=None, extra_env=None, extra_paths=None):
|
||||||
|
'''
|
||||||
|
Format a command given as a list of strings so that it can
|
||||||
|
be viewed nicely and executed by bash directly and print it to stdout.
|
||||||
|
'''
|
||||||
|
last_newline = ' \\\n'
|
||||||
|
newline_separator = last_newline + ' '
|
||||||
|
out = []
|
||||||
|
if extra_env is None:
|
||||||
|
extra_env = {}
|
||||||
|
if cwd is not None:
|
||||||
|
out.append('cd {} &&'.format(shlex.quote(cwd)))
|
||||||
|
if extra_paths is not None:
|
||||||
|
out.append('PATH="{}:${{PATH}}"'.format(':'.join(extra_paths)))
|
||||||
|
for key in extra_env:
|
||||||
|
out.append('{}={}'.format(shlex.quote(key), shlex.quote(extra_env[key])))
|
||||||
|
cmd_quote = []
|
||||||
|
newline_count = 0
|
||||||
|
for arg in cmd:
|
||||||
|
if arg == common.Newline:
|
||||||
|
cmd_quote.append(arg)
|
||||||
|
newline_count += 1
|
||||||
|
else:
|
||||||
|
cmd_quote.append(shlex.quote(arg))
|
||||||
|
if newline_count > 0:
|
||||||
|
cmd_quote = [' '.join(list(y)) for x, y in itertools.groupby(cmd_quote, lambda z: z == common.Newline) if not x]
|
||||||
|
out.extend(cmd_quote)
|
||||||
|
if newline_count == 1 and cmd[-1] == common.Newline:
|
||||||
|
ending = ''
|
||||||
|
else:
|
||||||
|
ending = last_newline + ';'
|
||||||
|
return newline_separator.join(out) + ending
|
||||||
|
|
||||||
def copy_dir_if_update_non_recursive(srcdir, destdir, filter_ext=None):
|
def copy_dir_if_update_non_recursive(srcdir, destdir, filter_ext=None):
|
||||||
# TODO print rsync equivalent.
|
# TODO print rsync equivalent.
|
||||||
os.makedirs(destdir, exist_ok=True)
|
os.makedirs(destdir, exist_ok=True)
|
||||||
@@ -207,6 +240,11 @@ def copy_dir_if_update_non_recursive(srcdir, destdir, filter_ext=None):
|
|||||||
update=1,
|
update=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def cp(src, dest):
|
||||||
|
print_cmd(['cp', src, dest])
|
||||||
|
if not common.dry_run:
|
||||||
|
shutil.copy2(src, dest)
|
||||||
|
|
||||||
def gem_list_checkpoint_dirs():
|
def gem_list_checkpoint_dirs():
|
||||||
'''
|
'''
|
||||||
List checkpoint directory, oldest first.
|
List checkpoint directory, oldest first.
|
||||||
@@ -475,38 +513,13 @@ def make_run_dirs():
|
|||||||
os.makedirs(common.p9_dir, exist_ok=True)
|
os.makedirs(common.p9_dir, exist_ok=True)
|
||||||
os.makedirs(common.qemu_run_dir, exist_ok=True)
|
os.makedirs(common.qemu_run_dir, exist_ok=True)
|
||||||
|
|
||||||
def cmd_to_string(cmd, cwd=None, extra_env=None, extra_paths=None):
|
def need_rebuild(srcs, dst):
|
||||||
'''
|
if not os.path.exists(dst):
|
||||||
Format a command given as a list of strings so that it can
|
return True
|
||||||
be viewed nicely and executed by bash directly and print it to stdout.
|
for src in srcs:
|
||||||
'''
|
if os.path.getmtime(src) > os.path.getmtime(dst):
|
||||||
last_newline = ' \\\n'
|
return True
|
||||||
newline_separator = last_newline + ' '
|
return False
|
||||||
out = []
|
|
||||||
if extra_env is None:
|
|
||||||
extra_env = {}
|
|
||||||
if cwd is not None:
|
|
||||||
out.append('cd {} &&'.format(shlex.quote(cwd)))
|
|
||||||
if extra_paths is not None:
|
|
||||||
out.append('PATH="{}:${{PATH}}"'.format(':'.join(extra_paths)))
|
|
||||||
for key in extra_env:
|
|
||||||
out.append('{}={}'.format(shlex.quote(key), shlex.quote(extra_env[key])))
|
|
||||||
cmd_quote = []
|
|
||||||
newline_count = 0
|
|
||||||
for arg in cmd:
|
|
||||||
if arg == common.Newline:
|
|
||||||
cmd_quote.append(arg)
|
|
||||||
newline_count += 1
|
|
||||||
else:
|
|
||||||
cmd_quote.append(shlex.quote(arg))
|
|
||||||
if newline_count > 0:
|
|
||||||
cmd_quote = [' '.join(list(y)) for x, y in itertools.groupby(cmd_quote, lambda z: z == common.Newline) if not x]
|
|
||||||
out.extend(cmd_quote)
|
|
||||||
if newline_count == 1 and cmd[-1] == common.Newline:
|
|
||||||
ending = ''
|
|
||||||
else:
|
|
||||||
ending = last_newline + ';'
|
|
||||||
return newline_separator.join(out) + ending
|
|
||||||
|
|
||||||
def print_cmd(cmd, cwd=None, cmd_file=None, extra_env=None, extra_paths=None):
|
def print_cmd(cmd, cwd=None, cmd_file=None, extra_env=None, extra_paths=None):
|
||||||
'''
|
'''
|
||||||
@@ -576,11 +589,6 @@ def resolve_args(defaults, args, extra_args):
|
|||||||
argcopy.__dict__ = dict(list(defaults.items()) + list(argcopy.__dict__.items()) + list(extra_args.items()))
|
argcopy.__dict__ = dict(list(defaults.items()) + list(argcopy.__dict__.items()) + list(extra_args.items()))
|
||||||
return argcopy
|
return argcopy
|
||||||
|
|
||||||
def cp(src, dest):
|
|
||||||
print_cmd(['cp', src, dest])
|
|
||||||
if not common.dry_run:
|
|
||||||
shutil.copy2(src, dest)
|
|
||||||
|
|
||||||
def rmrf(path):
|
def rmrf(path):
|
||||||
print_cmd(['rm', '-r', '-f', path])
|
print_cmd(['rm', '-r', '-f', path])
|
||||||
if not common.dry_run and os.path.exists(path):
|
if not common.dry_run and os.path.exists(path):
|
||||||
|
|||||||
Reference in New Issue
Block a user