mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
baremetal: symlink all programs that currently run on both userland and baremetal
This commit is contained in:
74
README.adoc
74
README.adoc
@@ -755,7 +755,7 @@ Or to run a baremetal example instead:
|
|||||||
....
|
....
|
||||||
./run \
|
./run \
|
||||||
--arch aarch64 \
|
--arch aarch64 \
|
||||||
--baremetal baremetal/hello.c \
|
--baremetal baremetal/c/hello.c \
|
||||||
--qemu-which host \
|
--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/<arch>/` generates a separate baremetal image.
|
Every `.c` file inside link:baremetal/[] and `.S` file inside `baremetal/arch/<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
|
./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:
|
The terminal prints:
|
||||||
@@ -1238,14 +1238,14 @@ echo $?
|
|||||||
To modify a baremetal program, simply edit the file, e.g.
|
To modify a baremetal program, simply edit the file, e.g.
|
||||||
|
|
||||||
....
|
....
|
||||||
vim baremetal/hello.c
|
vim baremetal/c/hello.c
|
||||||
....
|
....
|
||||||
|
|
||||||
and rebuild:
|
and rebuild:
|
||||||
|
|
||||||
....
|
....
|
||||||
./build-baremetal --arch aarch64
|
./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.
|
`./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:
|
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
|
./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
|
./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 <<qemu-buildroot-setup,as usual>> open a shell with:
|
and then <<qemu-buildroot-setup,as usual>> open a shell with:
|
||||||
@@ -1281,7 +1281,7 @@ and then <<qemu-buildroot-setup,as usual>> open a shell with:
|
|||||||
Or as usual, <<tmux>> users can do both in one go with:
|
Or as usual, <<tmux>> 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: <<gem5-baremetal-carriage-return>>.
|
TODO: the carriage returns are a bit different than in QEMU, see: <<gem5-baremetal-carriage-return>>.
|
||||||
@@ -1289,8 +1289,8 @@ TODO: the carriage returns are a bit different than in QEMU, see: <<gem5-baremet
|
|||||||
Note that `./build-baremetal` requires the `--emulator gem5` option, and generates separate executable images for both, as can be seen from:
|
Note that `./build-baremetal` requires the `--emulator gem5` option, and generates separate executable images for both, as can be seen from:
|
||||||
|
|
||||||
....
|
....
|
||||||
echo "$(./getvar --arch aarch64 --baremetal baremetal/hello.c --emulator qemu image)"
|
echo "$(./getvar --arch aarch64 --baremetal baremetal/c/hello.c --emulator qemu image)"
|
||||||
echo "$(./getvar --arch aarch64 --baremetal baremetal/hello.c --emulator gem5 image)"
|
echo "$(./getvar --arch aarch64 --baremetal baremetal/c/hello.c --emulator gem5 image)"
|
||||||
....
|
....
|
||||||
|
|
||||||
This is unlike the Linux kernel that has a single image for both QEMU and gem5:
|
This is unlike the Linux kernel that has a single image for both QEMU and gem5:
|
||||||
@@ -1306,14 +1306,14 @@ The reason for that is that on baremetal we don't parse the <<device-tree,device
|
|||||||
|
|
||||||
....
|
....
|
||||||
./build-baremetal --arch aarch64 --emulator gem5 --machine RealViewPBX
|
./build-baremetal --arch aarch64 --emulator gem5 --machine RealViewPBX
|
||||||
./run --arch aarch64 --baremetal baremetal/hello.c --emulator gem5 --machine RealViewPBX
|
./run --arch aarch64 --baremetal baremetal/c/hello.c --emulator gem5 --machine RealViewPBX
|
||||||
....
|
....
|
||||||
|
|
||||||
This generates yet new separate images with new magic constants:
|
This generates yet new separate images with new magic constants:
|
||||||
|
|
||||||
....
|
....
|
||||||
echo "$(./getvar --arch aarch64 --baremetal baremetal/hello.c --emulator gem5 --machine VExpress_GEM5_V1 image)"
|
echo "$(./getvar --arch aarch64 --baremetal baremetal/c/hello.c --emulator gem5 --machine VExpress_GEM5_V1 image)"
|
||||||
echo "$(./getvar --arch aarch64 --baremetal baremetal/hello.c --emulator gem5 --machine RealViewPBX image)"
|
echo "$(./getvar --arch aarch64 --baremetal baremetal/c/hello.c --emulator gem5 --machine RealViewPBX image)"
|
||||||
....
|
....
|
||||||
|
|
||||||
But just stick to newer and better `VExpress_GEM5_V1` unless you have a good reason to use `RealViewPBX`.
|
But just stick to newer and better `VExpress_GEM5_V1` unless you have a good reason to use `RealViewPBX`.
|
||||||
@@ -12685,7 +12685,7 @@ Guaranteed undefined! Therefore raise illegal instruction signal. Used by GCC `_
|
|||||||
* link:userland/arch/arm/udf.S[]
|
* link:userland/arch/arm/udf.S[]
|
||||||
* link:userland/arch/aarch64/udf.S[]
|
* link:userland/arch/aarch64/udf.S[]
|
||||||
|
|
||||||
TODO: why GNU GAS 2.29 does not have a mnemonic for it?
|
Why GNU GAS 2.29 does not have a mnemonic for it in A64 because it is very recent: shows in [[armarm8-db]] but not `ca`.
|
||||||
|
|
||||||
=== ARM SIMD
|
=== ARM SIMD
|
||||||
|
|
||||||
@@ -12932,12 +12932,30 @@ https://static.docs.arm.com/ddi0487/ca/DDI0487C_a_armv8_arm.pdf
|
|||||||
|
|
||||||
Latest version: https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile
|
Latest version: https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile
|
||||||
|
|
||||||
|
Versions are determined by two letteres in lexicographical order, e.g.:
|
||||||
|
|
||||||
|
* a
|
||||||
|
* af
|
||||||
|
* aj
|
||||||
|
* aj
|
||||||
|
* b
|
||||||
|
* ba
|
||||||
|
* bb
|
||||||
|
* ca
|
||||||
|
|
||||||
|
The link: https://static.docs.arm.com/ddi0487/ca/DDI0487C_a_armv8_arm.pdf is the `ca` version for example.
|
||||||
|
|
||||||
The official comprehensive ARMv8 reference.
|
The official comprehensive ARMv8 reference.
|
||||||
|
|
||||||
ISA quick references can be found in some places:
|
ISA quick references can be found in some places:
|
||||||
|
|
||||||
* https://web.archive.org/web/20161009122630/http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001m/QRC0001_UAL.pdf
|
* https://web.archive.org/web/20161009122630/http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001m/QRC0001_UAL.pdf
|
||||||
|
|
||||||
|
[[armarm8-db]]
|
||||||
|
===== ARMv8 architecture reference manual db
|
||||||
|
|
||||||
|
https://static.docs.arm.com/ddi0487/db/DDI0487D_b_armv8_arm.pdf
|
||||||
|
|
||||||
[[armv8-programmers-guide]]
|
[[armv8-programmers-guide]]
|
||||||
===== Programmer's Guide for ARMv8-A
|
===== Programmer's Guide for ARMv8-A
|
||||||
|
|
||||||
@@ -12962,19 +12980,19 @@ Except that is is even cooler here since we can easily control and understand ev
|
|||||||
For example, on the first shell:
|
For example, on the first shell:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --arch arm --baremetal baremetal/hello.c --gdb-wait
|
./run --arch arm --baremetal baremetal/c/hello.c --gdb-wait
|
||||||
....
|
....
|
||||||
|
|
||||||
then on the second shell:
|
then on the second shell:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run-gdb --arch arm --baremetal baremetal/hello.c -- main
|
./run-gdb --arch arm --baremetal baremetal/c/hello.c -- main
|
||||||
....
|
....
|
||||||
|
|
||||||
Or if you are a <<tmux,tmux pro>>, do everything in one go with:
|
Or if you are a <<tmux,tmux pro>>, 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 <<baremetal-bootloaders>>:
|
Alternatively, to start from the very first executed instruction of our tiny <<baremetal-bootloaders>>:
|
||||||
@@ -12982,13 +13000,13 @@ Alternatively, to start from the very first executed instruction of our tiny <<b
|
|||||||
....
|
....
|
||||||
./run \
|
./run \
|
||||||
--arch arm \
|
--arch arm \
|
||||||
--baremetal baremetal/hello.c \
|
--baremetal baremetal/c/hello.c \
|
||||||
--gdb-wait \
|
--gdb-wait \
|
||||||
--tmux-args=--no-continue \
|
--tmux-args=--no-continue \
|
||||||
;
|
;
|
||||||
....
|
....
|
||||||
|
|
||||||
Now you can just `stepi` to when jumping into main to go to the C code in link:baremetal/hello.c[].
|
Now you can just `stepi` to when jumping into main to go to the C code in link:baremetal/c/hello.c[].
|
||||||
|
|
||||||
This is specially interesting for the executables that don't use the bootloader from under `baremetal/arch/<arch>/no_bootloader/*.S`, e.g.:
|
This is specially interesting for the executables that don't use the bootloader from under `baremetal/arch/<arch>/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
|
sudo apt-get install gcc-arm-none-eabi qemu-system-arm
|
||||||
./build-baremetal --arch arm --gcc-which host-baremetal
|
./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:
|
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:
|
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:
|
Then inside GDB:
|
||||||
@@ -13720,12 +13738,12 @@ Source: link:test-baremetal[]
|
|||||||
Analogously to <<user-mode-tests>>, we can select individual tests or directories with:
|
Analogously to <<user-mode-tests>>, 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:
|
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/[]
|
* all tests under the directory: link:baremetal/arch/aarch64/no_bootloader/[]
|
||||||
|
|
||||||
We detect if tests failed by parsing logs for the <<magic-failure-string>>.
|
We detect if tests failed by parsing logs for the <<magic-failure-string>>.
|
||||||
@@ -15097,14 +15115,14 @@ Sources:
|
|||||||
If a test fails, re-run the test commands manually and use `--verbose` to understand what happened:
|
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 --arch arm --background --baremetal baremetal/c/add.c --gdb-wait &
|
||||||
./run-gdb --arch arm --baremetal baremetal/add.c --verbose -- main
|
./run-gdb --arch arm --baremetal baremetal/c/add.c --verbose -- main
|
||||||
....
|
....
|
||||||
|
|
||||||
and possibly repeat the GDB steps manually with the usual:
|
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 <<gem5-tracing,tracing>> options:
|
To debug GDB problems on gem5, you might want to enable the following <<gem5-tracing,tracing>> options:
|
||||||
@@ -15112,7 +15130,7 @@ To debug GDB problems on gem5, you might want to enable the following <<gem5-tra
|
|||||||
....
|
....
|
||||||
./run \
|
./run \
|
||||||
--arch arm \
|
--arch arm \
|
||||||
--baremetal baremetal/add.c \
|
--baremetal baremetal/c/add.c \
|
||||||
--gdb-wait \
|
--gdb-wait \
|
||||||
--trace GDBRecv,GDBSend \
|
--trace GDBRecv,GDBSend \
|
||||||
--trace-stdout \
|
--trace-stdout \
|
||||||
@@ -15163,7 +15181,7 @@ So setup this `on_exit` automatically from all our <<baremetal-bootloaders>>, so
|
|||||||
+
|
+
|
||||||
The following examples end up testing that our setup is working:
|
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/return1.c[]
|
||||||
* link:baremetal/return2.c[]
|
* link:baremetal/return2.c[]
|
||||||
* link:baremetal/exit0.c[]
|
* link:baremetal/exit0.c[]
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
../lkmc/add.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../lkmc/add.py
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../lkmc/assert_fail.c
|
|
||||||
1
baremetal/c/add.c
Symbolic link
1
baremetal/c/add.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/add.c
|
||||||
1
baremetal/c/add.py
Symbolic link
1
baremetal/c/add.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/add.py
|
||||||
1
baremetal/c/assert_fail.c
Symbolic link
1
baremetal/c/assert_fail.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/assert_fail.c
|
||||||
1
baremetal/c/hello.c
Symbolic link
1
baremetal/c/hello.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/hello.c
|
||||||
1
baremetal/c/infinite_loop.c
Symbolic link
1
baremetal/c/infinite_loop.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/infinite_loop.c
|
||||||
1
baremetal/c/stderr.c
Symbolic link
1
baremetal/c/stderr.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/stderr.c
|
||||||
@@ -1 +0,0 @@
|
|||||||
../lkmc/hello.c
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
int main(void) {
|
|
||||||
while(1) {}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,17 @@
|
|||||||
/* Test that input request through serial also works. */
|
/* Test out of memory. */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
char c;
|
|
||||||
char *ptr = NULL;
|
char *ptr = NULL;
|
||||||
size_t alloc_size = 1;
|
size_t alloc_size = 1;
|
||||||
while (1) {
|
while (1) {
|
||||||
printf("enter a character\n");
|
|
||||||
c = getchar();
|
|
||||||
printf("got: %c\n", c);
|
|
||||||
ptr = realloc(ptr, alloc_size);
|
ptr = realloc(ptr, alloc_size);
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
puts("out of memory");
|
puts("out of memory");
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
printf("new alloc of %zu bytes at address 0x%p\n", alloc_size, ptr);
|
|
||||||
alloc_size <<= 1;
|
alloc_size <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
6
bisect-gem5-gdb
Executable file
6
bisect-gem5-gdb
Executable file
@@ -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
|
||||||
@@ -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 +
|
It would be beautiful to do this evaluation in a lazy way, e.g. with functions +
|
||||||
cache decorators:
|
cache decorators:
|
||||||
https://stackoverflow.com/questions/815110/is-there-a-decorator-to-simply-cache-function-return-values
|
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__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*args,
|
*args,
|
||||||
|
is_userland=False,
|
||||||
defaults=None,
|
defaults=None,
|
||||||
supported_archs=None,
|
supported_archs=None,
|
||||||
**kwargs
|
**kwargs
|
||||||
@@ -171,6 +175,7 @@ class LkmcCliFunction(cli_function.CliFunction):
|
|||||||
kwargs['extra_config_params'] = os.path.basename(inspect.getfile(self.__class__))
|
kwargs['extra_config_params'] = os.path.basename(inspect.getfile(self.__class__))
|
||||||
if defaults is None:
|
if defaults is None:
|
||||||
defaults = {}
|
defaults = {}
|
||||||
|
self._is_userland = is_userland
|
||||||
self._defaults = defaults
|
self._defaults = defaults
|
||||||
self._is_common = True
|
self._is_common = True
|
||||||
self._common_args = set()
|
self._common_args = set()
|
||||||
@@ -1199,7 +1204,7 @@ lunch aosp_{}-eng
|
|||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
raise Exception('native emulator only supported in if target arch == host arch')
|
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:
|
if real_all_emulators:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
|||||||
21
lkmc/c/getchar.c
Normal file
21
lkmc/c/getchar.c
Normal file
@@ -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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
char c;
|
||||||
|
printf("enter a character: ");
|
||||||
|
c = getchar();
|
||||||
|
printf("you entered: %c\n", c);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
29
lkmc/c/infinite_loop.c
Normal file
29
lkmc/c/infinite_loop.c
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/* Loop infinitely. Print an integer whenever a period is reached:
|
||||||
|
*
|
||||||
|
* ....
|
||||||
|
* ./infinite_loop [period]
|
||||||
|
* ....
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
lkmc/c/stderr.c
Normal file
7
lkmc/c/stderr.c
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/* Print hello to stderr. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
fputs("hello\n", stderr);
|
||||||
|
}
|
||||||
@@ -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},
|
'exit1.c': {'exit_status': 1},
|
||||||
'infinite_loop.c': {'more_than_1s': True},
|
|
||||||
'lib': {'no_executable': True},
|
'lib': {'no_executable': True},
|
||||||
'getchar.c': {'interactive': True},
|
'getchar.c': {'interactive': True},
|
||||||
'return1.c': {'exit_status': 1},
|
'return1.c': {'exit_status': 1},
|
||||||
|
|||||||
Submodule submodules/gem5 updated: 1bfc29b059...c4cc3145cd
@@ -17,7 +17,7 @@ TODO: expose all userland relevant ./run args here as well somehow.
|
|||||||
'''
|
'''
|
||||||
if not 'defaults' in kwargs:
|
if not 'defaults' in kwargs:
|
||||||
kwargs['defaults'] = {}
|
kwargs['defaults'] = {}
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, is_userland=True, **kwargs)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'tests',
|
'tests',
|
||||||
nargs='*',
|
nargs='*',
|
||||||
|
|||||||
1
userland/c/add.c
Symbolic link
1
userland/c/add.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/add.c
|
||||||
1
userland/c/add.py
Symbolic link
1
userland/c/add.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/add.py
|
||||||
@@ -1 +1 @@
|
|||||||
../../lkmc/assert_fail.c
|
../../lkmc/c/assert_fail.c
|
||||||
@@ -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 <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
char c;
|
|
||||||
printf("enter a character: ");
|
|
||||||
c = getchar();
|
|
||||||
printf("you entered: %c\n", c);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
1
userland/c/getchar.c
Symbolic link
1
userland/c/getchar.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/getchar.c
|
||||||
@@ -1 +1 @@
|
|||||||
../../lkmc/hello.c
|
../../lkmc/c/hello.c
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/* Loop infinitely. Print an integer whenever a period is reached:
|
|
||||||
*
|
|
||||||
* ....
|
|
||||||
* ./infinite_loop [period]
|
|
||||||
* ....
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
userland/c/infinite_loop.c
Symbolic link
1
userland/c/infinite_loop.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/infinite_loop.c
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
/* Print hello to stderr. */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
fputs("hello\n", stderr);
|
|
||||||
}
|
|
||||||
1
userland/c/stderr.c
Symbolic link
1
userland/c/stderr.c
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../lkmc/c/stderr.c
|
||||||
@@ -1 +0,0 @@
|
|||||||
Testing mostly infrastructure of this repository rather than anything else.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../lkmc/add.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../lkmc/add.py
|
|
||||||
Reference in New Issue
Block a user