diff --git a/README.adoc b/README.adoc index ae8b3e8..9f8f139 100644 --- a/README.adoc +++ b/README.adoc @@ -755,7 +755,7 @@ Or to run a baremetal example instead: .... ./run \ --arch aarch64 \ - --baremetal baremetal/hello.c \ + --baremetal baremetal/c/hello.c \ --qemu-which host \ ; .... @@ -1193,11 +1193,11 @@ Our C bare-metal compiler is built with link:https://github.com/crosstool-ng/cro Every `.c` file inside link:baremetal/[] and `.S` file inside `baremetal/arch//` generates a separate baremetal image. -For example, to run link:baremetal/hello.c[] in QEMU do: +For example, to run link:baremetal/c/hello.c[] in QEMU do: .... ./build --arch aarch64 --download-dependencies qemu-baremetal -./run --arch aarch64 --baremetal baremetal/hello.c +./run --arch aarch64 --baremetal baremetal/c/hello.c .... The terminal prints: @@ -1238,14 +1238,14 @@ echo $? To modify a baremetal program, simply edit the file, e.g. .... -vim baremetal/hello.c +vim baremetal/c/hello.c .... and rebuild: .... ./build-baremetal --arch aarch64 -./run --arch aarch64 --baremetal baremetal/hello.c +./run --arch aarch64 --baremetal baremetal/c/hello.c .... `./build qemu-baremetal` that we run previously is only needed for the initial build. That script calls link:build-baremetal[] for us, in addition to building prerequisites such as QEMU and crosstool-NG. @@ -1255,7 +1255,7 @@ and rebuild: Alternatively, for the sake of tab completion, we also accept relative paths inside `baremetal/`, for example the following also work: .... -./run --arch aarch64 --baremetal baremetal/hello.c +./run --arch aarch64 --baremetal baremetal/c/hello.c ./run --arch aarch64 --baremetal baremetal/arch/aarch64/add.S .... @@ -1269,7 +1269,7 @@ To use gem5 instead of QEMU do: .... ./build --download-dependencies gem5-baremetal -./run --arch aarch64 --baremetal baremetal/hello.c --emulator gem5 +./run --arch aarch64 --baremetal baremetal/c/hello.c --emulator gem5 .... and then <> open a shell with: @@ -1281,7 +1281,7 @@ and then <> open a shell with: Or as usual, <> users can do both in one go with: .... -./run --arch aarch64 --baremetal baremetal/hello.c --emulator gem5 --tmux +./run --arch aarch64 --baremetal baremetal/c/hello.c --emulator gem5 --tmux .... TODO: the carriage returns are a bit different than in QEMU, see: <>. @@ -1289,8 +1289,8 @@ TODO: the carriage returns are a bit different than in QEMU, see: <>, do everything in one go with: .... -./run --arch arm --baremetal baremetal/hello.c --gdb +./run --arch arm --baremetal baremetal/c/hello.c --gdb .... Alternatively, to start from the very first executed instruction of our tiny <>: @@ -12982,13 +13000,13 @@ Alternatively, to start from the very first executed instruction of our tiny </no_bootloader/*.S`, e.g.: @@ -13125,7 +13143,7 @@ For `arm`, some baremetal examples compile fine with: .... sudo apt-get install gcc-arm-none-eabi qemu-system-arm ./build-baremetal --arch arm --gcc-which host-baremetal -./run --arch arm --baremetal baremetal/hello.c --qemu-which host +./run --arch arm --baremetal baremetal/c/hello.c --qemu-which host .... However, there are as usual limitations to using prebuilts: @@ -13154,7 +13172,7 @@ TODO: any advantage over QEMU? I doubt it, mostly using it as as toy for now: Without running `./run`, do directly: .... -./run-gdb --arch arm --baremetal baremetal/hello.c --sim +./run-gdb --arch arm --baremetal baremetal/c/hello.c --sim .... Then inside GDB: @@ -13720,12 +13738,12 @@ Source: link:test-baremetal[] Analogously to <>, we can select individual tests or directories with: .... -./test-baremetal --arch aarch64 baremetal/hello.c baremetal/arch/aarch64/no_bootloader/ +./test-baremetal --arch aarch64 baremetal/c/hello.c baremetal/arch/aarch64/no_bootloader/ .... which would run all of: -* link:baremetal/hello.c[] +* link:baremetal/c/hello.c[] * all tests under the directory: link:baremetal/arch/aarch64/no_bootloader/[] We detect if tests failed by parsing logs for the <>. @@ -15097,14 +15115,14 @@ Sources: If a test fails, re-run the test commands manually and use `--verbose` to understand what happened: .... -./run --arch arm --background --baremetal baremetal/add.c --gdb-wait & -./run-gdb --arch arm --baremetal baremetal/add.c --verbose -- main +./run --arch arm --background --baremetal baremetal/c/add.c --gdb-wait & +./run-gdb --arch arm --baremetal baremetal/c/add.c --verbose -- main .... and possibly repeat the GDB steps manually with the usual: .... -./run-gdb --arch arm --baremetal baremetal/add.c --no-continue --verbose +./run-gdb --arch arm --baremetal baremetal/c/add.c --no-continue --verbose .... To debug GDB problems on gem5, you might want to enable the following <> options: @@ -15112,7 +15130,7 @@ To debug GDB problems on gem5, you might want to enable the following <>, so + The following examples end up testing that our setup is working: + -* link:baremetal/assert_fail.c[] +* link:baremetal/c/assert_fail.c[] * link:baremetal/return1.c[] * link:baremetal/return2.c[] * link:baremetal/exit0.c[] diff --git a/baremetal/add.c b/baremetal/add.c deleted file mode 120000 index 42c36f0..0000000 --- a/baremetal/add.c +++ /dev/null @@ -1 +0,0 @@ -../lkmc/add.c \ No newline at end of file diff --git a/baremetal/add.py b/baremetal/add.py deleted file mode 120000 index d819366..0000000 --- a/baremetal/add.py +++ /dev/null @@ -1 +0,0 @@ -../lkmc/add.py \ No newline at end of file diff --git a/baremetal/assert_fail.c b/baremetal/assert_fail.c deleted file mode 120000 index 0263f59..0000000 --- a/baremetal/assert_fail.c +++ /dev/null @@ -1 +0,0 @@ -../lkmc/assert_fail.c \ No newline at end of file diff --git a/baremetal/c/add.c b/baremetal/c/add.c new file mode 120000 index 0000000..46def32 --- /dev/null +++ b/baremetal/c/add.c @@ -0,0 +1 @@ +../../lkmc/c/add.c \ No newline at end of file diff --git a/baremetal/c/add.py b/baremetal/c/add.py new file mode 120000 index 0000000..fb5788a --- /dev/null +++ b/baremetal/c/add.py @@ -0,0 +1 @@ +../../lkmc/c/add.py \ No newline at end of file diff --git a/baremetal/c/assert_fail.c b/baremetal/c/assert_fail.c new file mode 120000 index 0000000..904602c --- /dev/null +++ b/baremetal/c/assert_fail.c @@ -0,0 +1 @@ +../../lkmc/c/assert_fail.c \ No newline at end of file diff --git a/baremetal/c/hello.c b/baremetal/c/hello.c new file mode 120000 index 0000000..3f0a531 --- /dev/null +++ b/baremetal/c/hello.c @@ -0,0 +1 @@ +../../lkmc/c/hello.c \ No newline at end of file diff --git a/baremetal/c/infinite_loop.c b/baremetal/c/infinite_loop.c new file mode 120000 index 0000000..faa4cdd --- /dev/null +++ b/baremetal/c/infinite_loop.c @@ -0,0 +1 @@ +../../lkmc/c/infinite_loop.c \ No newline at end of file diff --git a/baremetal/c/stderr.c b/baremetal/c/stderr.c new file mode 120000 index 0000000..1344887 --- /dev/null +++ b/baremetal/c/stderr.c @@ -0,0 +1 @@ +../../lkmc/c/stderr.c \ No newline at end of file diff --git a/baremetal/hello.c b/baremetal/hello.c deleted file mode 120000 index d00921e..0000000 --- a/baremetal/hello.c +++ /dev/null @@ -1 +0,0 @@ -../lkmc/hello.c \ No newline at end of file diff --git a/baremetal/infinite_loop.c b/baremetal/infinite_loop.c deleted file mode 100644 index 6aaced0..0000000 --- a/baremetal/infinite_loop.c +++ /dev/null @@ -1,4 +0,0 @@ -int main(void) { - while(1) {} - return 0; -} diff --git a/baremetal/getchar.c b/baremetal/out_of_memory.c similarity index 55% rename from baremetal/getchar.c rename to baremetal/out_of_memory.c index 32becce..b7737a3 100644 --- a/baremetal/getchar.c +++ b/baremetal/out_of_memory.c @@ -1,22 +1,17 @@ -/* Test that input request through serial also works. */ +/* Test out of memory. */ #include #include int main(void) { - char c; char *ptr = NULL; size_t alloc_size = 1; while (1) { - printf("enter a character\n"); - c = getchar(); - printf("got: %c\n", c); ptr = realloc(ptr, alloc_size); if (ptr == NULL) { puts("out of memory"); break; } else { - printf("new alloc of %zu bytes at address 0x%p\n", alloc_size, ptr); alloc_size <<= 1; } } diff --git a/bisect-gem5-gdb b/bisect-gem5-gdb new file mode 100755 index 0000000..660fff1 --- /dev/null +++ b/bisect-gem5-gdb @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +# https://github.com/cirosantilli/linux-kernel-module-cheat#bisection +set -eu +cd ../.. +./build-gem5 --arch aarch64 --gem5-build-id bisect +./test-gdb --arch aarch64 --quit-on-fail diff --git a/common.py b/common.py index 9b293e7..25bfaa7 100644 --- a/common.py +++ b/common.py @@ -155,10 +155,14 @@ class LkmcCliFunction(cli_function.CliFunction): It would be beautiful to do this evaluation in a lazy way, e.g. with functions + cache decorators: https://stackoverflow.com/questions/815110/is-there-a-decorator-to-simply-cache-function-return-values + + :param is_userland: on ./run, we detect if userland based on --userland. However, ./test-user-mode + does not take --userland, and that causes problems. ''' def __init__( self, *args, + is_userland=False, defaults=None, supported_archs=None, **kwargs @@ -171,6 +175,7 @@ class LkmcCliFunction(cli_function.CliFunction): kwargs['extra_config_params'] = os.path.basename(inspect.getfile(self.__class__)) if defaults is None: defaults = {} + self._is_userland = is_userland self._defaults = defaults self._is_common = True self._common_args = set() @@ -1199,7 +1204,7 @@ lunch aosp_{}-eng continue else: raise Exception('native emulator only supported in if target arch == host arch') - if env['userland'] is None: + if env['userland'] is None and not self._is_userland: if real_all_emulators: continue else: diff --git a/lkmc/add.c b/lkmc/c/add.c similarity index 100% rename from lkmc/add.c rename to lkmc/c/add.c diff --git a/lkmc/add.py b/lkmc/c/add.py similarity index 100% rename from lkmc/add.py rename to lkmc/c/add.py diff --git a/lkmc/assert_fail.c b/lkmc/c/assert_fail.c similarity index 100% rename from lkmc/assert_fail.c rename to lkmc/c/assert_fail.c diff --git a/lkmc/c/getchar.c b/lkmc/c/getchar.c new file mode 100644 index 0000000..2430e29 --- /dev/null +++ b/lkmc/c/getchar.c @@ -0,0 +1,21 @@ +/* Get on character from stdin, and then print it back out. + * + * Same as getc(stdin). + * + * You have to press enter for the character to go through: + * https://stackoverflow.com/questions/1798511/how-to-avoid-pressing-enter-with-getchar + * + * Used at: + * https://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1/53937376#53937376 + */ + +#include +#include + +int main(void) { + char c; + printf("enter a character: "); + c = getchar(); + printf("you entered: %c\n", c); + return EXIT_SUCCESS; +} diff --git a/lkmc/hello.c b/lkmc/c/hello.c similarity index 100% rename from lkmc/hello.c rename to lkmc/c/hello.c diff --git a/lkmc/c/infinite_loop.c b/lkmc/c/infinite_loop.c new file mode 100644 index 0000000..2ae905f --- /dev/null +++ b/lkmc/c/infinite_loop.c @@ -0,0 +1,29 @@ +/* Loop infinitely. Print an integer whenever a period is reached: + * + * .... + * ./infinite_loop [period] + * .... + */ + +#include +#include +#include +#include + +int main(int argc, char **argv) { + uintmax_t i, j, period; + if (argc > 1) { + period = strtoumax(argv[1], NULL, 10); + } else { + period = 100000000; + } + i = 0; + j = 0; + while (1) { + i++; + if (i % period == 0) { + printf("%ju\n", j); + j++; + } + } +} diff --git a/lkmc/c/stderr.c b/lkmc/c/stderr.c new file mode 100644 index 0000000..b43d067 --- /dev/null +++ b/lkmc/c/stderr.c @@ -0,0 +1,7 @@ +/* Print hello to stderr. */ + +#include + +int main(void) { + fputs("hello\n", stderr); +} diff --git a/path_properties.py b/path_properties.py index 703a825..c13f467 100644 --- a/path_properties.py +++ b/path_properties.py @@ -258,9 +258,14 @@ path_properties_tuples = ( ) } ), - 'assert_fail.c': {'exit_status': 134}, + 'c': ( + {}, + { + 'assert_fail.c': {'exit_status': 134}, + 'infinite_loop.c': {'more_than_1s': True}, + } + ), 'exit1.c': {'exit_status': 1}, - 'infinite_loop.c': {'more_than_1s': True}, 'lib': {'no_executable': True}, 'getchar.c': {'interactive': True}, 'return1.c': {'exit_status': 1}, diff --git a/submodules/gem5 b/submodules/gem5 index 1bfc29b..c4cc314 160000 --- a/submodules/gem5 +++ b/submodules/gem5 @@ -1 +1 @@ -Subproject commit 1bfc29b0592eb040a01d7977a14191c3d3d46c51 +Subproject commit c4cc3145cd1eeed236b5cd3f7b2424bc0761878e diff --git a/test-user-mode b/test-user-mode index a811df0..912b5fa 100755 --- a/test-user-mode +++ b/test-user-mode @@ -17,7 +17,7 @@ TODO: expose all userland relevant ./run args here as well somehow. ''' if not 'defaults' in kwargs: kwargs['defaults'] = {} - super().__init__(*args, **kwargs) + super().__init__(*args, is_userland=True, **kwargs) self.add_argument( 'tests', nargs='*', diff --git a/userland/c/add.c b/userland/c/add.c new file mode 120000 index 0000000..46def32 --- /dev/null +++ b/userland/c/add.c @@ -0,0 +1 @@ +../../lkmc/c/add.c \ No newline at end of file diff --git a/userland/c/add.py b/userland/c/add.py new file mode 120000 index 0000000..fb5788a --- /dev/null +++ b/userland/c/add.py @@ -0,0 +1 @@ +../../lkmc/c/add.py \ No newline at end of file diff --git a/userland/c/assert_fail.c b/userland/c/assert_fail.c index c1c99d6..904602c 120000 --- a/userland/c/assert_fail.c +++ b/userland/c/assert_fail.c @@ -1 +1 @@ -../../lkmc/assert_fail.c \ No newline at end of file +../../lkmc/c/assert_fail.c \ No newline at end of file diff --git a/userland/c/getchar.c b/userland/c/getchar.c deleted file mode 100644 index 2430e29..0000000 --- a/userland/c/getchar.c +++ /dev/null @@ -1,21 +0,0 @@ -/* Get on character from stdin, and then print it back out. - * - * Same as getc(stdin). - * - * You have to press enter for the character to go through: - * https://stackoverflow.com/questions/1798511/how-to-avoid-pressing-enter-with-getchar - * - * Used at: - * https://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1/53937376#53937376 - */ - -#include -#include - -int main(void) { - char c; - printf("enter a character: "); - c = getchar(); - printf("you entered: %c\n", c); - return EXIT_SUCCESS; -} diff --git a/userland/c/getchar.c b/userland/c/getchar.c new file mode 120000 index 0000000..8216384 --- /dev/null +++ b/userland/c/getchar.c @@ -0,0 +1 @@ +../../lkmc/c/getchar.c \ No newline at end of file diff --git a/userland/c/hello.c b/userland/c/hello.c index 1a462a6..3f0a531 120000 --- a/userland/c/hello.c +++ b/userland/c/hello.c @@ -1 +1 @@ -../../lkmc/hello.c \ No newline at end of file +../../lkmc/c/hello.c \ No newline at end of file diff --git a/userland/c/infinite_loop.c b/userland/c/infinite_loop.c deleted file mode 100644 index 2ae905f..0000000 --- a/userland/c/infinite_loop.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Loop infinitely. Print an integer whenever a period is reached: - * - * .... - * ./infinite_loop [period] - * .... - */ - -#include -#include -#include -#include - -int main(int argc, char **argv) { - uintmax_t i, j, period; - if (argc > 1) { - period = strtoumax(argv[1], NULL, 10); - } else { - period = 100000000; - } - i = 0; - j = 0; - while (1) { - i++; - if (i % period == 0) { - printf("%ju\n", j); - j++; - } - } -} diff --git a/userland/c/infinite_loop.c b/userland/c/infinite_loop.c new file mode 120000 index 0000000..faa4cdd --- /dev/null +++ b/userland/c/infinite_loop.c @@ -0,0 +1 @@ +../../lkmc/c/infinite_loop.c \ No newline at end of file diff --git a/userland/c/stderr.c b/userland/c/stderr.c deleted file mode 100644 index b43d067..0000000 --- a/userland/c/stderr.c +++ /dev/null @@ -1,7 +0,0 @@ -/* Print hello to stderr. */ - -#include - -int main(void) { - fputs("hello\n", stderr); -} diff --git a/userland/c/stderr.c b/userland/c/stderr.c new file mode 120000 index 0000000..1344887 --- /dev/null +++ b/userland/c/stderr.c @@ -0,0 +1 @@ +../../lkmc/c/stderr.c \ No newline at end of file diff --git a/userland/lkmc/README.adoc b/userland/lkmc/README.adoc deleted file mode 100644 index f06563e..0000000 --- a/userland/lkmc/README.adoc +++ /dev/null @@ -1 +0,0 @@ -Testing mostly infrastructure of this repository rather than anything else. diff --git a/userland/lkmc/add.c b/userland/lkmc/add.c deleted file mode 120000 index 01339d7..0000000 --- a/userland/lkmc/add.c +++ /dev/null @@ -1 +0,0 @@ -../../lkmc/add.c \ No newline at end of file diff --git a/userland/lkmc/add.py b/userland/lkmc/add.py deleted file mode 120000 index 6c162bc..0000000 --- a/userland/lkmc/add.py +++ /dev/null @@ -1 +0,0 @@ -../../lkmc/add.py \ No newline at end of file