diff --git a/src/ch2_03_testing_toolchain.md b/src/ch2_03_testing_toolchain.md
index c1420b7d3c4e9682ec3674e50bbe0a6428c358f9..ac19f3f7409bcf6db73e4b7e488efefebe2c90c4 100644
--- a/src/ch2_03_testing_toolchain.md
+++ b/src/ch2_03_testing_toolchain.md
@@ -1 +1,112 @@
-# Testing the toolchain
+# Testing the toolchain and device connection
+
+## Hardware
+
+Connect your STM32F401 to the computer via a mini-USB cable.
+
+Start OpenOCD
+```
+openocd -f interface/stlink.cfg -f target/stm32f4x.cfg
+```
+
+### Troubleshoot OpenOCD
+
+If OpenOCD reports no such device, double check with eg. `lsusb` on Linux if you have something like 
+
+```
+0483:3752 STMicroelectronics ST-LINK/V2.1
+```
+
+The firmware in the ST-Link can be too new for your currently installed version of OpenOCD.
+
+If this is the case, then you may have to install/compile the latest version of OpenOCD.
+
+See [OpenOCD git](https://sourceforge.net/p/openocd/code/ci/master/tree/) for complete instructions.
+
+tl;dr:
+
+```
+git://git.code.sf.net/p/openocd/code
+./bootstrap (when building from the git repository)
+./configure
+make
+sudo make install
+```
+
+### If success!
+
+The next step assumes you get the following output from OpenOCD:
+
+```
+➜ openocd -f interface/stlink.cfg -f target/stm32f4x.cfg
+Open On-Chip Debugger 0.10.0+dev-00973-g80f1a92bd (2019-12-01-00:09)
+Licensed under GNU GPL v2
+For bug reports, read
+        http://openocd.org/doc/doxygen/bugs.html
+Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
+Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
+Info : Listening on port 6666 for tcl connections
+Info : Listening on port 4444 for telnet connections
+Info : clock speed 2000 kHz
+Info : STLINK V2J33M25 (API v2) VID:PID 0483:3752
+Info : Target voltage: 3.259749
+Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
+Info : Listening on port 3333 for gdb connections
+```
+
+
+## Software
+
+Fetch the following project [https://gitlab.henriktjader.com/pln/stm32-rtfm5/tree/rtfm_start](https://gitlab.henriktjader.com/pln/stm32-rtfm5/tree/rtfm_start) 
+and switch to the `rtfm_start` branch.
+```
+git clone https://gitlab.henriktjader.com/pln/stm32-rtfm5.git
+git checkout rtfm_start
+```
+
+You can run the cargo test inside the firmware directory:
+
+```
+cd firmware
+cargo test
+cd ..
+```
+It will print that tests succeeded (hopefully).
+
+
+Inside the binary directory run `cargo run`:
+
+```
+cd binary
+cargo run
+```
+
+If everything went as expected you will see the following:
+
+```
+cargo run
+    Finished dev [optimized + debuginfo] target(s) in 0.06s
+     Running `arm-none-eabi-gdb -q -x openocd.gdb target/thumbv7em-none-eabihf/debug/app`
+Reading symbols from target/thumbv7em-none-eabihf/debug/app...
+0x08001bce in ?? ()
+semihosting is enabled
+
+Loading section .vector_table, size 0x400 lma 0x8000000
+Loading section .text, size 0x14e8 lma 0x8000400
+Loading section .rodata, size 0x49c lma 0x80018f0
+Start address 0x80017fa, load size 7556
+Transfer rate: 12 KB/sec, 2518 bytes/write.
+Temporary breakpoint 1 at 0x8000448: file src/main.rs, line 15.
+Note: automatically using hardware breakpoints for read-only addresses.
+
+Temporary breakpoint 1, main () at src/main.rs:15
+15      #[app(device = stm32f4xx_hal::stm32, peripherals = true)]
+Breakpoint 2 at 0x8000448: file src/main.rs, line 15.
+Breakpoint 3 at 0x80018e2: file /home/henrik/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.10/src/lib.rs, line 548.
+Breakpoint 4 at 0x8000eda: file src/libcore/panicking.rs, line 80.
+Section .vector_table, range 0x8000000 -- 0x8000400: matched.
+Section .text, range 0x8000400 -- 0x80018e8: matched.
+Section .rodata, range 0x80018f0 -- 0x8001d8c: matched.
+(gdb)
+```
+including some messages in the OpenOCD terminal.