From fc9e0c28a546bc913a252325de37aac663246244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Thu, 8 Nov 2018 23:00:02 +0000 Subject: [PATCH] baremetal: create an assert_fail C helper Create a test for it under interactive/assert_fail.c Move prompt under interactive Create baremetal/arch/aarch64/c_from_as.S as an example of calling C functions from assembly. --- README.adoc | 34 ++++++++++++++-------------- baremetal/arch/aarch64/c_from_as.S | 5 ++++ baremetal/interactive/assert_fail.c | 6 +++++ baremetal/{ => interactive}/prompt.c | 0 baremetal/lib/common.c | 6 +++++ baremetal/lib/common.h | 4 ++++ build-baremetal | 1 + 7 files changed, 39 insertions(+), 17 deletions(-) create mode 100644 baremetal/arch/aarch64/c_from_as.S create mode 100644 baremetal/interactive/assert_fail.c rename baremetal/{ => interactive}/prompt.c (100%) create mode 100644 baremetal/lib/common.h diff --git a/README.adoc b/README.adoc index 56c11a7..8a5eb97 100644 --- a/README.adoc +++ b/README.adoc @@ -739,10 +739,10 @@ QEMU: ./build-qemu --arch arm && \ ./build-crosstool-ng --arch arm && \ ./build-baremetal --arch arm && \ -./run --arch arm --baremetal prompt +./run --arch arm --baremetal interactive/prompt .... -You are now left inside QEMU running the tiny baremetal system link:baremetal/prompt.c[], which uses the UART to: +You are now left inside QEMU running the tiny baremetal system link:baremetal/interactive/prompt.c[], which uses the UART to: * print characters to the terminal * read characters from your keyboard @@ -798,7 +798,7 @@ patch -d "$(./getvar gem5_src_dir)" -p 1 < patches/manual/gem5-semihost.patch ./build-gem5 --arch arm ./build-crosstool-ng --arch arm ./build-baremetal --arch arm --gem5 -./run --arch arm --baremetal prompt --gem5 +./run --arch arm --baremetal interactive/prompt --gem5 .... and then <> open a shell with: @@ -814,8 +814,8 @@ The semihosting patch is required to enable <>, on which base funct Note that `./build-baremetal` requires the `--gem5` option, and generates separate executable images for both, as can be seen from: .... -echo "$(./getvar --arch aarch64 --baremetal prompt image)" -echo "$(./getvar --arch aarch64 --baremetal prompt --gem5 image)" +echo "$(./getvar --arch aarch64 --baremetal interactive/prompt image)" +echo "$(./getvar --arch aarch64 --baremetal interactive/prompt --gem5 image)" .... This is unlike the Linux kernel that has a single image for both QEMU and gem5: @@ -831,14 +831,14 @@ The reason for that is that on baremetal we don't parse the <>. Typing now shows nothing because that prompt is expecting input from `ttyS1`. -Instad, we connect to the serial port `ttyS1` with GDB: +Instead, we connect to the serial port `ttyS1` with GDB: .... ./run-gdb --kgdb --no-continue @@ -10155,18 +10155,18 @@ GDB step debug works on baremetal exactly as it does on the Linux kernel, except For example, on the first shell: .... -./run --arch arm --baremetal prompt --wait-gdb +./run --arch arm --baremetal interactive/prompt --wait-gdb .... then on the second shell: .... -./run-gdb --arch arm --baremetal prompt --no-continue +./run-gdb --arch arm --baremetal interactive/prompt --no-continue .... and now we are left at the very first executed instruction of our tiny bootloader: link:baremetal/lib/arm.S[] -Then just use `stepi` to when jumping into main to go to the C code in link:baremetal/prompt.c[]. +Then just use `stepi` to when jumping into main to go to the C code in link:baremetal/interactive/prompt.c[]. The bootloader is used to put the hardware in its main operating mode before we run our main payload on it. @@ -10179,19 +10179,19 @@ You can also find executables that don't use the bootloader at all under `bareme Alternatively, skip directly to the C program main function with: .... -./run-gdb --arch arm --baremetal prompt main +./run-gdb --arch arm --baremetal interactive/prompt main .... and then proceed as usual: .... -./run --arch arm --baremetal prompt --wait-gdb --gem5 +./run --arch arm --baremetal interactive/prompt --wait-gdb --gem5 .... and on another shell: .... -./run-gdb --arch arm --baremetal prompt --gem5 --no-continue +./run-gdb --arch arm --baremetal interactive/prompt --gem5 --no-continue .... `aarch64` GDB step debug is broken as mentioned at: <>. @@ -10284,7 +10284,7 @@ For `arm`, some baremetal examples compile fine with: .... sudo apt-get install gcc-arm-none-eabi qemu-system-arm ./build-baremetal --arch arm --prebuilt -./run --arch arm --baremetal prompt --prebuilt +./run --arch arm --baremetal interactive/prompt --prebuilt .... However, there are as usual limitations to using prebuilts: @@ -10313,7 +10313,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 prompt --sim +./run-gdb --arch arm --baremetal interactive/prompt --sim .... Then inside GDB: diff --git a/baremetal/arch/aarch64/c_from_as.S b/baremetal/arch/aarch64/c_from_as.S new file mode 100644 index 0000000..8359afb --- /dev/null +++ b/baremetal/arch/aarch64/c_from_as.S @@ -0,0 +1,5 @@ +/* Call a C function. */ +.global main +main: + mov x0, #0 + bl exit diff --git a/baremetal/interactive/assert_fail.c b/baremetal/interactive/assert_fail.c new file mode 100644 index 0000000..b2a70cc --- /dev/null +++ b/baremetal/interactive/assert_fail.c @@ -0,0 +1,6 @@ +#include + +void main(void) { + assert_fail(); +} + diff --git a/baremetal/prompt.c b/baremetal/interactive/prompt.c similarity index 100% rename from baremetal/prompt.c rename to baremetal/interactive/prompt.c diff --git a/baremetal/lib/common.c b/baremetal/lib/common.c index b6a3e33..fa1c79d 100644 --- a/baremetal/lib/common.c +++ b/baremetal/lib/common.c @@ -1,3 +1,4 @@ +#include #include enum { @@ -76,3 +77,8 @@ void _exit(int status) { ); #endif } + +void assert_fail() { + puts("lkmc_test_fail"); + exit(1); +} diff --git a/baremetal/lib/common.h b/baremetal/lib/common.h new file mode 100644 index 0000000..3e80696 --- /dev/null +++ b/baremetal/lib/common.h @@ -0,0 +1,4 @@ +#ifndef COMMON_H +#define COMMON_H +void assert_fail(); +#endif diff --git a/build-baremetal b/build-baremetal index 37d0cf1..08cf271 100755 --- a/build-baremetal +++ b/build-baremetal @@ -15,6 +15,7 @@ class BaremetalComponent(common.Component): '-mcpu={}'.format(common.mcpu), common.Newline, '-nostartfiles', common.Newline, '-O0', common.Newline, + '-I', common.baremetal_src_lib_dir, common.Newline, ] if args.prebuilt: gcc = 'arm-none-eabi-gcc'