diff --git a/tools/poor-profiler/README.md b/tools/poor-profiler/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..42e2e4b1750e8a4a0097940f6bbb67f405c2a079
--- /dev/null
+++ b/tools/poor-profiler/README.md
@@ -0,0 +1,37 @@
+poor-profiler
+-------------
+This is a (rather poor) attempt at building a profiler for card10.  The
+idea is based on the [poor man's profiler](https://poormansprofiler.org/).
+Essentially, it uses stack-traces gathered using GDB.  This means,
+execution will be significantly slowed down which might make certain
+features of the firmware misbehave.  Use with care!
+
+That said, here is how to use it:
+
+1. Configure the profiler by adjusting `nsamples` and `sleeptime` in
+   [`poor-profiler.sh`](https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/tools/poor-profiler/poor-profiler.sh).
+   (If anyone wants to send a patch which makes this script use proper
+   commandline args, please do!)
+2. Start profiling!  Just call
+   ```bash
+   ./tools/poor-profiler/poor-profiler.sh >/tmp/samples
+   ```
+   from the firmware repository root.
+3. Next, collapse the samples using the
+   [`poor-collapse.sh`](https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/tools/poor-profiler/poor-collapse.sh)
+   script:
+   ```bash
+   $ ./tools/poor-profiler/poor-collapse.sh /tmp/samples >/tmp/samples.collapsed
+   ```
+4. Finally, feed the collapsed samples into the Brendan Gregg's
+   [FlameGraph](https://github.com/brendangregg/FlameGraph) script which
+   will create an svg you can view (and interact with!) in your browser:
+   ```bash
+   $ /path/to/FlameGraph/flamegraph.pl /tmp/samples.collapsed >/tmp/flamegraph.svg
+   $ firefox /tmpflamegraph.svg
+   ```
+   (If you feel that a perl script is not modern enough, you can also use
+   [`inferno-flamegraph`](https://github.com/jonhoo/inferno) which is
+   written in Rust ...)
+
+Happy profiling!
diff --git a/tools/poor-profiler/poor-collapse.sh b/tools/poor-profiler/poor-collapse.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6e6af32d53d2d5472a20d4c4d3069f8fc0e2e8cf
--- /dev/null
+++ b/tools/poor-profiler/poor-collapse.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+cat "$1" | \
+    sort | \
+    uniq -c | \
+    sort -r -n -k 1,1 | \
+    sed 's/^ \+\([0-9]\+\) \(.*\)$/\2 \1/g' | \
+    sort
diff --git a/tools/poor-profiler/poor-profiler.sh b/tools/poor-profiler/poor-profiler.sh
new file mode 100755
index 0000000000000000000000000000000000000000..91179b0d2c7e8ed4737b1a60880391bff215679f
--- /dev/null
+++ b/tools/poor-profiler/poor-profiler.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+nsamples=4096
+sleeptime=0.05
+
+for x in $(seq 1 $nsamples); do
+    printf "Capturing %6u/%u ...\n" "$x" "$nsamples" >&2
+    arm-none-eabi-gdb -nx -x init.gdb -ex "set pagination 0" -ex "bt" -ex "continue&" -batch build/epicardium/epicardium.elf 2>/dev/null | \
+        grep -E '^#' | \
+        tac | \
+        sed 's/^#[0-9]\+ \+0x.* in \(.*\) (.*$/\1/g;s/^#[0-9]\+ \+\(.*\) (.*$/\1/g' | \
+        tr '\n' ';' | \
+        sed 's/^\(.*\);$/\1\n/g'
+    sleep $sleeptime
+done