Skip to content

Commit 0f00f8e

Browse files
committed
SiFive HiFive (FE310) RISC-V support
* HiFive1 HAL Support for PLL Clock, UART, RTC and Flash QSPI Erase/Write. * HiFive1 update demo application for accepting firmware updates over UART. * Added test-update-server application for pushing firmware image over UART. * Fixes for building with `make SIGN=ECC256`. * Improvements to wolfCrypt `user_settings.h`. * General library cleanup (license headers and formatting) * Updated the wolfSSL submodule to latest. * Documentation updates including new `Targets.md` section for hardare instructions.
1 parent 11dd4f1 commit 0f00f8e

57 files changed

Lines changed: 1429 additions & 305 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,11 @@ cscope.out
6767
tags
6868

6969

70+
image.bin
71+
image_v1_signed.bin
72+
.wolfboot-arch-offset
73+
.wolfboot-offset
74+
.wolfboot-partition-size
75+
factory.bin
76+
wolfboot-align.bin
77+
wolfboot.bin

Makefile

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
ARCH?=ARM
88
TARGET?=stm32f4
99
SIGN?=ED25519
10-
TARGET?=stm32f4
1110
KINETIS?=$(HOME)/src/FRDM-K64F
1211
KINETIS_CPU=MK64FN1M0VLL12
1312
KINETIS_DRIVERS?=$(KINETIS)/devices/MK64F12
@@ -135,12 +134,12 @@ wolfboot.hex: wolfboot.elf
135134
align: wolfboot-align.bin
136135

137136
wolfboot-align.bin: wolfboot.bin
138-
@cat include/target.h |grep WOLFBOOT_PARTITION_BOOT_ADDRESS | tr -d "\n\r" | sed -e "s/.*[ ]//g" > .wolfboot-offset
137+
@cat include/target.h | grep WOLFBOOT_PARTITION_BOOT_ADDRESS | tr -d "\n\r" | sed -e "s/.*[ ]//g" > .wolfboot-offset
139138
@printf "%d" `cat .wolfboot-offset` > .wolfboot-offset
140-
@printf "%d" $(ARCH_FLASH_OFFSET) >.wolfboot-arch-offset
141-
@expr `cat .wolfboot-offset` - `cat .wolfboot-arch-offset` >.wolfboot-partition-size
139+
@printf "%d" $(ARCH_FLASH_OFFSET) > .wolfboot-arch-offset
140+
@expr `cat .wolfboot-offset` - `cat .wolfboot-arch-offset` > .wolfboot-partition-size
142141
@dd if=/dev/zero bs=`cat .wolfboot-partition-size` count=1 2>/dev/null | tr "\000" "\377" > $(@)
143-
@rm -f .wolfboot-partition-size .wolfboot-offset .wolfboot-arch-offset
142+
@#rm -f .wolfboot-partition-size .wolfboot-offset .wolfboot-arch-offset
144143
@dd if=$^ of=$(@) conv=notrunc 2>/dev/null
145144
@echo
146145
@echo "\t[SIZE]"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ microcontrollers will be added later. Relocating the interrupt vector can be dis
4242

4343
### Required steps
4444

45+
- See `docs/Targets.md` for reference implementation examples.
4546
- Provide a HAL implementation for the target platform (see [Hardware Abstraction Layer](docs/HAL.md))
4647
- Decide a flash partition strategy and modify `include/target.h` accordingly (see [Flash partitions](docs/flash_partitions.md))
4748
- Change the entry point of the firmware image to account for bootloader presence

arch.mk

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@
22

33
# check for FASTMATH or SP_MATH
44
ifeq ($(SPMATH),1)
5-
MATH_OBJS:=./lib/wolfssl/wolfcrypt/src/sp_int.o
5+
MATH_OBJS:=./lib/wolfssl/wolfcrypt/src/sp_int.o ./lib/wolfssl/wolfcrypt/src/sp_c32.o
66
else
77
MATH_OBJS:=./lib/wolfssl/wolfcrypt/src/integer.o
88
endif
99

10+
# Default flash offset
11+
ARCH_FLASH_OFFSET=0x0
12+
1013
## ARM
1114
ifeq ($(ARCH),ARM)
1215
CROSS_COMPILE:=arm-none-eabi-
1316
CFLAGS+=-mthumb -mlittle-endian -mthumb-interwork -DARCH_ARM
1417
LDFLAGS+=-mthumb -mlittle-endian -mthumb-interwork
1518
OBJS+=src/boot_arm.o
16-
ARCH_FLASH_OFFSET=0x0
1719

1820
## Cortex-M CPU
1921
ifeq ($(CORTEX_M0),1)
@@ -46,9 +48,11 @@ ifeq ($(ARCH),RISCV)
4648
CFLAGS+=-fno-builtin-printf -DUSE_PLIC -DUSE_M_TIME -g -march=rv32imac -mabi=ilp32 -mcmodel=medany -nostartfiles -DARCH_RISCV
4749
LDFLAGS+=-march=rv32imac -mabi=ilp32 -mcmodel=medany
4850
OBJS+=src/boot_riscv.o src/vector_riscv.o
49-
ARCH_FLASH_OFFSET=0x20400000
51+
ARCH_FLASH_OFFSET=0x20010000
5052
endif
5153

