forked from apache/nuttx-apps
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
boot/mcuboot: Add support for MCUboot bootloader
Signed-off-by: Gustavo Henrique Nihei <[email protected]>
- Loading branch information
1 parent
e6b767f
commit 794cfd0
Showing
10 changed files
with
684 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/Kconfig |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
############################################################################ | ||
# apps/boot/Make.defs | ||
# | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. The | ||
# ASF licenses this file to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance with the | ||
# License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
# License for the specific language governing permissions and limitations | ||
# under the License. | ||
# | ||
############################################################################ | ||
|
||
include $(wildcard $(APPDIR)/boot/*/Make.defs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
############################################################################ | ||
# apps/boot/Makefile | ||
# | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. The | ||
# ASF licenses this file to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance with the | ||
# License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
# License for the specific language governing permissions and limitations | ||
# under the License. | ||
# | ||
############################################################################ | ||
|
||
MENUDESC = "Bootloader Utilities" | ||
|
||
include $(APPDIR)/Directory.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/mcuboot | ||
/*.tar.gz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# | ||
# For a description of the syntax of this configuration file, | ||
# see the file kconfig-language.txt in the NuttX tools repository. | ||
# | ||
|
||
menuconfig BOOT_MCUBOOT | ||
bool "MCUboot" | ||
default n | ||
select BCH | ||
---help--- | ||
Enable support for the MCUboot bootloader. | ||
|
||
if BOOT_MCUBOOT | ||
|
||
config MCUBOOT_VERSION | ||
string "MCUboot version" | ||
default "01184bd0361c4128c6382aa9c640b02e7f1422f6" | ||
|
||
config MCUBOOT_ENABLE_LOGGING | ||
bool "Enable MCUboot logging" | ||
default n | ||
---help--- | ||
Enable MCUboot's logging infrastructure. | ||
|
||
config MCUBOOT_BOOTLOADER | ||
bool "MCUboot bootloader application" | ||
default n | ||
select BOARDCTL | ||
select BOARDCTL_BOOT_IMAGE | ||
---help--- | ||
MCUboot bootloader application. | ||
|
||
config MCUBOOT_UPDATE_AGENT_EXAMPLE | ||
bool "MCUboot update agent example" | ||
default n | ||
depends on NET_TCP | ||
---help--- | ||
Example application that implements an update agent that downloads | ||
an application firmware image from a given URL and saves it to the | ||
secondary slot as a pending update. | ||
|
||
if MCUBOOT_UPDATE_AGENT_EXAMPLE | ||
|
||
config MCUBOOT_UPDATE_AGENT_EXAMPLE_UPDATE_URL | ||
string "URL for update image" | ||
default "" | ||
|
||
config MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_BUFFER_SIZE | ||
int "Download buffer size in bytes" | ||
default 512 | ||
|
||
config MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5 | ||
bool "Calculate MD5 of update image" | ||
default n | ||
depends on CODECS_HASH_MD5 | ||
|
||
config MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_MD5_HASH | ||
string "Expected MD5 sum of update image" | ||
default "" | ||
depends on MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5 | ||
|
||
endif # MCUBOOT_UPDATE_AGENT_EXAMPLE | ||
|
||
config MCUBOOT_SLOT_CONFIRM_EXAMPLE | ||
tristate "MCUboot slot confirm example" | ||
default n | ||
---help--- | ||
Example application for confirming a newly installed application | ||
application firmware image using MCUboot public APIs. | ||
This application should be used as the OTA update package of the | ||
MCUBOOT_UPDATE_AGENT_EXAMPLE example. | ||
|
||
config MCUBOOT_WATCHDOG | ||
bool "Watchdog feeding support" | ||
default n | ||
depends on WATCHDOG | ||
---help--- | ||
This config must be selected in case the Watchdog is enabled while | ||
performing a swap upgrade and the time it takes for a swapping is long | ||
enough to cause an unwanted reset. | ||
|
||
config MCUBOOT_WATCHDOG_DEVPATH | ||
string "Watchdog device path" | ||
default "/dev/watchdog0" | ||
depends on MCUBOOT_WATCHDOG | ||
---help--- | ||
The path to the watchdog device. | ||
Default: /dev/watchdog0 | ||
|
||
config MCUBOOT_PRIMARY_SLOT_PATH | ||
string "Application firmware image primary slot path" | ||
default "/dev/ota0" | ||
---help--- | ||
The path to the application firmware image primary slot character | ||
device driver. | ||
Default: /dev/ota0 | ||
|
||
config MCUBOOT_SECONDARY_SLOT_PATH | ||
string "Application firmware image secondary slot path" | ||
default "/dev/ota1" | ||
---help--- | ||
The path to the application firmware image secondary slot character | ||
device driver. | ||
Default: /dev/ota1 | ||
|
||
config MCUBOOT_SCRATCH_PATH | ||
string "Scratch partition path" | ||
default "/dev/otascratch" | ||
---help--- | ||
The path to the scratch partition character device driver. | ||
Default: /dev/otascratch | ||
|
||
config MCUBOOT_DEFAULT_FLASH_ERASE_STATE | ||
hex "Default flash erase state" | ||
default 0xff | ||
---help--- | ||
MCUboot will attempt to retrieve this value from the underlying MTD | ||
driver. | ||
In case of failure, the value from this config will be used as a | ||
fallback. | ||
|
||
endif # BOOT_MCUBOOT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
############################################################################ | ||
# apps/boot/mcuboot/Make.defs | ||
# | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. The | ||
# ASF licenses this file to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance with the | ||
# License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
# License for the specific language governing permissions and limitations | ||
# under the License. | ||
# | ||
############################################################################ | ||
|
||
ifeq ($(CONFIG_BOOT_MCUBOOT),y) | ||
CONFIGURED_APPS += $(APPDIR)/boot/mcuboot | ||
|
||
# It allows import of NuttX implementation headers for MCUboot interfaces. | ||
|
||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/boot/mcuboot/mcuboot/boot/nuttx/include} | ||
CXXFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/boot/mcuboot/mcuboot/boot/nuttx/include} | ||
|
||
# It allows import of MCUboot's bootutil library headers. | ||
|
||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/boot/mcuboot/mcuboot/boot/bootutil/include} | ||
CXXFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/boot/mcuboot/mcuboot/boot/bootutil/include} | ||
|
||
endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
############################################################################ | ||
# apps/boot/mcuboot/Makefile | ||
# | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. The | ||
# ASF licenses this file to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance with the | ||
# License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
# License for the specific language governing permissions and limitations | ||
# under the License. | ||
# | ||
############################################################################ | ||
|
||
include $(APPDIR)/Make.defs | ||
|
||
MCUBOOT_VERSION := $(patsubst "%",%,$(CONFIG_MCUBOOT_VERSION)) | ||
MCUBOOT_TARBALL = $(MCUBOOT_VERSION).tar.gz | ||
MCUBOOT_UNPACK = mcuboot | ||
MCUBOOT_SRCDIR = $(MCUBOOT_UNPACK)$(DELIM)boot$(DELIM)bootutil$(DELIM)src | ||
|
||
DEPPATH += --dep-path $(MCUBOOT_UNPACK)$(DELIM)src | ||
DEPPATH += --dep-path $(MCUBOOT_SRCDIR) | ||
VPATH += :$(MCUBOOT_UNPACK)$(DELIM)src | ||
VPATH += :$(MCUBOOT_SRCDIR) | ||
|
||
ifneq ($(CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE),) | ||
MAINSRC = mcuboot_agent_main.c | ||
|
||
PROGNAME = mcuboot_agent | ||
PRIORITY = SCHED_PRIORITY_DEFAULT | ||
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) | ||
else ifneq ($(CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE),) | ||
MAINSRC = mcuboot_confirm_main.c | ||
|
||
PROGNAME = mcuboot_confirm | ||
PRIORITY = SCHED_PRIORITY_DEFAULT | ||
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) | ||
else ifneq ($(CONFIG_MCUBOOT_BOOTLOADER),) | ||
MAINSRC = mcuboot/boot/nuttx/main.c | ||
|
||
PROGNAME = mcuboot_loader | ||
PRIORITY = SCHED_PRIORITY_DEFAULT | ||
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE) | ||
endif | ||
|
||
CSRCS := mcuboot/boot/bootutil/src/boot_record.c \ | ||
mcuboot/boot/bootutil/src/bootutil_misc.c \ | ||
mcuboot/boot/bootutil/src/bootutil_public.c \ | ||
mcuboot/boot/bootutil/src/caps.c \ | ||
mcuboot/boot/bootutil/src/encrypted.c \ | ||
mcuboot/boot/bootutil/src/fault_injection_hardening.c \ | ||
mcuboot/boot/bootutil/src/fault_injection_hardening_delay_rng_mbedtls.c \ | ||
mcuboot/boot/bootutil/src/image_ec.c \ | ||
mcuboot/boot/bootutil/src/image_ec256.c \ | ||
mcuboot/boot/bootutil/src/image_ed25519.c \ | ||
mcuboot/boot/bootutil/src/image_rsa.c \ | ||
mcuboot/boot/bootutil/src/image_validate.c \ | ||
mcuboot/boot/bootutil/src/loader.c \ | ||
mcuboot/boot/bootutil/src/swap_misc.c \ | ||
mcuboot/boot/bootutil/src/swap_move.c \ | ||
mcuboot/boot/bootutil/src/swap_scratch.c \ | ||
mcuboot/boot/bootutil/src/tlv.c \ | ||
mcuboot/boot/nuttx/src/flash_map_backend/flash_map_backend.c | ||
|
||
ifneq ($(CONFIG_MCUBOOT_WATCHDOG),) | ||
CSRCS += mcuboot/boot/nuttx/src/watchdog/watchdog.c | ||
endif | ||
|
||
$(MCUBOOT_TARBALL): | ||
$(Q) echo "Downloading MCUboot-$(MCUBOOT_VERSION)" | ||
$(Q) curl -O -L https://github.com/mcu-tools/mcuboot/archive/$(MCUBOOT_TARBALL) | ||
|
||
$(MCUBOOT_UNPACK): $(MCUBOOT_TARBALL) | ||
$(Q) echo "Unpacking: $(MCUBOOT_TARBALL) -> $(MCUBOOT_UNPACK)" | ||
$(Q) tar zxf $(MCUBOOT_TARBALL) | ||
$(Q) mv mcuboot-$(MCUBOOT_VERSION) $(MCUBOOT_UNPACK) | ||
$(Q) touch $(MCUBOOT_UNPACK) | ||
|
||
context:: $(MCUBOOT_UNPACK) | ||
|
||
distclean:: | ||
$(call DELFILE, $(MCUBOOT_TARBALL)) | ||
$(call DELDIR, $(MCUBOOT_UNPACK)) | ||
|
||
include $(APPDIR)/Application.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Boot / `mcuboot` MCUboot | ||
|
||
## Description | ||
|
||
The NuttX port of MCUboot secure boot library expects that the platform provides a Flash storage with the following partitions: | ||
- `CONFIG_MCUBOOT_PRIMARY_SLOT_PATH`: MTD partition for the application firmware image PRIMARY slot; | ||
- `CONFIG_MCUBOOT_SECONDARY_SLOT_PATH`: MTD partition for the application firmware image SECONDARY slot; | ||
- `CONFIG_MCUBOOT_SCRATCH_PATH`: MTD partition for the Scratch area; | ||
|
||
Also, these are optional features that may be enabled: | ||
|
||
- `CONFIG_MCUBOOT_WATCHDOG`: If `CONFIG_WATCHDOG` is enabled, MCUboot shall reset the watchdog timer indicated by `CONFIG_MCUBOOT_WATCHDOG_DEVPATH` to the current timeout value, preventing any imminent watchdog timeouts. | ||
|
||
The porting layer of MCUboot library consists of the following interfaces: | ||
- `<flash_map_backend/flash_map_backend.h>`, for enabling MCUboot to manage the application firmware image slots in the device storage. | ||
- `<mcuboot_config/mcuboot_config.h>`, for configuration of MCUboot's features. | ||
- `<mcuboot_config/mcuboot_logging.h>`, for providing logging capabilities. | ||
- `<os/os_malloc.h>`, for providing MCUboot access to the OS memory management interfaces. | ||
- `<sysflash/sysflash.h>`, for configuration of the system's flash area organization. | ||
|
||
The NuttX port of MCUboot is implemented at application-level and requires minimal knowledge about characteristics of the underlying storage device. This is achieved by means of the `BCH` and `FTL` subsystems, which enable MCUboot to manage MTD partitions via character device drivers using standard POSIX filesystem operations (e.g. `open()` / `close()` / `read()` / `write()`). | ||
|
||
## Creating MCUboot-compatible application firmware images | ||
|
||
One common use case for MCUboot is to integrate it to a firmware update agent, which is an important component of a secure firmware update subsystem. Through MCUboot APIs an application is able to install a newly received application firmware image and, once this application firmware image is assured to be valid, the application may confirm it as a stable image. In case that application firmware image is deemed bogus, MCUboot provides an API for invalidating that update, which will induce a rollback procedure to the most recent stable application firmware image. | ||
|
||
The `CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE` example demonstrates this workflow by downloading an application firmware image from a webserver, installing it and triggering the firmware update process for the next boot after a system reset. There is also the `CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE`, which is a fairly simple example that just calls an MCUboot API for confirming the executing application firmware image as stable. | ||
|
||
## Using MCUboot on NuttX as a secure boot solution | ||
|
||
NuttX port for MCUboot also enables the creation of a secure bootloader application requiring minimal platform-specific implementation. The logical implementation for the secure boot is performed at application-level by the MCUboot library. Once MCUboot validates the application firmware image, it delegates the loading and execution of the application firmware image to a platform-specific routine, which is accessed via `boardctl(BOARDIOC_BOOT_IMAGE)` call. Each platform must then provide an implementation for the `board_boot_image()` for executing the required actions in order to boot a new application firmware image (e.g. deinitialize peripherals, load the Program Counter register with the application firmware image entry point address). | ||
|
||
The MCUboot bootloader application may be enabled by selecting the `CONFIG_MCUBOOT_BOOTLOADER` option. | ||
|
||
## Assumptions | ||
|
||
### IOCTL MTD commands | ||
|
||
The implementation of `<flash_map_backend/flash_map_backend.h>` expects that the MTD driver for a given image partition handles the following `ioctl` commands: | ||
- `MTDIOC_GEOMETRY`, for retrieving information about the geometry of the MTD, required for the configuration of the size of each flash area. | ||
- `MTDIOC_ERASESTATE`, for retrieving the byte value of an erased cell of the MTD, required for the implementation of `flash_area_erased_val()` interface. | ||
|
||
### Write access alignment | ||
|
||
Through `flash_area_align()` interface MCUboot expects that the implementation provides the shortest data length that may be written via `flash_area_write()` interface. The NuttX implementation passes through the `BCH` and `FTL` layers, which appropriately handle the write alignment restrictions of the underlying MTD. So The NuttX implementation of `flash_area_align()` is able to return a fixed value of 1 byte, even if the MTD does not support byte operations. | ||
|
||
## Limitations | ||
|
||
### `<flash_map_backend/flash_map_backend.h>` functions are not multitasking-safe | ||
|
||
MCUboot's documentation imposes no restrictions regarding the usage of its public interfaces, which doesn't mean they are thread-safe. | ||
But, regarding NuttX implementation of the `<flash_map_backend/flash_map_backend.h>`, it is safe to state that they are **not** multitasking-safe. NuttX implementation manages the MTD partitions via character device drivers. As file-descriptors cannot be shared between different tasks, if one task calls `flash_area_open` and another task calls `flash_area_<read/write/close>` passing the same `struct flash_area` instance, it will result in failure. |
Oops, something went wrong.