diff --git a/Dockerfile b/Dockerfile index 8617eaa191..71bedcbbb6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,22 +4,28 @@ FROM debian:9 # install build tools and dependencies +ARG EMULATOR=0 +ENV EMULATOR=$EMULATOR + RUN apt-get update && \ - apt-get install -y \ - build-essential curl unzip git python3 python3-pip \ - gcc-arm-none-eabi libnewlib-arm-none-eabi + apt-get install -y build-essential curl git python3 python3-pip + +RUN if [ "$EMULATOR" = 1 ]; then \ + apt-get install -y libsdl2-dev libsdl2-image-dev; \ + else \ + apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi; \ + fi ENV PROTOBUF_VERSION=3.4.0 RUN curl -LO "https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" ENV PYTHON=python3 +ENV LC_ALL=C.UTF-8 +ENV LANG=C.UTF-8 # use zipfile module to extract files world-readable RUN $PYTHON -m zipfile -e "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" /usr/local && chmod 755 /usr/local/bin/protoc -ENV LC_ALL=C.UTF-8 -ENV LANG=C.UTF-8 - ENV WORKON_HOME=/tmp/.venvs RUN $PYTHON -m pip install pipenv diff --git a/README.md b/README.md index 75b0a110d4..0b8435ff59 100644 --- a/README.md +++ b/README.md @@ -4,23 +4,40 @@ https://trezor.io/ -## How to build the TREZOR bootloader and firmware? +## How to build the TREZOR bootloader, firmware and emulator -1. [Install Docker](https://docs.docker.com/engine/installation/) -2. `git clone https://github.com/trezor/trezor-mcu.git` -3. `cd trezor-mcu` -4. `./build.sh BOOTLOADER_TAG FIRMWARE_TAG` (where BOOTLOADER_TAG is bl1.5.0 and FIRMWARE_TAG is v1.7.0 for example, if left blank the script builds latest commit in master branch) +Ensure that you have Docker installed. You can follow [Docker's installation instructions](https://docs.docker.com/engine/installation/). -This creates the files `build/bootloader-BOOTLOADER_TAG.bin` and `build/trezor-FIRMWARE_TAG.bin` and prints their fingerprints and sizes at the end of the build log. +Clone this repository: +```sh +git clone https://github.com/trezor/trezor-mcu.git` +cd trezor-mcu +``` -## How to build TREZOR emulator for Linux? +Use the `build.sh` command to build the images. -1. [Install Docker](https://docs.docker.com/engine/installation/) -2. `git clone https://github.com/trezor/trezor-mcu.git` -3. `cd trezor-mcu` -4. `./build-emulator.sh TAG` (where TAG is v1.5.0 for example, if left blank the script builds latest commit in master branch) +* to build bootloader 1.6.0 and firmware 1.7.0: + ```sh + ./build.sh bl1.6.0 v1.7.0 + ``` +* to build latest firmware from master: + ```sh + ./build.sh + ``` +* to build the emulator from master: + ```sh + ./build.sh EMU + ``` +* to build the emulator for version 1.7.0: + ```sh + ./build.sh EMU v1.7.0 + ``` -This creates binary file `build/trezor-emulator-TAG`, which can be run and works as a trezor emulator. (Use `TREZOR_OLED_SCALE` env. variable to make screen bigger.) +Build results are stored in the `build/` directory. File `bootloader-.bin` represents +the bootloader, `trezor-.bin` is the firmware image, and `trezor-emulator-.elf` +is the emulator executable. + +You can use `TREZOR_OLED_SCALE` environment variable to make emulator screen bigger. ## How to get fingerprint of firmware signed and distributed by SatoshiLabs? diff --git a/build-emulator.sh b/build-emulator.sh deleted file mode 100755 index 40d5d28d46..0000000000 --- a/build-emulator.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -set -e - -IMAGE=trezor-mcu-build-emulator64 -TAG=${1:-master} -ELFFILE=build/trezor-emulator64-$TAG - -docker build -f Dockerfile.emulator -t $IMAGE . -docker run -t -v $(pwd)/build:/build:z $IMAGE /bin/sh -c "\ - git clone https://github.com/trezor/trezor-mcu && \ - cd trezor-mcu && \ - git checkout $TAG && \ - git submodule update --init && \ - make -C vendor/nanopb/generator/proto && \ - make -C firmware/protob && \ - EMULATOR=1 make && \ - EMULATOR=1 make -C emulator && \ - EMULATOR=1 make -C firmware && \ - cp firmware/trezor.elf /$ELFFILE" diff --git a/build.sh b/build.sh index 81dc2a8dc5..6afb96c5da 100755 --- a/build.sh +++ b/build.sh @@ -1,11 +1,19 @@ #!/bin/bash set -e -IMAGE=trezor-mcu-build - BOOTLOADER_COMMIT=${1:-HEAD} FIRMWARE_COMMIT=${2:-HEAD} -docker build -t "$IMAGE" . +if [ "$BOOTLOADER_COMMIT" = "EMU" ]; then + export EMULATOR=1 +fi + +if [ "$EMULATOR" = 1 ]; then + IMAGE=trezor-mcu-emulator +else + IMAGE=trezor-mcu-build +fi + +docker build -t "$IMAGE" --build-arg EMULATOR=$EMULATOR . docker run -it -v $(pwd):/src:z --user="$(stat -c "%u:%g" .)" "$IMAGE" \ /src/script/fullbuild "$BOOTLOADER_COMMIT" "$FIRMWARE_COMMIT" diff --git a/script/fullbuild b/script/fullbuild index 520271fdc9..044ab94e63 100755 --- a/script/fullbuild +++ b/script/fullbuild @@ -22,6 +22,10 @@ readonly FIRMWARE_DIR="$BUILD_DIR/firmware" readonly FIRMWARE_FILENAME="firmware/trezor.bin" readonly FIRMWARE_PATH="$FIRMWARE_DIR/$FIRMWARE_FILENAME" +readonly EMULATOR_DIR="$FIRMWARE_DIR" +readonly EMULATOR_FILENAME="firmware/trezor-emulator.elf" +readonly EMULATOR_PATH="$EMULATOR_DIR/firmware/trezor.elf" + worktree_setup() { local path="$1" local commit="$2" @@ -38,7 +42,21 @@ worktree_setup() { worktree_build() { local path="$1" - ( cd "$path" && pipenv install && pipenv run script/cibuild ) + if [ -e "$path/Pipfile" ]; then + pushd $path + if ! pipenv install; then + # older tags can fail because they don't have protobuf in Pipfile + pipenv run pip install "protobuf==3.4.0" + pipenv install + fi + pipenv run script/cibuild + popd + else + # even older tags don't have Pipfile! + # use current one + pipenv install + ( cd "$path" && pipenv run script/cibuild ) + fi } worktree_copy() { @@ -67,28 +85,42 @@ main() { local firmware_commit="$2" script/bootstrap - - worktree_setup "$BOOTLOADER_DIR" "$bootloader_commit" - worktree_build "$BOOTLOADER_DIR" - - local bootloader_path="$(worktree_copy \ - "$BOOTLOADER_DIR" \ - "$BOOTLOADER_FILENAME" \ - "bl*")" - worktree_setup "$FIRMWARE_DIR" "$firmware_commit" - cp "$BOOTLOADER_PATH" "$FIRMWARE_DIR/$BOOTLOADER_FILENAME" + + if [ "$EMULATOR" != 1 ]; then + worktree_setup "$BOOTLOADER_DIR" "$bootloader_commit" + worktree_build "$BOOTLOADER_DIR" + + cp "$BOOTLOADER_PATH" "$FIRMWARE_DIR/$BOOTLOADER_FILENAME" + fi + worktree_build "$FIRMWARE_DIR" - local firmware_path="$(worktree_copy \ - "$FIRMWARE_DIR" \ - "$FIRMWARE_FILENAME" \ - "v*")" + if [ "$EMULATOR" = 1 ]; then + cp "$EMULATOR_PATH" "$EMULATOR_DIR/$EMULATOR_FILENAME" + local firmware_path="$(worktree_copy \ + "$EMULATOR_DIR" \ + "$EMULATOR_FILENAME" \ + "v*")" + chmod +x "$firmware_path" - printf "\n\n"; $PYTHON script/fingerprint \ - "$bootloader_path" \ - --max-size 32768 \ - --double + else + + local firmware_path="$(worktree_copy \ + "$FIRMWARE_DIR" \ + "$FIRMWARE_FILENAME" \ + "v*")" + + local bootloader_path="$(worktree_copy \ + "$BOOTLOADER_DIR" \ + "$BOOTLOADER_FILENAME" \ + "bl*")" + + printf "\n\n"; $PYTHON script/fingerprint \ + "$bootloader_path" \ + --max-size 32768 \ + --double + fi printf "\n\n"; $PYTHON script/fingerprint \ "$firmware_path" \