54+
CFLAGS+=-DARCH_FLASH_OFFSET=$(ARCH_FLASH_OFFSET)
55+
5256
## Toolchain setup
5357
CC=$(CROSS_COMPILE)gcc
5458
LD=$(CROSS_COMPILE)gcc

docs/API.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ An application that requires interactions with wolfBoot must include the header
99

1010
`#include <wolfboot/wolfboot.h>`
1111

12-
Which exports the API function declarations, and the predefined values for the flags
13-
and the tags stored together with the firmware images in the two partitions.
12+
This exports the API function declarations, and the predefined values for the flags
13+
and tags stored together with the firmware images in the two partitions.
1414

1515
For more information about flash partitions, flags and states see [Flash partitions](flash_partitions.md).
1616

@@ -48,7 +48,7 @@ an update application that has retrieved a new version of the running firmware,
4848
stored it in the UPDATE partition on the flash. This function will set the state of the UPDATE partition
4949
to `STATE_UPDATING`, instructing the bootloader to perform the update upon the next execution (after reboot).
5050

51-
wolfBoot update process consist in swapping the content of the UPDATE and the BOOT partitions, using a temporary
51+
wolfBoot update process swaps the contents of the UPDATE and the BOOT partitions, using a temporary
5252
single-block SWAP space.
5353

