diff --git a/BUILD.md b/BUILD.md
index 67f6f8508..ddf271127 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -2,21 +2,6 @@
# Build BitBox02 firmware and bootloader
-## Dependencies
-
-- [HIDAPI](https://github.com/signal11/hidapi)
-- [GNU ARM Embedded Toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads)
-- SEGGER J-Link software
- - [All packages and versions](https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack)
- - Newer versions should work, but if not, go to "Older versions" and get version 6.34g
- - [OSX package](https://www.segger.com/downloads/jlink/JLink_MacOSX_V630d.pkg)
- - [Linux 64bit](https://www.segger.com/downloads/jlink/JLink_Linux_x86_64.tgz)
- - [others](https://www.segger.com/downloads/jlink/)
-- cmake
-- git
-- Install the pre-built [protobuf python binary](https://github.com/protocolbuffers/protobuf/releases)
- - Then install the included [Python Protocol Buffers](https://github.com/protocolbuffers/protobuf/tree/master/python#installation) runtime library
-
## Reporting issues
@@ -25,99 +10,170 @@ For security related issues please see [SECURITY.md](SECURITY.md).
## Development environment
-### Install development environment as a Docker container
+There is a container image with all the build dependencies and there are some
+`make` shortcuts to use it.
-The container will contain all tools needed to build the project but it is still necessary to get
-the J-Link software to flash the bootloader. Run the commands below to build the container and
-execute a persistent one.
+> [!TIP]
+> It is highly recommended to use the container for development.
-```sh
-make dockerinit
-make dockerdev
-```
+Accessing USB devices, like the flashing tool and the bitbox, is easier outside
+of the container. So it is recommended to install the J-Link Software on your
+development machine to follow the instructions below.
+
+### Development Dependencies*
+
+| Dependency | Version** |
+| ---------- | -------- |
+| [Arm GNU Toolchain](https://developer.arm.com/downloads/-/gnu-rm) | 8-2018-q4 |
+| [HIDAPI](https://github.com/signal11/hidapi) | 0.11.2 |
+| [cmake](https://cmake.org/download/) | 3.10 |
+| [git](https://git-scm.com/downloads) | 2.34 |
+| [Protobuf Compiler](https://github.com/protocolbuffers/protobuf/releases) | 21.2 |
+| [Python Probobuf Runtime](https://github.com/protocolbuffers/protobuf/tree/master/python#installation) | 5.27.3 |
+| [SEGGER J-Link Software and Documentation Pack](https://www.segger.com/downloads/jlink) | 6.34g |
+| Graphviz | 2.42.2 |
+| Doxygen | 1.9.1 |
+| [cmocka](https://cmocka.org/files/1.1/) | 1.1.5 |
+
+* See the complete list of dependences in the Dockerfile.
+
+** The versions here are known to be working. Newer versions should
+work.
+
+### Setup containerized environment
+
+`make dockerpull` will use `docker pull` to fetch the current container image.
+`make dockerdev` will use `docker run` and `docker exec` to run a container in
+the background and enter it.
+
+> [!NOTE]
+> The current development container is defined in the file `.containerversion`
-If you do not want to build the docker image locally, or are not working on it, it may be more straightforward to
-pull the image from docker instead of building it. This should be a bit faster and there should not be any issues with
-`make dockerdev` expecting specific version of the image.
+`make dockerdev` will mount the project root outside
+the container to the same path inside the container so that you can use your
+preferred editor/IDE outside the container and so that compiler errors have the
+right file paths.
+
+> [!IMPORTANT]
+> `make dockerdev` will enter an already running container if it exists.
```sh
make dockerpull
make dockerdev
```
+`make dockerinit` is a shortcut to run `docker build` if you need to update the
+container image (`Dockerfile`). Don't forget to update the `.containerversion`
+file.
-The docker container will not allow you to access the hosts USB devices by default which means that
-it is necessary to flash the device in a terminal not running in docker.
-
-> [!NOTE]
-> Current development container is defined in the file `.containerversion`
+```sh
+make dockerinit
+```
-The docker container mounts the repo it was launched from, so you can freely edit your fork in your preferred IDE and
-the changes will be reflected in the docker container.
+### Setup development environment on macOS with brew
-**It is highly recommended you develop using this docker container as not all of local setup is completely up to date
-with every Operating system.**
+> [!CAUTION]
+> Brew usually only supports the latest versions of software packages. It is
+> not easy to get a working development environment using brew. CI uses the
+> development container so it will be additional work getting CI to pass.
-### Install development environment on macOS
+> [!IMPORTANT]
+> If you use compiler versions different from CI and everyone else you will not
+> be able to reproducibly build the firmware.
-Make sure you have [Homebrew](https://brew.sh) installed.
-Install the dependencies with:
+Make sure you have [Homebrew](https://brew.sh) installed. Install the
+dependencies with:
```sh
-brew install hidapi cmake protobuf
-brew install automake libtool # for building some code in the external/ folder
+brew install hidapi cmake protobuf@21
+brew install automake libtool
brew tap osx-cross/arm
brew install arm-gcc-bin
```
-## Simulator
+## Contributor instructions
-The Multi edition firmware can be built as a simulator for linux-amd64. To build it, run:
+### Check out the repository
- make -j simulator
+#### 1. Fork the repository on github.
-Run it with:
+Go to [bitbox02-firmware](https://github.com/bitboxswiss/bitbox02-firmware) and fork the repository.
- ./build-build/bin/simulator
+#### 2. Check out your fork
-This launches a server simulating the firmware. The send_message tool can connect to it with:
+Run the following commands to check out your fork:
- ./py/send_message.py --simulator
+```sh
+git clone --recurse-submodules git@github.com:/bitbox02-firmware.git
+cd bitbox02-firmware
+```
-If you choose to create a wallet by restoring a mnemonic, the simulator will automatically use this
-mnemonic:
+> [!TIP]
+> If you have already cloned the repository without the `--recurse-submodules`
+> argument, run:
+>
+> ```sh
+> git submodule update --init --recursive
+> ```
- boring mistake dish oyster truth pigeon viable emerge sort crash wire portion cannon couple enact box walk height pull today solid off enable tide
+### Build the firmware
-## Instructions
+Run the following commands to enter the container and build the firmware:
-Connect the J-Link to the debug pins on the BitBox02 prototype board.
+```sh
+make dockerdev
+make firmware
+```
+
+> [!TIP]
+> If you have multiple cores you can speed up compilation by passing `-j`, for example `-j8`.
-Plug in both the J-Link hardware and the BitBox02 device into USB ports on your computer or a hub connected to your computer.
+### Build the bootloader
-Build the firmware:
+Run the following commands to enter the container and build the bootloader:
```sh
-git clone --recurse-submodules https://github.com/BitBoxSwiss/bitbox02-firmware && cd bitbox02-firmware
-# or via ssh
-git clone --recurse-submodules git@github.com:BitBoxSwiss/bitbox02-firmware.git && cd bitbox02-firmware
-make firmware # requires a GNU ARM toolchain for cross-compiling
+make dockerdev
+make bootloader
```
-If you have already cloned the repository without the `--recurse-submodules` argument, run:
+> [!NOTE]
+> To create a bootloader for a development or a production device, use `make
+> bootloader-devdevice` or `make bootloader-production` respectively.
-```sh
-git submodule update --init --recursive
-```
+> [!NOTE]
+> To run unsigned firmwares you need a development bootloader.
-Build the bootloader:
+### Build the simulator
+
+The Multi edition firmware can be built as a simulator for linux-amd64. To build it, run:
```sh
-make bootloader
+make simulator
```
-(to create a bootloader for a devdevice or a production device, use `make bootloader-devdevice` or
-`make bootloader-production` respectively).
+### Flash instructions
+
+#### Connect J-Link probe
+
+Connect the J-Link probe to the debug pins on the BitBox02 prototype board. The
+pinout of the board and the Arm JTAG/SWD 10-pin connector can be seen in the
+table below.
+
+| Signal | Bitbox02 # | Arm JTAG/SWD # |
+| ------ | ---------- | -------------- |
+| VCC | 1 | 1 |
+| CLK | 2 | 4 |
+| GND | 3 | 3, 5 |
+| DIO | 4 | 2 |
+
+See [bitbox schematics](doc/bb02_v2.10_schematics.pdf) and [Arm JTAG/SWD
+interface](https://developer.arm.com/documentation/101636/0100/Debug-and-Trace/JTAG-SWD-Interface)
+
+Plug **both** the J-Link probe and the BitBox02 into your development machine using
+USB.
+
+#### Flash bootloader using J-Link
Load the bootloader by JLink (requires JLinkExe in PATH).
@@ -125,13 +181,11 @@ Load the bootloader by JLink (requires JLinkExe in PATH).
make jlink-flash-bootloader
```
-You need to install the [BitBox02 Python Library](#BitBox02-Python-library) before you can flash the built firmware.
-
-Load the firmware by the bootloader (requires loading bootloader.bin by JLink, if not already loaded on the device):
+> [!NOTE]
+> To flash a bootloader for a development device
+> `make jlink-flash-bootloader-development`.
-```sh
-make flash-dev-firmware
-```
+#### Flash firmware using J-Link
Load the firmware by JLink:
@@ -139,15 +193,20 @@ Load the firmware by JLink:
make jlink-flash-firmware
```
-### Build reference documentation (Doxygen)
+#### Flash firmware using bootloader and python cli client
+
+> [!TIP]
+> This method does not require a J-Link probe while developing.
+
+Install the [BitBox02 Python CLI client](#bitbox02-python-cli-client).
-Dependencies:
+Load the firmware through the bootloader:
```sh
-brew install graphviz doxygen
+make flash-dev-firmware
```
-Build:
+### Build reference documentation (Doxygen)
```sh
make docs
@@ -155,48 +214,80 @@ make docs
To view the results, open `build/docs/html/index.html` in a web browser.
-### BitBox02 Python library
+### Debugging
-There is a Python api library in `py/bitbox02`.
+#### Debugging using the simulator
-Run `pip install -r py/requirements.txt` to install the deps (virtualenv recommended).
-
-`make -C py/bitbox02` to generate the protobuf files.
-
-To kick off some api calls:
+Run it with:
```sh
-./py/send_message.py
+./build-build/bin/simulator
```
-### Unit tests
+This launches a server simulating the firmware. The send_message tool can connect to it with:
-We are using CMocka [https://cmocka.org/](https://cmocka.org/) for unit tests. To run the tests, the CMocka library
-needs to be installed on your system.
+ ./py/send_message.py --simulator
-If you're on a Mac, you can use the brew command to install it:
+If you choose to create a wallet by restoring a mnemonic, the simulator will automatically use this
+mnemonic:
+
+ boring mistake dish oyster truth pigeon viable emerge sort crash wire portion cannon couple enact box walk height pull today solid off enable tide
+
+
+#### Debugging using the J-Link probe and GDB
+
+The *debug firmware* enables pretty printing of panics over [RTT](https://www.segger.com/products/debug-probes/j-link/technology/about-real-time-transfer/).
+
+Run the following commands to build the debug firmware.
```sh
-brew install cmocka
+make dockerdev
+make firmware-debug
```
-Alternatively, you can get CMocka by cloning the git repository and following these instructions:
+Run the following command to run the J-Link GDB Server.
```sh
-git clone git://git.cryptomilk.org/projects/cmocka.git
-cd cmocka
-mkdir build && cd build
-cmake ..
-make && sudo make install
+make jlink-gdb-server
```
-By default, the library will be installed into /usr/local/lib64 directory under Linux x86\_64.
-If the library is not on the library path by default, you might need to export the following environment variable:
+> [!TIP]
+> The J-Link GDB Server can be left running in the background.
+
+Run the following command to connect with telnet to the J-Link GDB Server to
+see the RTT output.
```sh
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib64/
+make rtt-client
```
+Run the following command to run GDB. GDB will connect to the J-Link GDB
+server, flash the debug firmware and then start execution from the bootloader
+(as if the device was just plugged in).
+
+```sh
+make run
+```
+
+> [!TIP]
+> After rebuilding the firmware, exit GDB and rerun `make run` to flash and reset the device.
+
+### Unit tests
+
+CMocka [https://cmocka.org/](https://cmocka.org/) is used for mocking in the
+unit tests. To compile the tests, the CMocka library needs to be installed on
+your system. CMocka is available through most package managers, like *brew* and
+*apt*.
+
+> [!NOTE]
+> If you compiled it yourself from souce, the library will, by default, be
+> installed into **/usr/local/** directory instead of **/usr/**.
+> If the library is not on the library path by default, you might need to export
+> the following environment variable:
+> ```sh
+> export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib64/
+> ```
+
Then you can run the tests by executing
```sh
@@ -220,9 +311,26 @@ make -C build-build coverage-lcovr
### SCCache / CCache
-The build systems supports sccache/ccache, you just need to have it available in your path. You can
-install it into your dev container with the following commands:
+The build systems supports sccache/ccache, you just need to have it available
+in your path. You can install it into your dev container with the following
+commands:
```
docker exec -u 0 -it bitbox02-firmware-dev bash -c 'apt update && apt install -y libssl-dev && CARGO_HOME=/opt/cargo cargo install --locked sccache'
```
+
+## BitBox02 Python Library
+
+There is a Python api library in `py/bitbox02`.
+
+### BitBox02 CLI client
+
+Run `pip install -r py/requirements.txt` to install the deps (virtualenv recommended).
+
+`make -C py/bitbox02` to generate the protobuf files.
+
+To kick off some api calls:
+
+```sh
+./py/send_message.py
+```