1###########################################################################
2# Sample multi-part application Makefile
3#
4# Copyright (c) 2017 Linaro Limited
5# Copyright (c) 2017 Open Source Foundries Limited
6#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11#     http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18###########################################################################
19
20# This is an example Makefile to demonstrate how to use mcuboot to
21# deploy and upgrade images.  The image building should work on any
22# supported target, however flashing will likely require changes to
23# the flash addresses, depending on the partition layout of the device
24# in question.
25#
26# running
27#
28#     make BOARD=frdm_k64f all
29#
30# should generate three "*.bin" files in this directory:
31#
32#   mcuboot.bin: The bootloader itself
33#   signed-hello1.bin: A signed sample.
34#   signed-hello2.bin: An upgrade image, signed and marked for
35#   upgrade.
36#
37# "make flash_boot" should flash the bootloader into the flash,
38# erasing the rest of the device.  If you examine the device at this
39# time, you should see a message about the bootloader not being able
40# to find a bootable image.
41#
42# "make flash_hello1" will then flash the first application into the
43# "primary slot".  This should boot into this app, print a small message, and
44# give the zephyr console.
45#
46# "make flash_hello2" will flash hello2 into the "secondary slot".  The
47# reset should upgrade and run the new image.  Resetting again should
48# then revert back to the first app, since we did not mark this image
49# as good.
50
51# Extra .conf fragments to merge into the MCUboot .config, as a
52# semicolon-separated list (i.e., a CMake list).
53BOOTLOADER_OVERLAY_CONFIG ?=
54
55BOARD ?= frdm_k64f
56
57.PHONY: check boot hello1 clean_boot clean_hello1 \
58	hello2 clean_hello2 flash_boot flash_hello1 flash_hello2
59
60# For signing, use the default RSA demo key, to match the default in
61# the mcuboot Makefile.
62SIGNING_KEY ?= ../../root-rsa-2048.pem
63
64# The header size should match that in hello1/prj.conf
65# CONFIG_TEXT_SECTION_OFFSET.  This value needs to be a power of two
66# that is at least as large as the size of the vector table.  The
67# value given here of 0x200 should be sufficient for any supported
68# devices, but it can be made smaller, as long as this value matches
69# that used to build the app.
70BOOT_HEADER_LEN = 0x200
71
72# For upgrades, the signing tool needs to know the device alignment.
73# This requirement will be going away soon.
74FLASH_ALIGNMENT = 8
75
76IMGTOOL = ../../scripts/imgtool.py
77ASSEMBLE = ../../scripts/assemble.py
78PYOCD = pyocd
79
80SOURCE_DIRECTORY := $(CURDIR)
81BUILD_DIRECTORY := $(CURDIR)/build/$(BOARD)
82BUILD_DIR_BOOT := $(BUILD_DIRECTORY)/mcuboot
83BUILD_DIR_HELLO1 := $(BUILD_DIRECTORY)/hello1
84BUILD_DIR_HELLO2 := $(BUILD_DIRECTORY)/hello2
85
86help:
87	@echo "make <target> BOARD=<board>"
88	@echo "<target>: all, boot, hello1, full.bin"
89	@echo "<board>: frdm_k64f only for now"
90
91all: boot hello1 hello2
92
93full.bin: boot hello1 hello2
94	$(ASSEMBLE) -b $(BUILD_DIR_BOOT) \
95	    -z $(ZEPHYR_BASE) \
96	    -p signed-hello1.bin \
97	    -s signed-hello2.bin \
98	    -o full.bin
99
100clean: clean_boot clean_hello1 clean_hello2
101	@rm -f signed-hello1.bin
102	@rm -f signed-hello2.bin
103	@rm -f mcuboot.bin
104
105boot: check
106	@rm -f mcuboot.bin
107	(mkdir -p $(BUILD_DIR_BOOT) && \
108		cd $(BUILD_DIR_BOOT) && \
109		cmake -DOVERLAY_CONFIG=$(BOOTLOADER_OVERLAY_CONFIG) \
110			-G"Ninja" \
111			-DBOARD=$(BOARD) \
112			$(SOURCE_DIRECTORY)/../../boot/zephyr && \
113		ninja)
114	cp $(BUILD_DIR_BOOT)/zephyr/zephyr.bin mcuboot.bin
115
116clean_boot: check
117	rm -rf $(BUILD_DIR_BOOT)
118
119# Build and sign "hello1".
120hello1: check
121	(mkdir -p $(BUILD_DIR_HELLO1) && \
122		cd $(BUILD_DIR_HELLO1) && \
123		cmake -DFROM_WHO=hello1 \
124			-G"Ninja" \
125			-DBOARD=$(BOARD) \
126			$(SOURCE_DIRECTORY)/hello-world && \
127		ninja)
128	$(IMGTOOL) sign \
129		--key $(SIGNING_KEY) \
130		--header-size $(BOOT_HEADER_LEN) \
131		--align $(FLASH_ALIGNMENT) \
132		--version 1.2 \
133		--slot-size 0x60000 \
134		$(BUILD_DIR_HELLO1)/zephyr/zephyr.bin \
135		signed-hello1.bin
136
137clean_hello1: check
138	rm -rf $(BUILD_DIR_HELLO1)
139
140# Build and sign "hello2".
141# This is the same signing command as above, except that it adds the
142# "--pad" argument.  This will also add the trailer that indicates
143# this image is intended to be an upgrade.  It should be flashed into
144# the secondary slot instead of the primary slot.
145hello2: check
146	(mkdir -p $(BUILD_DIR_HELLO2) && \
147		cd $(BUILD_DIR_HELLO2) && \
148		cmake -DFROM_WHO=hello2 \
149			-G"Ninja" \
150			-DBOARD=$(BOARD) \
151			$(SOURCE_DIRECTORY)/hello-world && \
152		ninja)
153	$(IMGTOOL) sign \
154		--key $(SIGNING_KEY) \
155		--header-size $(BOOT_HEADER_LEN) \
156		--align $(FLASH_ALIGNMENT) \
157		--version 1.2 \
158		--slot-size 0x60000 \
159		--pad \
160		$(BUILD_DIR_HELLO2)/zephyr/zephyr.bin \
161		signed-hello2.bin
162
163clean_hello2: check
164	rm -rf $(BUILD_DIR_HELLO2)
165
166# These flash_* targets use pyocd to flash the images.  The addresses
167# are hardcoded at this time.
168
169flash_boot:
170	$(PYOCD) flash -e chip -a 0 mcuboot.bin
171
172flash_hello1:
173	$(PYOCD) flash -a 0x20000 signed-hello1.bin
174
175flash_hello2:
176	$(PYOCD) flash -a 0x80000 signed-hello2.bin
177
178flash_full:
179	$(PYOCD) flash -e chip -a 0 full.bin
180
181# These test- targets reinvoke make with the configuration set to test
182# various configurations.  This will generally be followed by using
183# the above flash targets.
184
185# Test a good image, with a good upgrade, using RSA signatures.
186# flash_boot: Unable to find bootable image
187# flash_hello1: hello1 runs
188# flash_hello2: hello2 runs
189# reset: hello1 runs
190test-good-rsa: clean
191	$(MAKE) \
192		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-rsa.conf \
193		all
194
195# Test a good image, with a good upgrade, using ECDSA signatures.
196# flash_boot: Unable to find bootable image
197# flash_hello1: hello1 runs
198# flash_hello2: hello2 runs
199# reset: hello1 runs
200test-good-ecdsa: clean
201	$(MAKE) \
202		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-ecdsa-p256.conf \
203		SIGNING_KEY=../../root-ec-p256.pem \
204		all
205
206# Test (with RSA) that overwrite-only works.  This should boot,
207# upgrade correctly, but not revert once the upgrade has been done.
208# flash_boot: Unable to find bootable image
209# flash_hello1: hello1 runs
210# flash_hello2: hello2 runs
211# reset: hello2 runs
212test-overwrite: clean
213	$(MAKE) \
214		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-upgrade-only.conf \
215		all
216
217# Test that when configured for RSA, a wrong signature in the upgrade
218# image will fail to upgrade.
219# flash_boot: Unable to find bootable image
220# flash_hello1: hello1 runs
221# flash_hello2: hello1 runs
222# reset: hello1 runs
223test-bad-rsa-upgrade: clean
224	$(MAKE) \
225		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-rsa.conf \
226		boot hello1
227	$(MAKE) \
228		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-rsa.conf \
229		SIGNING_KEY=../../root-ec-p256.pem \
230		hello2
231
232# Test that when configured for ECDSA, a wrong signature in the upgrade
233# image will fail to upgrade.
234# flash_boot: Unable to find bootable image
235# flash_hello1: hello1 runs
236# flash_hello2: hello1 runs
237# reset: hello1 runs
238test-bad-ecdsa-upgrade: clean
239	$(MAKE) \
240		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-ecdsa-p256.conf \
241		SIGNING_KEY=../../root-ec-p256.pem \
242		boot hello1
243	$(MAKE) \
244		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-ecdsa-p256.conf \
245		SIGNING_KEY=../../root-rsa-2048.pem \
246		hello2
247
248# Test that when configured to not validate the primary slot, we still boot, but
249# don't upgrade.
250# flash_boot: tries to boot and resets
251# flash_hello1: hello1 runs
252# flash_hello2: hello1 runs
253# reset: hello1 runs
254test-no-bootcheck: clean
255	$(MAKE) \
256		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-skip-primary-slot-validate.conf \
257		SIGNING_KEY=../../root-ec-p256.pem \
258		all
259
260# Test a good image, with a wrong-signature upgrade, using RSA signatures.
261# flash_boot: Unable to find bootable image
262# flash_hello1: hello1 runs
263# flash_hello2: hello1 runs
264# reset: hello1 runs
265test-wrong-rsa: clean
266	$(MAKE) \
267		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-rsa.conf \
268		boot hello1
269	$(MAKE) \
270		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-rsa.conf \
271		SIGNING_KEY=bad-keys/bad-rsa-2048.pem \
272		hello2
273
274# Test a good image, with a wrong-signature upgrade, using ECDSA signatures.
275# flash_boot: Unable to find bootable image
276# flash_hello1: hello1 runs
277# flash_hello2: hello1 runs
278# reset: hello1 runs
279test-wrong-ecdsa: clean
280	$(MAKE) \
281		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-ecdsa-p256.conf \
282		SIGNING_KEY=../../root-ec-p256.pem \
283		boot hello1
284	$(MAKE) \
285		BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-ecdsa-p256.conf \
286		SIGNING_KEY=bad-keys/bad-ec-p256.pem \
287		hello2
288
289check:
290	@if [ -z "$$ZEPHYR_BASE" ]; then echo "Zephyr environment not set up"; false; fi
291	@if [ -z "$(BOARD)" ]; then echo "You must specify BOARD=<board>"; false; fi
292