5454
### Confirm current image
@@ -59,12 +59,10 @@ at any time, but it will only be effective to mark the current firmware (in the
5959
only after verifying that the basic system features are up and running, including the possibility to retrieve
6060
a new firmware for the next upgrade.
6161

62-
If after an upgrade wolfBoot detects that the active firmware is still in `STATE_TESTING` state, it means that
62+
If after an upgrade and reboot wolfBoot detects that the active firmware is still in `STATE_TESTING` state, it means that
6363
a successful boot has not been confirmed for the application, and will attempt to revert the update by swapping
6464
the two images again.
6565

6666
For more information about the update process, see [Firmware Update](firmware_update.md)
6767

6868
For the image format, see [Firmware Image](firmware_image.md)
69-
70-

docs/HAL.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
In order to run wolfBoot on a target microcontroller, an implementation of the HAL
44
must be provided.
55

6-
The HAL only purposes are allowing write/erase operations from the bootloader
6+
The HAL's purpose is to allow write/erase operations from the bootloader
77
and the application initiating the firmware upgrade through the application library, and
8-
ensuring that the MCU is running at full speed during boot, to optimize the
9-
verification of the signatures.
8+
ensuring that the MCU is running at full speed during boot (to optimize the
9+
verification of the signatures).
1010

1111
The implementation of the hardware-specific calls for each platform are grouped in
1212
a single c file in the [hal](../hal) directory.
1313

1414
The directory also contains a platform-specific linker script for each supported MCU,
15-
with the same name and the `.ld` extension. This is used to link the bootloader's
15+
with the same name and the `.ld` extension. This is used to link the bootloader's
1616
firmware on the specific hardware, exporting all the necessary symbols for flash
1717
and RAM boundaries.
1818

@@ -24,6 +24,7 @@ The following platforms are supported in the current version:
2424
- Atmel samR21
2525
- TI cc26x2
2626
- Kinetis
27+
- SiFive HiFive1 RISC-V
2728

2829
## API
2930

@@ -118,4 +119,3 @@ by the bootloader at the end of every write and erase operations on the external
118119
If the IAP interface of the external memory requires it, this function
119120
is called before every write and erase operations to unlock write access to the
120121
device. On some drivers, this function may be empty.
121-

docs/Targets.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Targets
2+
3+
## SiFive HiFive1 RISC-V
4+
5+
### Features
6+
* E31 RISC-V 320MHz 32-bit processor
7+
* Onboard 16KB scratchpad RAM
8+
* External 4MB QSPI Flash
9+
10+
### Default Linker Settings
11+
* FLASH: Address 0x20000000, Len 0x6a120 (424 KB)
12+
* RAM: Address 0x80000000, Len 0x4000 (16 KB)
13+
14+
### Stock bootloader
15+
Start Address: 0x20000000 is 64KB. Provides a "double tap" reset feature to halt boot and allow debugger to attach for reprogramming. Press reset button, when green light comes on press reset button again, then board will flash red.
16+
17+
### Application Code
18+
Start Address: 0x20010000
19+
20+
### wolfBoot configuration
21+
22+
The default wolfBoot configuration will add a second stage bootloader, leaving the stock "double tap" bootloader for safety.
23+
24+
For testing wolfBoot here are the changes required:
25+
26+
1. Makefile arguments:
27+
* ARCH?=RISCV
28+
* TARGET?=hifive1
29+
30+
```
31+
make ARCH=RISCV TARGET=hifive1 clean
32+
make ARCH=RISCV TARGET=hifive1
33+
```
34+
35+
If using the `riscv64-unknown-elf-` cross compiler you can add `CROSS_COMPILE=riscv64-unknown-elf-` to your `make` or modify `arch.mk` as follows:
36+
37+
```
38+
ifeq ($(ARCH),RISCV)
39+
- CROSS_COMPILE:=riscv32-unknown-elf-
40+
+ CROSS_COMPILE:=riscv64-unknown-elf-
41+
```
42+
43+
44+
2. `include/target.h`
45+
46+
Bootloader Size: 0x10000 (64KB)
47+
48+
```c
49+
#define WOLFBOOT_SECTOR_SIZE 0x10000
50+
#define WOLFBOOT_PARTITION_BOOT_ADDRESS 0x20010000
51+
```
52+
53+
Application Size 0x40000 (256KB)
54+
55+
```c
56+
#define WOLFBOOT_PARTITION_SIZE 0x40000
57+
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x20020000
58+
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x20060000
59+
```
60+
61+
## STM32-F407
62+
63+
Example 512KB partitioning on STM32-F407
64+
65+
The example firmware provided in the `test-app` is configured to boot from the primary partition
66+
starting at address 0x20000. The flash layout is provided by the default example using the following
67+
configuration in `target.h`:
68+
69+
```C
70+
#define WOLFBOOT_SECTOR_SIZE 0x20000
71+
#define WOLFBOOT_PARTITION_SIZE 0x20000
72+
73+
#define WOLFBOOT_PARTITION_BOOT_ADDRESS 0x20000
74+
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x40000
75+
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x60000
76+
```
77+
78+
This results in the following partition configuration:
79+
80+
![example partitions](png/example_partitions.png)
81+
82+
This configuration demonstrates one of the possible layouts, with the slots
83+
aligned to the beginning of the physical sector on the flash.
84+
85+
The entry point for all the runnable firmware images on this target will be `0x20100`,
86+
256 Bytes after the beginning of the first flash partition. This is due to the presence
87+
of the firmware image header at the beginning of the partition, as explained more in details
88+
in [Firmware image](firmware_image.md)
89+
90+
In this particular case, due to the flash geometry, the swap space must be as big as 64KB, to account for proper sector swapping between the two images.
91+
92+
On other systems, the SWAP space can be as small as 512B, if multiple smaller flash blocks are used.
93+
94+
More information about the geometry of the flash and in-application programming (IAP) can be found in the manufacturer manual of each target device.

docs/compile.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ in the [hal](../hal) directory.
2020

2121
Default option if none specified: `TARGET=stm32f4`
2222

23-
Some platform will require extra options, specific for the architecture.
23+
Some platforms will require extra options, specific for the architecture.
2424
By default, wolfBoot is compiled for ARM Cortex-M3/4/7. To compile for Cortex-M0, use:
2525

2626
`CORTEX_M0=1`
@@ -135,4 +135,3 @@ both `PART_UPDATE_EXT` and `PART_SWAP_EXT` are defined.
135135

136136
When external memory is used, the HAL API must be extended to define methods to access the custom memory.
137137
Refer to the [HAL](HAL.md) page for the description of the `ext_flash_*` API.
138-

docs/firmware_image.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
WolfBoot can only chain-load and execute firmware images from a specific entry point in memory,
66
which must be specified as the origin of the FLASH memory in the linker script of the embedded
7-
application. This correspond to the first partition in the flash memory.
7+
application. This corresponds to the first partition in the flash memory.
88

99
Multiple firmware images can be created this way, and stored in two different partitions. The bootloader
1010
will take care of moving the selected firmware to the first (BOOT) partition before chain-loading the image.

docs/firmware_update.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This section documents the complete firmware update procedure, enabling secure boot
44
for an existing embedded application.
55

6-
The steps to follow to complete a firmware update with wolfBoot are:
6+
The steps to complete a firmware update with wolfBoot are:
77
- Compile the firmware with the correct entry point
88
- Sign the firmware
99
- Transfer the image using a secure connection, and store it to the secondary firmware slot
@@ -51,10 +51,9 @@ is responsible for pre-validating an update image and copy it to the correct add
5151
All the firmware images must therefore have their entry point set to the address corresponding to the beginning
5252
of the **BOOT** partition, plus an offset of 256 Bytes to account for the image header.
5353

54-
Once the firmware is compiled and linked, it must be signed using the `ed25519_sign` tool. The tool produces
54+
Once the firmware is compiled and linked, it must be signed using the `sign` tool. The tool produces
5555
a signed image that can be transferred to the target using a secure connection, using the same key corresponding
5656
to the public key currently used for verification.
5757

5858
The tool also adds all the required Tags to the image header, containing the signatures and the SHA256 hash of
5959
the firmware.
60-

0 commit comments

Comments
 (0)