Skip to content

Commit 8dd0141

Browse files
committed
baremetal: only rebuild required files based on mtime
Move multcore test up with bootloader.
1 parent f73eaaf commit 8dd0141

File tree

4 files changed

+99
-93
lines changed

4 files changed

+99
-93
lines changed

README.adoc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,7 +1589,9 @@ See also: https://github.com/cirosantilli/linux-kernel-module-cheat/issues/19
15891589

15901590
The implementation is described at: https://stackoverflow.com/questions/46415059/how-to-observe-aarch64-system-registers-in-qemu/53043044#53043044
15911591

1592-
=== GDB step debug multicore
1592+
=== GDB step debug multicore userland
1593+
1594+
For a more minimal baremetal multicore setup, see: <<arm-multicore>>.
15931595

15941596
We can set and get which cores the Linux kernel allows a program to run on with `sched_getaffinity` and `sched_setaffinity`:
15951597

@@ -10510,13 +10512,13 @@ output:
1051010512

1051110513
==== ARM multicore
1051210514

10513-
TODO get working: CPU1 not waking up:
10515+
TODO get working: CPU 1 not waking up:
1051410516

1051510517
....
10516-
./run --arch aarch64 --baremetal arch/aarch64/no_bootloader/multicore
10518+
./run --arch aarch64 --baremetal arch/aarch64/multicore --cpus 2
1051710519
....
1051810520

10519-
Source: link:baremetal/arch/aarch64/no_bootloader/multicore.S[]
10521+
Source: link:baremetal/arch/aarch64/multicore.S[]
1052010522

1052110523
CPU 0 of this program enters a spinlock loop: it repeatedly checks if a given memory address is `1`.
1052210524

baremetal/arch/aarch64/no_bootloader/multicore.S renamed to baremetal/arch/aarch64/multicore.S

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-multicore */
22

3-
.global mystart
4-
mystart:
3+
.global main
4+
main:
55
/* Reset spinlock. */
66
mov x0, #0
77
ldr x1, =spinlock
@@ -21,15 +21,7 @@ mystart:
2121
ldr x0, spinlock
2222
cbz x0, 1b
2323

