docker builds working
This commit is contained in:
parent
fd51e8e6e7
commit
ee11794bc8
17
README.md
17
README.md
@ -12,6 +12,23 @@ with the latest updates and security alerts.
|
||||

|
||||

|
||||
|
||||
## Reproducable Builds
|
||||
|
||||
To have confidence this source code tree is the same as the binary on your device,
|
||||
you can rebuild it from source and get **exactly the same bytes**. This process
|
||||
has been automated using Docker. Steps are as follows:
|
||||
|
||||
1. Install Docker
|
||||
2. You'll need [GNUMake](https://www.gnu.org/software/make/) but you probably already have it.
|
||||
3. Checkout the code, and start the process.
|
||||
|
||||
git clone --recursive https://github.com/Coldcard/firmware.git
|
||||
cd firmware/stm32
|
||||
make repro
|
||||
|
||||
4. Maek a coffee, drink it.
|
||||
5. At the end the process, the differences, if any are shown and/or a clear confirmation message.
|
||||
|
||||
## Check-out and Setup
|
||||
|
||||
Do a checkout, recursively to get all the submodules:
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
# Dockerfile to build firmware binary
|
||||
#
|
||||
# based on <https://blog.feabhas.com/2017/12/introduction-docker-embedded-developers-part-4-reducing-docker-image-size/>
|
||||
# and <https://github.com/lucaszanella/coldcard-docker>
|
||||
#
|
||||
FROM alpine:3.13.2
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
#ADD . /work
|
||||
|
||||
RUN apk add --no-cache git python3 py-pip musl-dev make && \
|
||||
apk add gcc-arm-none-eabi newlib-arm-none-eabi --update-cache \
|
||||
--repository http://dl-3.alpinelinux.org/alpine/edge/testing/
|
||||
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python
|
||||
|
||||
RUN git clone --recursive https://github.com/Coldcard/firmware.git
|
||||
|
||||
WORKDIR /work/firmware
|
||||
|
||||
RUN git submodule update --init
|
||||
|
||||
WORKDIR /work/firmware/stm32
|
||||
|
||||
RUN make setup
|
||||
|
||||
# TODO ... more
|
||||
#RUN make
|
||||
|
||||
#RUN sed -i '29 s/^/ #/' /home/project/firmware/unix/frozen-modules/pyb.py \
|
||||
#&& sed -i "31,32 s/# *//" /home/project/firmware/unix/frozen-modules/pyb.py
|
||||
|
||||
|
||||
#COPY docker_init.sh /home/project/docker_init.sh
|
||||
@ -1,15 +0,0 @@
|
||||
|
||||
all:
|
||||
@echo no default
|
||||
|
||||
build:
|
||||
docker build -t coldcard-build .
|
||||
|
||||
shell:
|
||||
docker run -it coldcard-build sh
|
||||
|
||||
|
||||
copy:
|
||||
(cd .. ; git archive --format tar HEAD) | \
|
||||
docker run -i coldcard-build tar x -C /work -f -
|
||||
(cd .. ; git archive -o docker/snapshot.tar HEAD)
|
||||
@ -1,13 +0,0 @@
|
||||
# Docker Build
|
||||
|
||||
For deterministic builds, we are using Docker.
|
||||
|
||||
Thanks to <https://github.com/lucaszanella/coldcard-docker> for inspiration.
|
||||
|
||||
## Background
|
||||
|
||||
- Alpine base image
|
||||
- files in this directory will be visible in container at /work
|
||||
- no need for git to be pushed, because we clone into container from current checkout
|
||||
|
||||
|
||||
2
external/libngu
vendored
2
external/libngu
vendored
@ -1 +1 @@
|
||||
Subproject commit 2fbfefb11b2a7bd4d1abe0b26bb99a6fea050b8d
|
||||
Subproject commit 88a61084bd483948d02876ffa12065ea89a28506
|
||||
@ -17,6 +17,7 @@
|
||||
was used, did not reflect the (non-zero) account number.
|
||||
- HSM/CKBunker mode:
|
||||
- IMPORTANT: users with passwords will have to be reconstructed as hash algo has changed
|
||||
- Enhancement: Reproducable builds! Checkout code, "cd stm32; make repro" should do it all.
|
||||
- Enhancement: Paper wallet feature restored as it was previously. Same cautions apply.
|
||||
- Enhancement: Show a progress bar during slow parts of the login process.
|
||||
- Remaining GPL code has been removed, so licence is now MIT+CC on everything.
|
||||
|
||||
6
stm32/.gitignore
vendored
6
stm32/.gitignore
vendored
@ -14,3 +14,9 @@ firmware-signed.dfu
|
||||
|
||||
dev.bin
|
||||
dev.dfu
|
||||
|
||||
# byproducts of check-repro target
|
||||
check-fw.bin
|
||||
check-bootrom.bin
|
||||
repro-got.txt
|
||||
repro-want.txt
|
||||
|
||||
@ -26,11 +26,9 @@ TEXT0_ADDR = 0x08008000
|
||||
TEXT1_ADDR = 0x0800C000
|
||||
|
||||
# don't want any of these: soft_spi, soft_qspi, dht
|
||||
DRIVERS_SRC_C -= \
|
||||
drivers/bus/softspi.c \
|
||||
drivers/bus/softqspi.c \
|
||||
drivers/memory/spiflash.c \
|
||||
drivers/dht/dht.c
|
||||
#DRIVERS_SRC_C -= drivers/bus/softspi.c \
|
||||
# drivers/bus/softqspi.c drivers/memory/spiflash.c \
|
||||
# drivers/dht/dht.c
|
||||
|
||||
# Approximately all the source code files?
|
||||
ALL_SRC = $(SRC_LIB) $(SRC_LIBM) $(EXTMOD_SRC_C) $(DRIVERS_SRC_C) \
|
||||
|
||||
@ -16,12 +16,14 @@ MAKE_ARGS = BOARD=COLDCARD -j 4 EXCLUDE_NGU_TESTS=1
|
||||
all: COLDCARD/file_time.c
|
||||
cd $(PORT_TOP) && $(MAKE) $(MAKE_ARGS)
|
||||
|
||||
clean-mpy:
|
||||
rm -rf build
|
||||
|
||||
clean: clean-mpy
|
||||
clean:
|
||||
cd $(PORT_TOP) && $(MAKE) $(MAKE_ARGS) clean
|
||||
|
||||
# These trigger the 'all' target when we haven't completed a successful build yet
|
||||
l-port/build-COLDCARD/firmware.elf: all
|
||||
l-port/build-COLDCARD/firmware0.bin: all
|
||||
l-port/build-COLDCARD/firmware1.bin: all
|
||||
|
||||
# These values used to make .DFU files. Flash memory locations.
|
||||
FIRMWARE_BASE = 0x08008000
|
||||
BOOTLOADER_BASE = 0x08000000
|
||||
@ -33,8 +35,8 @@ VERSION_STRING = 4.0.0
|
||||
#
|
||||
# Sign and merge various parts
|
||||
#
|
||||
firmware-signed.bin: l-port/build-COLDCARD/firmware?.bin
|
||||
$(SIGNIT) sign $(VERSION_STRING)
|
||||
firmware-signed.bin: l-port/build-COLDCARD/firmware0.bin l-port/build-COLDCARD/firmware1.bin
|
||||
$(SIGNIT) sign $(VERSION_STRING) -o $@
|
||||
firmware-signed.dfu: firmware-signed.bin Makefile
|
||||
$(PYTHON_MAKE_DFU) -b $(FIRMWARE_BASE):$< $@
|
||||
|
||||
@ -42,7 +44,7 @@ firmware-signed.dfu: firmware-signed.bin Makefile
|
||||
dfu: firmware-signed.dfu
|
||||
|
||||
# Build a binary, signed w/ production key
|
||||
# - always rebuild binary
|
||||
# - always rebuild binary for this one
|
||||
.PHONY: dev.dfu
|
||||
dev.dfu: l-port/build-COLDCARD/firmware?.bin
|
||||
cd $(PORT_TOP) && $(MAKE) $(MAKE_ARGS)
|
||||
@ -66,7 +68,7 @@ COLDCARD/file_time.c: Makefile make_filetime.py
|
||||
|
||||
# Make a factory release: using key #1
|
||||
production.bin: firmware-signed.bin Makefile
|
||||
$(SIGNIT) sign $(VERSION_STRING) -r firmware-signed.bin -k 1 -o production.bin
|
||||
$(SIGNIT) sign $(VERSION_STRING) -r firmware-signed.bin -k 1 -o $@
|
||||
|
||||
# This is release of the bootloader that will be built into the release firmware.
|
||||
BOOTLOADER_VERSION = 2.0.1
|
||||
@ -74,17 +76,21 @@ BOOTLOADER_VERSION = 2.0.1
|
||||
# This target just combines latest version of production firmware with bootrom into a DFU
|
||||
# file, stored in ../releases with appropriately dated file name.
|
||||
.PHONY: release
|
||||
release: NEW_VERSION = $(shell $(SIGNIT) version production.bin)
|
||||
release: NEW_VERSION = $(shell $(SIGNIT) version built/production.bin)
|
||||
release: RELEASE_FNAME = ../releases/$(NEW_VERSION)-coldcard.dfu
|
||||
release: production.bin
|
||||
release: built/production.bin
|
||||
test ! -f $(RELEASE_FNAME)
|
||||
$(PYTHON_MAKE_DFU) -b $(FIRMWARE_BASE):production.bin \
|
||||
$(PYTHON_MAKE_DFU) -b $(FIRMWARE_BASE):built/production.bin \
|
||||
-b $(BOOTLOADER_BASE):bootloader/releases/$(BOOTLOADER_VERSION)/bootloader.bin \
|
||||
$(RELEASE_FNAME)
|
||||
@echo
|
||||
@echo 'Made release: ' $(RELEASE_FNAME)
|
||||
@echo
|
||||
|
||||
built/production.bin:
|
||||
@echo "To make production build, must run docker code"
|
||||
@false
|
||||
|
||||
# Use DFU to install the latest production version you have on hand
|
||||
dfu-latest:
|
||||
$(PYTHON_DO_DFU) -u `ls -t1 ../releases/*.dfu | head -1`
|
||||
@ -103,6 +109,7 @@ code-committed:
|
||||
.PHONY: sign-release
|
||||
sign-release: PUBLIC_VERSION = $(shell $(SIGNIT) version production.bin)
|
||||
sign-release:
|
||||
test -f ../releases/$(PBULIC_VERSION)-coldcard.dfu # need to copy built=>releases
|
||||
(cd ../releases; shasum -a 256 *.dfu *.md | sort -rk 2 | \
|
||||
gpg --clearsign -u A3A31BAD5A2A5B10 --digest-algo SHA256 --output signatures.txt --yes - )
|
||||
git commit -m "Signed for release: "$(PUBLIC_VERSION) ../releases/signatures.txt
|
||||
@ -165,11 +172,6 @@ PY_FILES = $(shell find ../shared -name \*.py)
|
||||
ALL_MPY_FILES = $(addprefix build/, $(PY_FILES:../shared/%.py=%.mpy))
|
||||
MPY_FILES = $(filter-out build/obsolete/%, $(ALL_MPY_FILES))
|
||||
|
||||
build/%.mpy: ../shared/%.py Makefile
|
||||
mkdir -p $(dir $@)
|
||||
$(MPY_CROSS) -o $@ -s $*.py $<
|
||||
|
||||
|
||||
# In another window:
|
||||
#
|
||||
# openocd -f openocd_stm32l4x6.cfg
|
||||
@ -182,11 +184,11 @@ build/%.mpy: ../shared/%.py Makefile
|
||||
# - and so on
|
||||
#
|
||||
debug:
|
||||
arm-none-eabi-gdb $(PORT_TOP)/build-COLDCARD/firmware.elf -x gogo.gdb
|
||||
arm-none-eabi-gdb l-port/build-COLDCARD/firmware.elf -x gogo.gdb
|
||||
|
||||
# detailed listing, very handy
|
||||
OBJDUMP = arm-none-eabi-objdump
|
||||
firmware.lss: $(PORT_TOP)/build-COLDCARD/firmware.elf
|
||||
firmware.lss: l-port/build-COLDCARD/firmware.elf
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
# Dump sizes of all frozen py files; requires recent build.
|
||||
@ -207,6 +209,50 @@ setup:
|
||||
cd $(MPY_TOP)/mpy-cross ; make
|
||||
-ln -s $(PORT_TOP) l-port
|
||||
-ln -s $(MPY_TOP) l-mpy
|
||||
-cd $(PORT_TOP)/boards ; ln -s ../../../../../stm32/COLDCARD COLDCARD
|
||||
#-ln -s ../../../../../stm32/COLDCARD $(PORT_TOP)/boards/COLDCARD
|
||||
|
||||
# Caution: docker container has write access to your source tree
|
||||
# - a readonly copy of source tree, and one output directory
|
||||
# - build products are copied to there, see repro-build.sh
|
||||
DOCK_RUN_ARGS = -v $(realpath ..):/work/src:ro \
|
||||
-v $(realpath built):/work/built:rw \
|
||||
--privileged coldcard-build
|
||||
repro:
|
||||
docker build -t coldcard-build - < dockerfile.build
|
||||
(cd ..; docker run $(DOCK_RUN_ARGS) sh src/stm32/repro-build.sh)
|
||||
|
||||
# debug: shell into docker container
|
||||
shell:
|
||||
docker run -it $(DOCK_RUN_ARGS) sh
|
||||
|
||||
# debug: allow docker to write into source tree
|
||||
#DOCK_RUN_ARGS := -v $(realpath ..):/work/src:rw --privileged coldcard-build
|
||||
|
||||
PUBLISHED_BIN = $(wildcard ../releases/*-v$(VERSION_STRING)-coldcard.dfu)
|
||||
|
||||
# final step in repro-building: check you got the right bytes
|
||||
# - but you don't have the production signing key, so that section is removed
|
||||
check-repro: TRIM_SIG = sed -e 's/^00003f[89abcdef]0 .*/(firmware signature here)/'
|
||||
check-repro: firmware-signed.bin
|
||||
ifeq ($(PUBLISHED_BIN),)
|
||||
@echo ""
|
||||
@echo "No binary published yet for: $(VERSION_STRING)"
|
||||
@echo ""
|
||||
else
|
||||
@echo Comparing against: $(PUBLISHED_BIN)
|
||||
test -n "$(PUBLISHED_BIN)" -a -f $(PUBLISHED_BIN)
|
||||
$(RM) -f check-fw.bin check-bootrom.bin
|
||||
$(SIGNIT) split $(PUBLISHED_BIN) check-fw.bin check-bootrom.bin
|
||||
$(SIGNIT) check check-fw.bin
|
||||
$(SIGNIT) check firmware-signed.bin
|
||||
hexdump -C firmware-signed.bin | $(TRIM_SIG) > repro-got.txt
|
||||
hexdump -C check-fw.bin | $(TRIM_SIG) > repro-want.txt
|
||||
diff repro-got.txt repro-want.txt
|
||||
@echo ""
|
||||
@echo "SUCCESS. "
|
||||
@echo ""
|
||||
@echo "You have built a bit-for-bit identical copy of Coldcard firmware for v$(VERSION_STRING)"
|
||||
endif
|
||||
|
||||
|
||||
# EOF
|
||||
|
||||
3
stm32/built/.gitignore
vendored
Normal file
3
stm32/built/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*
|
||||
!README.md
|
||||
!.gitignore
|
||||
7
stm32/built/README.md
Normal file
7
stm32/built/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
# Built
|
||||
|
||||
Output files will be saved into this directory after they are made inside the Docker container.
|
||||
|
||||
Everything but this README is in the .gitignore
|
||||
|
||||
17
stm32/dockerfile.build
Normal file
17
stm32/dockerfile.build
Normal file
@ -0,0 +1,17 @@
|
||||
# Dockerfile to build tools for building firmware binary
|
||||
#
|
||||
# Thanks to <https://github.com/lucaszanella/coldcard-docker> for inspiration.
|
||||
#
|
||||
# Also somewhat based on
|
||||
# <https://blog.feabhas.com/2017/12/introduction-docker-embedded-developers-part-4-reducing-docker-image-size/>
|
||||
#
|
||||
FROM alpine:3.13.2
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
RUN apk add --no-cache git python3 py-pip musl-dev make rsync && \
|
||||
apk add gcc-arm-none-eabi newlib-arm-none-eabi --update-cache \
|
||||
--repository http://dl-3.alpinelinux.org/alpine/edge/testing/
|
||||
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python
|
||||
|
||||
41
stm32/repro-build.sh
Normal file
41
stm32/repro-build.sh
Normal file
@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Executes inside the docker container... but works on your files here!
|
||||
#
|
||||
set -ex
|
||||
|
||||
TARGETS="firmware-signed.bin firmware-signed.dfu production.bin dev.dfu"
|
||||
|
||||
cd /work/src/stm32
|
||||
|
||||
if ! touch repro-build.sh ; then
|
||||
# If we seem to be on a R/O filesystem:
|
||||
# - create a writable overlay on top of read-only source tree
|
||||
# from <https://stackoverflow.com/a/54465442>
|
||||
# - copy certain files (build products) back to /work/built
|
||||
|
||||
mkdir /tmp/overlay
|
||||
mount -t tmpfs tmpfs /tmp/overlay
|
||||
mkdir -p /tmp/overlay/upper /tmp/overlay/work /work/tmp
|
||||
mount -t overlay overlay -o lowerdir=/work/src,upperdir=/tmp/overlay/upper,workdir=/tmp/overlay/work /work/tmp
|
||||
|
||||
cd /work/tmp/stm32
|
||||
fi
|
||||
|
||||
# need signit.py in path
|
||||
cd ../cli
|
||||
python -m pip install -r requirements.txt
|
||||
python -m pip install --editable .
|
||||
cd ../stm32
|
||||
|
||||
make setup
|
||||
#make clean
|
||||
make all
|
||||
make $TARGETS
|
||||
|
||||
if [ $PWD == '/work/tmp/stm32' ]; then
|
||||
# Copy back build products.
|
||||
rsync -av --ignore-missing-args $TARGETS /work/built
|
||||
fi
|
||||
|
||||
make check-repro
|
||||
Loading…
Reference in New Issue
Block a user