diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f003c6c --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,43 @@ +name: Build + +on: + pull_request: + branches: [main, master] + push: + branches: [main, master] + +jobs: + build: + name: Build Firmware + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@v14 + + - name: Cache Nix store + uses: actions/cache@v3 + with: + path: | + ~/.cache/nix + /nix/store + key: nix-${{ runner.os }}-${{ hashFiles('flake.lock') }} + restore-keys: | + nix-${{ runner.os }}- + + - name: Build Unix simulator + run: nix develop -c make unix + + - name: Build STM32F469 Discovery firmware + run: nix develop -c make disco + + - name: Upload firmware artifacts + uses: actions/upload-artifact@v4 + with: + name: firmware-binaries + path: | + bin/specter-diy.bin + bin/specter-diy.hex diff --git a/.gitignore b/.gitignore index c6229d0..0562adc 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ release .idea .vscode .DS_Store +.direnv diff --git a/docs/build.md b/docs/build.md index cdef143..af123e5 100644 --- a/docs/build.md +++ b/docs/build.md @@ -6,11 +6,35 @@ Clone the repository recursively `git clone https://github.com/cryptoadvance/spe ## Prerequisities +There are multiple ways to get all necessary tools. The recommended way is to use the Nix flake with direnv. +If that's too complicated for you, you can use the traditional `nix-shell` or install the tools manually (which mighty be tricky to get the dependencies right). + +### Nix flake (Recommended) + +The easiest way to get all necessary tools is to use the Nix flake from the root of the repository. You need to have [Nix](https://nixos.org/) (on Mac use [determinate](https://github.com/DeterminateSystems/nix-installer)) with flakes enabled. This only works with Nix >2.7 (check with `nix --version`). +Install direnv with `brew install direnv` (on Mac) or `sudo apt install direnv` (on Linux). + +Make sure that [flakes are enabled](https://nixos.wiki/wiki/Flakes) in your Nix config. On Linux systems, your user might need to be added to the nix-users group. + +```sh +# Enter development shell +nix develop + +# Or use with direnv for automatic activation +direnv allow +``` + + ### Nix shell -The easiest way to get all necessary tools is to run `nix-shell` from the root of the repository. You need to have [Nix](https://nixos.org/) installed. +Alternatively, you can use the traditional `shell.nix`: + +```sh +nix-shell +``` +You'll need to have [Nix](https://nixos.org/) installed as well. -### Prerequisities: Board +### Prerequisities (Manually): Board To compile the firmware for the board you will need `arm-none-eabi-gcc` compiler. @@ -34,7 +58,7 @@ brew install arm-none-eabi-gcc On **Windows**: Install linux subsystem and follow Linux instructions. -### Prerequisities: Simulator +### Prerequisities (Manually): Simulator You may need to install SDL2 library to simulate the screen of the device. @@ -55,6 +79,8 @@ brew install sdl2 ## Build +All build commands might need a prefix like `nix develop -c` or need to be run from `nix develop` shell. If you use direnv, you don't need to do anything, apart from an initial `direnv allow`. + To build custom bootloader and firmware that you will be able to sign check out the bootloader doc on [self-signed firmware](https://github.com/cryptoadvance/specter-bootloader/blob/master/doc/selfsigned.md). To wipe flash and remove protections on the device with the secure bootloader check out [this doc](https://github.com/cryptoadvance/specter-bootloader/blob/master/doc/remove_protection.md). To build an open firmware (no bootloader and signature verifications) run `make disco`. The result is the `bin/specter-diy.bin` file that you can copy-paste to the board over miniUSB. diff --git a/docs/development.md b/docs/development.md index 6fdb93c..3cd2044 100644 --- a/docs/development.md +++ b/docs/development.md @@ -2,29 +2,36 @@ ## Compiling the code yourself -We use this build as a platform for Specter: https://github.com/diybitcoinhardware/f469-disco +See the [build documentation](build.md) for instructions on how to compile the code. -To compile the firmware you will need `arm-none-eabi-gcc` compiler. - -On MacOS install it using brew: `brew install arm-none-eabi-gcc` - -On Debian: `sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi gdb-arm-none-eabi openocd` - -On Arch Linux: `sudo pacman -S arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-gdb arm-none-eabi-newlib openocd` +## Enabling developer mode -Run `make disco` to get the binary or `make unix` to compile the simulator. They will be in the `bin` folder. +By default developer mode and USB communication are turned off. This means that when you connect the board to the computer it will NOT mount the `PYBFLASH` anymore and there will be no way to connect to debug shell. -`specter-diy.bin` file is the firmware that you need to copy to the device. -The easiest way to start developing is to use a [simulator](./simulator.md), and when you are done - try it on a real hardware. +~~To turn on the developer mode get to the main screen (enter PIN code, generate recovery phrase, enter password), and then go to **Settings - Security - turn on Developer mode - Save**.~~ +(Currently deactivated for securtiy reasons) -## Enabling developer mode +~~Now the board will restart and get mounted to the computer as before. You can also connect to the board over miniUSB and get to interactive console (baudrate 115200). You can use `screen` or `putty` or `minicom` for that, i.e. `screen /dev/tty.usbmodem14403 115200`.~~ -By default developer mode and USB communication are turned off. This means that when you connect the board to the computer it will NOT mount the `PYBFLASH` anymore and there will be no way to connect to debug shell. +In order to connect to the board, modify those lines in [boot.py](https://github.com/cryptoadvance/specter-diy/blob/2f51e152bcdb184cf719792e6c5f972214e3dd36/boot/main/boot.py#L33-L40) like this: +```python +# configure usb from start if you want, +# otherwise will be configured after PIN +pyb.usb_mode("VCP+MSC") # debug mode with USB and mounted storages from start +#pyb.usb_mode("VCP") # debug mode with USB from start +# disable at start +# pyb.usb_mode(None) +``` -To turn on the developer mode get to the main screen (enter PIN code, generate recovery phrase, enter password), and then go to **Settings - Security - turn on Developer mode - Save**. +and after flashing, you can connect with something like: +``` +# Linux +screen /dev/ttyACM0 115200 # or maybe ttyACM1 or ttyACM2 +# Mac +screen /dev/tty.usbmodem14403 115200`. +``` -Now the board will restart and get mounted to the computer as before. You can also connect to the board over miniUSB and get to interactive console (baudrate 115200). You can use `screen` or `putty` or `minicom` for that, i.e. `screen /dev/tty.usbmodem14403 115200`. ## Writing a simple app diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..cc5e0b1 --- /dev/null +++ b/flake.lock @@ -0,0 +1,78 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1685573264, + "narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "380be19fbd2d9079f677978361792cb25e8a3635", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..8dd6938 --- /dev/null +++ b/flake.nix @@ -0,0 +1,30 @@ +{ + description = "Specter DIY development environment"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.05"; + flake-utils.url = "github:numtide/flake-utils"; + flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; + }; + }; + + outputs = { self, nixpkgs, flake-utils, ... }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + { + devShells.default = pkgs.mkShell { + nativeBuildInputs = [ + pkgs.buildPackages.gcc-arm-embedded-9 + pkgs.buildPackages.python39 + pkgs.openocd + pkgs.stlink + pkgs.SDL2 + ]; + hardeningDisable = ["all"]; + }; + }); +} diff --git a/shell.nix b/shell.nix index 6f6d2d4..83cd59b 100644 --- a/shell.nix +++ b/shell.nix @@ -1,4 +1,23 @@ -{ pkgs ? import {} }: +(import + ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + in + fetchTarball { + url = + lock.nodes.flake-compat.locked.url + or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) + { + src = ./.; + } +).shellNix + url = "https://github.com/NixOS/nixpkgs/archive/nixos-22.05.tar.gz"; + sha256 = "154x9swf494mqwi4z8nbq2f0sp8pwp4fvx51lqzindjfbb9yxxv5"; + }) {} +}: pkgs.mkShell { nativeBuildInputs = [ pkgs.buildPackages.gcc-arm-embedded-9