diff --git a/README.adoc b/README.adoc index b884753..1d488f2 100644 --- a/README.adoc +++ b/README.adoc @@ -11321,13 +11321,13 @@ since boot has already happened, and the parameters are already in the RAM of th ==== gem5 checkpoint userland minimal example -In order to debug checkpoint restore bugs, this minimal setup using link:userland/freestanding/gem5_checkpoint_restore.S[] can be handy: +In order to debug checkpoint restore bugs, this minimal setup using link:userland/freestanding/gem5_checkpoint.S[] can be handy: .... ./build-userland --arch aarch64 --static -./run --arch aarch64 --emulator gem5 --static --userland userland/freestanding/gem5_checkpoint_restore.S --trace-insts-stdout -./run --arch aarch64 --emulator gem5 --static --userland userland/freestanding/gem5_checkpoint_restore.S --trace-insts-stdout --gem5-restore 1 -./run --arch aarch64 --emulator gem5 --static --userland userland/freestanding/gem5_checkpoint_restore.S --trace-insts-stdout --gem5-restore 1 -- --cpu-type=DerivO3CPU --restore-with-cpu=DerivO3CPU --caches +./run --arch aarch64 --emulator gem5 --static --userland userland/freestanding/gem5_checkpoint.S --trace-insts-stdout +./run --arch aarch64 --emulator gem5 --static --userland userland/freestanding/gem5_checkpoint.S --trace-insts-stdout --gem5-restore 1 +./run --arch aarch64 --emulator gem5 --static --userland userland/freestanding/gem5_checkpoint.S --trace-insts-stdout --gem5-restore 1 -- --cpu-type=DerivO3CPU --restore-with-cpu=DerivO3CPU --caches .... On the initial run, we see that all instructions are executed and the checkpoint is taken: @@ -11512,7 +11512,7 @@ And then restore the checkpoint with a different slower CPU: And now you will notice that everything happens much slower in the guest terminal! -One even more direct and minimal way to observe this is with link:userland/freestanding/gem5_checkpoint_restore.S[] which was mentioned at <> plus some logging: +One even more direct and minimal way to observe this is with link:userland/freestanding/gem5_checkpoint.S[] which was mentioned at <> plus some logging: .... ./run \ @@ -11520,7 +11520,7 @@ One even more direct and minimal way to observe this is with link:userland/frees --emulator gem5 \ --static \ --trace ExecAll,FmtFlag,O3CPU,SimpleCPU \ - --userland userland/freestanding/gem5_checkpoint_restore.S \ + --userland userland/freestanding/gem5_checkpoint.S \ ; cat "$(./getvar --arch aarch64 --emulator gem5 trace_txt_file)" ./run \ @@ -11529,7 +11529,7 @@ cat "$(./getvar --arch aarch64 --emulator gem5 trace_txt_file)" --gem5-restore 1 \ --static \ --trace ExecAll,FmtFlag,O3CPU,SimpleCPU \ - --userland userland/freestanding/gem5_checkpoint_restore.S \ + --userland userland/freestanding/gem5_checkpoint.S \ -- \ --caches \ --cpu-type DerivO3CPU \ @@ -11584,7 +11584,7 @@ This is generally useless compared to checkpoint restoring because: * checkpoint restore allows to run multiple contents after the restore, and restoring to multiple different system states, which you almost always want to do * we generally don't know the exact tick at which the region of interest will start, especially as the binaries change. It is much easier to just instrument the content with a checkoint <> -But let's give it a try anyways with link:userland/freestanding/gem5_checkpoint_restore.S[] which was mentioned at <> +But let's give it a try anyways with link:userland/freestanding/gem5_checkpoint.S[] which was mentioned at <> .... ./run \ @@ -11592,7 +11592,7 @@ But let's give it a try anyways with link:userland/freestanding/gem5_checkpoint_ --emulator gem5 \ --static \ --trace ExecAll,FmtFlag,O3CPU,SimpleCPU \ - --userland userland/freestanding/gem5_checkpoint_restore.S \ + --userland userland/freestanding/gem5_checkpoint.S \ -- \ --caches --cpu-type DerivO3CPU \ @@ -17003,6 +17003,7 @@ The C standard library infrastructure is implemented in the common userland / ba Unlike most our other assembly examples, which use the C standard library for portability, examples under `freestanding/` directories don't link to the C standard library: +* link:userland/freestanding/[]: freestanding programs that work on any ISA * link:userland/arch/x86_64/freestanding/[] * link:userland/arch/arm/freestanding/[] * link:userland/arch/aarch64/freestanding/[] diff --git a/baremetal/arch/aarch64/no_bootloader/gem5_exit.S b/baremetal/arch/aarch64/no_bootloader/gem5_exit.S deleted file mode 100644 index 4c678fc..0000000 --- a/baremetal/arch/aarch64/no_bootloader/gem5_exit.S +++ /dev/null @@ -1,5 +0,0 @@ -#include - -.global _start -_start: - LKMC_M5OPS_EXIT_ASM diff --git a/baremetal/arch/arm/no_bootloader/gem5_exit.S b/baremetal/arch/arm/no_bootloader/gem5_exit.S deleted file mode 100644 index 7a6a407..0000000 --- a/baremetal/arch/arm/no_bootloader/gem5_exit.S +++ /dev/null @@ -1,3 +0,0 @@ -.global _start -_start: - mov r0, #0; mov r1, #0; .inst 0xEE000110 | (0x21 << 16); diff --git a/baremetal/lib/syscalls_asm.S b/baremetal/lib/syscalls_asm.S index 30cc367..ac19d8c 100644 --- a/baremetal/lib/syscalls_asm.S +++ b/baremetal/lib/syscalls_asm.S @@ -7,6 +7,7 @@ * void _exit(int status) * * If only there was a GCC attribute to create such a function! + * https://stackoverflow.com/questions/43310704/creating-a-c-function-without-compiler-generated-prologue-epilogue-ret-instruc */ .text .global _exit diff --git a/common.py b/common.py index 0c3ac1e..5cfe601 100644 --- a/common.py +++ b/common.py @@ -1716,10 +1716,16 @@ after configure, e.g. SCons. Usually contains specific targets or other build fl if extra_objs is None: extra_objs= [] if link: - if self.env['mode'] == 'baremetal' or my_path_properties['extra_objs_lkmc_common']: + # Baremetal builds cannot add their usual syscall objects, as those + # rely on standard library symbols. + if my_path_properties['freestanding']: + extra_objs = [] + if (self.env['mode'] == 'baremetal' and not my_path_properties['freestanding']) \ + or my_path_properties['extra_objs_lkmc_common']: extra_objs.extend(extra_objs_lkmc_common) if ( self.env['mode'] == 'baremetal' and + not my_path_properties['freestanding'] and not my_path_properties['extra_objs_disable_baremetal_bootloader'] ): extra_objs.extend(extra_objs_baremetal_bootloader) diff --git a/path_properties.py b/path_properties.py index ffdebb2..da52bf6 100644 --- a/path_properties.py +++ b/path_properties.py @@ -50,6 +50,7 @@ class PathProperties: 'extra_objs_disable_baremetal_bootloader': False, # We should get rid of this if we ever properly implement dependency graphs. 'extra_objs_lkmc_common': False, + 'freestanding': True, 'gem5_unimplemented_instruction': False, # Fully, or partially unimplemented. 'gem5_unimplemented_syscall': False, @@ -374,13 +375,18 @@ freestanding_properties = { '-static', LF, ], 'extra_objs_lkmc_common': False, + 'freestanding': True, } # https://cirosantilli.com/linux-kernel-module-cheat#nostartfiles-programs nostartfiles_properties = { + # The baremetal bootloader sets up the stack to a valid value. + # Therefore, without it, C code may not be called, and so this is very restrictive in general. + # Programs that don't call C code nor use stack can still work. 'baremetal': False, 'cc_flags': [ '-nostartfiles', LF, ], + 'extra_objs_disable_baremetal_bootloader': True, } # See: https://cirosantilli.com/linux-kernel-module-cheat#path-properties path_properties_tuples = ( @@ -406,7 +412,6 @@ path_properties_tuples = ( 'no_bootloader': ( {'extra_objs_disable_baremetal_bootloader': True}, { - 'gem5_exit.S': {'requires_m5ops': True}, 'multicore_asm.S': {'test_run_args': {'cpus': 2}}, 'semihost_exit.S': {'requires_semihosting': True}, } @@ -423,7 +428,6 @@ path_properties_tuples = ( 'no_bootloader': ( {'extra_objs_disable_baremetal_bootloader': True}, { - 'gem5_exit.S': {'requires_m5ops': True}, 'multicore_asm.S': {'test_run_args': {'cpus': 2}}, 'semihost_exit.S': {'requires_semihosting': True}, 'wfe_loop.S': {'more_than_1s': True}, @@ -685,9 +689,9 @@ path_properties_tuples = ( }, ), 'freestanding': ( - freestanding_properties, + {**freestanding_properties, **{'baremetal': True}}, { - 'gem5_checkpoint_restore.S': {'allowed_emulators': {'gem5'}}, + 'gem5_checkpoint.S': {'allowed_emulators': {'gem5'}}, 'gem5_exit.S': {'allowed_emulators': {'gem5'}}, } ), diff --git a/userland/arch/aarch64/freestanding/linux/gem5_exit.S b/userland/arch/aarch64/freestanding/linux/gem5_exit.S deleted file mode 100644 index ba4842d..0000000 --- a/userland/arch/aarch64/freestanding/linux/gem5_exit.S +++ /dev/null @@ -1,10 +0,0 @@ -/* https://cirosantilli.com/linux-kernel-module-cheat#benchmark-emulators-on-userland-executables */ - -#define LKMC_M5OPS_ENABLE 1 -#include "lkmc/m5ops.h" - -.text -.global _start -_start: -asm_main_after_prologue: - LKMC_M5OPS_EXIT_ASM diff --git a/userland/freestanding/README.adoc b/userland/freestanding/README.adoc new file mode 100644 index 0000000..e01d17d --- /dev/null +++ b/userland/freestanding/README.adoc @@ -0,0 +1 @@ +https://cirosantilli.com/linux-kernel-module-cheat#freestanding-programs diff --git a/userland/freestanding/gem5_checkpoint_restore.S b/userland/freestanding/gem5_checkpoint.S similarity index 100% rename from userland/freestanding/gem5_checkpoint_restore.S rename to userland/freestanding/gem5_checkpoint.S