24-
/* Semihost exit. */
25-
mov x1, #0x26
26-
movk x1, #2, lsl #16
27-
str x1, [sp,#0]
28-
mov x0, #0
29-
str x0, [sp,#8]
30-
mov x1, sp
31-
mov w0, #0x18
32-
hlt 0xf000
24+
ret
3325

3426
spinlock:
3527
.skip 8

build-baremetal

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -44,29 +44,32 @@ class BaremetalComponent(common.Component):
4444
uart_address = 0x09000000
4545
os.makedirs(build_dir, exist_ok=True)
4646
os.makedirs(common.baremetal_build_lib_dir, exist_ok=True)
47-
common.run_cmd(
48-
[gcc, common.Newline] +
49-
cflags +
50-
[
51-
'-c', common.Newline,
52-
'-o', bootloader_obj, common.Newline,
53-
os.path.join(common.baremetal_src_lib_dir, '{}{}'.format(args.arch, common.asm_ext)), common.Newline,
54-
]
55-
)
56-
for src, obj in [
57-
(common_src, common_obj),
58-
(syscalls_src, syscalls_obj),
59-
]:
47+
src = os.path.join(common.baremetal_src_lib_dir, '{}{}'.format(args.arch, common.asm_ext))
48+
if common.need_rebuild([src], bootloader_obj):
6049
common.run_cmd(
6150
[gcc, common.Newline] +
6251
cflags +
6352
[
6453
'-c', common.Newline,
65-
'-D', 'UART0_ADDR={:#x}'.format(uart_address), common.Newline,
66-
'-o', obj, common.Newline,
54+
'-o', bootloader_obj, common.Newline,
6755
src, common.Newline,
6856
]
6957
)
58+
for src, obj in [
59+
(common_src, common_obj),
60+
(syscalls_src, syscalls_obj),
61+
]:
62+
if common.need_rebuild([src], obj):
63+
common.run_cmd(
64+
[gcc, common.Newline] +
65+
cflags +
66+
[
67+
'-c', common.Newline,
68+
'-D', 'UART0_ADDR={:#x}'.format(uart_address), common.Newline,
69+
'-o', obj, common.Newline,
70+
src, common.Newline,
71+
]
72+
)
7073
self._build_dir(
7174
'',
7275
gcc=gcc,
@@ -137,38 +140,39 @@ Build the baremetal examples with crosstool-NG.
137140
in_dir = os.path.join(common.baremetal_src_dir, subpath)
138141
out_dir = os.path.join(common.baremetal_build_dir, subpath)
139142
os.makedirs(out_dir, exist_ok=True)
143+
common_objs = common_objs.copy()
140144
if bootloader:
141-
bootloader_cmd = [bootloader_obj, common.Newline]
142-
else:
143-
bootloader_cmd = []
145+
common_objs.append(bootloader_obj)
144146
for in_basename in os.listdir(in_dir):
145147
in_path = os.path.join(in_dir, in_basename)
146148
if os.path.isfile(in_path) and os.path.splitext(in_basename)[1] in (common.c_ext, common.asm_ext):
147149
in_name = os.path.splitext(in_basename)[0]
148150
main_obj = os.path.join(common.baremetal_build_dir, subpath, '{}{}'.format(in_name, common.obj_ext))
149-
common.run_cmd(
150-
[gcc, common.Newline] +
151-
cflags +
152-
[
153-
'-c', common.Newline,
154-
'-o', main_obj, common.Newline,
155-
os.path.join(common.baremetal_src_dir, in_path), common.Newline,
156-
]
157-
)
158-
common.run_cmd(
159-
[gcc, common.Newline] +
160-
cflags +
161-
[
162-
'-Wl,--section-start=.text={:#x}'.format(entry_address), common.Newline,
163-
'-o', os.path.join(common.baremetal_build_dir, subpath, in_name + common.baremetal_build_ext), common.Newline,
164-
'-T', os.path.join(common.baremetal_src_dir, 'link.ld'), common.Newline,
165-
] +
166-
bootloader_cmd +
167-
common.add_newlines(common_objs) +
168-
[
169-
main_obj, common.Newline,
170-
]
171-
)
151+
src = os.path.join(common.baremetal_src_dir, in_path)
152+
if common.need_rebuild([src], main_obj):
153+
common.run_cmd(
154+
[gcc, common.Newline] +
155+
cflags +
156+
[
157+
'-c', common.Newline,
158+
'-o', main_obj, common.Newline,
159+
src, common.Newline,
160+
]
161+
)
162+
objs = common_objs + [main_obj]
163+
out = os.path.join(common.baremetal_build_dir, subpath, in_name + common.baremetal_build_ext)
164+
link_script = os.path.join(common.baremetal_src_dir, 'link.ld')
165+
if common.need_rebuild(objs + [link_script], out):
166+
common.run_cmd(
167+
[gcc, common.Newline] +
168+
cflags +
169+
[
170+
'-Wl,--section-start=.text={:#x}'.format(entry_address), common.Newline,
171+
'-o', out, common.Newline,
172+
'-T', link_script, common.Newline,
173+
] +
174+
common.add_newlines(objs)
175+
)
172176

173177
if __name__ == '__main__':
174178
BaremetalComponent().build()

common.py

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,39 @@ def write_string_to_file(path, string, mode='w'):
193193
with open(path, 'a') as f:
194194
f.write(string)
195195

196+
def cmd_to_string(cmd, cwd=None, extra_env=None, extra_paths=None):
197+
'''
198+
Format a command given as a list of strings so that it can
199+
be viewed nicely and executed by bash directly and print it to stdout.
200+
'''
201+
last_newline = ' \\\n'
202+
newline_separator = last_newline + ' '
203+
out = []
204+
if extra_env is None:
205+
extra_env = {}
206+
if cwd is not None:
207+
out.append('cd {} &&'.format(shlex.quote(cwd)))
208+
if extra_paths is not None:
209+
out.append('PATH="{}:${{PATH}}"'.format(':'.join(extra_paths)))
210+
for key in extra_env:
211+
out.append('{}={}'.format(shlex.quote(key), shlex.quote(extra_env[key])))
212+
cmd_quote = []
213+
newline_count = 0
214+
for arg in cmd:
215+
if arg == common.Newline:
216+
cmd_quote.append(arg)
217+
newline_count += 1
218+
else:
219+
cmd_quote.append(shlex.quote(arg))
220+
if newline_count > 0:
221+
cmd_quote = [' '.join(list(y)) for x, y in itertools.groupby(cmd_quote, lambda z: z == common.Newline) if not x]
222+
out.extend(cmd_quote)
223+
if newline_count == 1 and cmd[-1] == common.Newline:
224+
ending = ''
225+
else:
226+
ending = last_newline + ';'
227+
return newline_separator.join(out) + ending
228+
196229
def copy_dir_if_update_non_recursive(srcdir, destdir, filter_ext=None):
197230
# TODO print rsync equivalent.
198231
os.makedirs(destdir, exist_ok=True)
@@ -207,6 +240,11 @@ def copy_dir_if_update_non_recursive(srcdir, destdir, filter_ext=None):
207240
update=1,
208241
)
209242

243+
def cp(src, dest):
244+
print_cmd(['cp', src, dest])
245+
if not common.dry_run:
246+
shutil.copy2(src, dest)
247+
210248
def gem_list_checkpoint_dirs():
211249
'''
212250
List checkpoint directory, oldest first.
@@ -475,38 +513,13 @@ def make_run_dirs():
475513
os.makedirs(common.p9_dir, exist_ok=True)
476514
os.makedirs(common.qemu_run_dir, exist_ok=True)
477515

478-
def cmd_to_string(cmd, cwd=None, extra_env=None, extra_paths=None):
479-
'''
480-
Format a command given as a list of strings so that it can
481-
be viewed nicely and executed by bash directly and print it to stdout.
482-
'''
483-
last_newline = ' \\\n'
484-
newline_separator = last_newline + ' '
485-
out = []
486-
if extra_env is None:
487-
extra_env = {}
488-
if cwd is not None:
489-
out.append('cd {} &&'.format(shlex.quote(cwd)))
490-
if extra_paths is not None:
491-
out.append('PATH="{}:${{PATH}}"'.format(':'.join(extra_paths)))
492-
for key in extra_env:
493-
out.append('{}={}'.format(shlex.quote(key), shlex.quote(extra_env[key])))
494-
cmd_quote = []
495-
newline_count = 0
496-
for arg in cmd:
497-
if arg == common.Newline:
498-
cmd_quote.append(arg)
499-
newline_count += 1
500-
else:
501-
cmd_quote.append(shlex.quote(arg))
502-
if newline_count > 0:
503-
cmd_quote = [' '.join(list(y)) for x, y in itertools.groupby(cmd_quote, lambda z: z == common.Newline) if not x]
504-
out.extend(cmd_quote)
505-
if newline_count == 1 and cmd[-1] == common.Newline:
506-
ending = ''
507-
else:
508-
ending = last_newline + ';'
509-
return newline_separator.join(out) + ending
516+
def need_rebuild(srcs, dst):
517+
if not os.path.exists(dst):
518+
return True
519+
for src in srcs:
520+
if os.path.getmtime(src) > os.path.getmtime(dst):
521+
return True
522+
return False
510523

511524
def print_cmd(cmd, cwd=None, cmd_file=None, extra_env=None, extra_paths=None):
512525
'''
@@ -576,11 +589,6 @@ def resolve_args(defaults, args, extra_args):
576589
argcopy.__dict__ = dict(list(defaults.items()) + list(argcopy.__dict__.items()) + list(extra_args.items()))
577590
return argcopy
578591

579-
def cp(src, dest):
580-
print_cmd(['cp', src, dest])
581-
if not common.dry_run:
582-
shutil.copy2(src, dest)
583-
584592
def rmrf(path):
585593
print_cmd(['rm', '-r', '-f', path])
586594
if not common.dry_run and os.path.exists(path):

0 commit comments

Comments
 (0)