Skip to content

Commit 63eb744

Browse files
authored
Merge pull request #14 from wolfSSL/hifive1-hal
SiFive HiFive (FE310) RISC-V support
2 parents 11dd4f1 + 88d0e4d commit 63eb744

60 files changed

Lines changed: 1729 additions & 345 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
@@ -36,6 +36,7 @@
3636
*.x86_64
3737
*.hex
3838
*.rom
39+
*.bin
3940

4041
# Debug files
4142
*.dSYM/
@@ -66,4 +67,11 @@ tools/ecc256/ecc256_keygen
6667
cscope.out
6768
tags
6869

70+
# Generated files using target.h
71+
.wolfboot-arch-offset
72+
.wolfboot-offset
73+
.wolfboot-partition-size
6974

75+
# Test tools
76+
tools/test-expect-version/test-expect-version
77+
tools/test-update-server/server

Makefile

Lines changed: 5 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]"
@@ -154,6 +153,7 @@ test-app/image.bin:
154153
KINETIS_CMSIS=$(KINETIS_CMSIS) NVM_FLASH_WRITEONCE=$(NVM_FLASH_WRITEONCE) \
155154
FREEDOM_E_SDK=$(FREEDOM_E_SDK)
156155
@rm -f src/*.o hal/*.o
156+
@$(SIZE) test-app/image.elf
157157

158158
include tools/test.mk
159159

README.md

Lines changed: 3 additions & 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
@@ -50,6 +51,8 @@ microcontrollers will be added later. Relocating the interrupt vector can be dis
5051

5152
### Examples provided
5253

54+
Additional examples available on our GitHub wolfBoot-examples repository [here](https://github.com/wolfSSL/wolfBoot-examples).
55+
5356
The following steps are automated in the default `Makefile` target, using the baremetal test
5457
application as an example to create the factory image. By running `make`, the build system will:
5558

arch.mk

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ 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)
@@ -43,12 +45,20 @@ endif
4345
## RISCV
4446
ifeq ($(ARCH),RISCV)
4547
CROSS_COMPILE:=riscv32-unknown-elf-
46-
CFLAGS+=-fno-builtin-printf -DUSE_PLIC -DUSE_M_TIME -g -march=rv32imac -mabi=ilp32 -mcmodel=medany -nostartfiles -DARCH_RISCV
48+
CFLAGS+=-fno-builtin-printf -DUSE_M_TIME -g -march=rv32imac -mabi=ilp32 -mcmodel=medany -nostartfiles -DARCH_RISCV
4749
LDFLAGS+=-march=rv32imac -mabi=ilp32 -mcmodel=medany
50+
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
51+
52+
# Prune unused functions and data
53+
CFLAGS +=-ffunction-sections -fdata-sections
54+
LDFLAGS+=-Wl,--gc-sections
55+
4856
OBJS+=src/boot_riscv.o src/vector_riscv.o
49-
ARCH_FLASH_OFFSET=0x20400000
57+
ARCH_FLASH_OFFSET=0x20010000
5058
endif
5159

60+
CFLAGS+=-DARCH_FLASH_OFFSET=$(ARCH_FLASH_OFFSET)
61+
5262
## Toolchain setup
5363
CC=$(CROSS_COMPILE)gcc
5464
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: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Targets
2+
3+
## STM32-F407
4+
5+
Example 512KB partitioning on STM32-F407
6+
7+
The example firmware provided in the `test-app` is configured to boot from the primary partition
8+
starting at address 0x20000. The flash layout is provided by the default example using the following
9+
configuration in `target.h`:
10+
11+
```C
12+
#define WOLFBOOT_SECTOR_SIZE 0x20000
13+
#define WOLFBOOT_PARTITION_SIZE 0x20000
14+
15+
#define WOLFBOOT_PARTITION_BOOT_ADDRESS 0x20000
16+
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x40000
17+
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x60000
18+
```
19+
20+
This results in the following partition configuration:
21+
22+
![example partitions](png/example_partitions.png)
23+
24+
This configuration demonstrates one of the possible layouts, with the slots
25+
aligned to the beginning of the physical sector on the flash.
26+
27+
The entry point for all the runnable firmware images on this target will be `0x20100`,
28+
256 Bytes after the beginning of the first flash partition. This is due to the presence
29+
of the firmware image header at the beginning of the partition, as explained more in details
30+
in [Firmware image](firmware_image.md)
31+
32+
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.
33+
34+
On other systems, the SWAP space can be as small as 512B, if multiple smaller flash blocks are used.
35+
36+
More information about the geometry of the flash and in-application programming (IAP) can be found in the manufacturer manual of each target device.
37+
38+
39+
## SiFive HiFive1 RISC-V
40+
41+
### Features
42+
* E31 RISC-V 320MHz 32-bit processor
43+
* Onboard 16KB scratchpad RAM
44+
* External 4MB QSPI Flash
45+
46+
### Default Linker Settings
47+
* FLASH: Address 0x20000000, Len 0x6a120 (424 KB)
48+
* RAM: Address 0x80000000, Len 0x4000 (16 KB)
49+
50+
### Stock bootloader
51+
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.
52+
53+
### Application Code
54+
Start Address: 0x20010000
55+
56+
### wolfBoot configuration
57+
58+
The default wolfBoot configuration will add a second stage bootloader, leaving the stock "double tap" bootloader as a fallback for recovery. Your production implementation should replace this and partition addresses in `target.h` will need updated, so they are `0x10000` less.
59+
60+
For testing wolfBoot here are the changes required:
61+
62+
1. Makefile arguments:
63+
* ARCH=RISCV
64+
* TARGET=hifive1
65+
66+
```
67+
make ARCH=RISCV TARGET=hifive1 RAM_CODE=1 clean
68+
make ARCH=RISCV TARGET=hifive1 RAM_CODE=1
69+
```
70+
71+
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:
72+
73+
```
74+
ifeq ($(ARCH),RISCV)
75+
- CROSS_COMPILE:=riscv32-unknown-elf-
76+
+ CROSS_COMPILE:=riscv64-unknown-elf-
77+
```
78+
79+
80+
2. `include/target.h`
81+
82+
Bootloader Size: 0x10000 (64KB)
83+
Application Size 0x40000 (256KB)
84+
Swap Sector Size: 0x1000 (4KB)
85+
86+
```c
87+
#define WOLFBOOT_SECTOR_SIZE 0x1000
88+
#define WOLFBOOT_PARTITION_BOOT_ADDRESS 0x20020000
89+
90+
#define WOLFBOOT_PARTITION_SIZE 0x40000
91+
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x20060000
92+
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x200A0000
93+
```
94+
95+
### Build Options
96+
97+
* To use ECC instead of ED25519 use make argument `SIGN=ECC256`
98+
* To output wolfboot as hex for loading with JLink use make argument `wolfboot.hex`
99+
100+
### Loading
101+
102+
Loading with JLink:
103+
104+
```
105+
JLinkExe -device FE310 -if JTAG -speed 4000 -jtagconf -1,-1 -autoconnect 1
106+
loadbin factory.bin 0x20010000
107+
rnh
108+
```
109+
110+
### Debugging
111+
112+
Debugging with JLink:
113+
114+
In one terminal:
115+
`JLinkGDBServer -device FE310 -port 3333`
116+
117+
In another terminal:
118+
```
119+
riscv64-unknown-elf-gdb wolfboot.elf -ex "set remotetimeout 240" -ex "target extended-remote localhost:3333"
120+
add-symbol-file test-app/image.elf 0x20020100
121+
```
122+
123+
```
124+
riscv64-unknown-elf-objdump -D test-app/image.elf
125+
```

docs/compile.md

Lines changed: 20 additions & 1 deletion
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`
@@ -136,3 +136,22 @@ both `PART_UPDATE_EXT` and `PART_SWAP_EXT` are defined.
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.
138138

139+
### Using Mac OS/X
140+
141+
If you see 0xC3 0xBF (C3BF) repeated in your factory.bin then your OS is using Unicode characters.
142+
143+
The "tr" command for assembling the 0xFF padding between `"bootloader" ... 0xFF ... "application" = factory.bin`, which requires the "C" locale.
144+
145+
Set this in your terminal
146+
```
147+
LANG=
148+
LC_COLLATE="C"
149+
LC_CTYPE="C"
150+
LC_MESSAGES="C"
151+
LC_MONETARY="C"
152+
LC_NUMERIC="C"
153+
LC_TIME="C"
154+
LC_ALL=
155+
```
156+
157+
Then run the normal `make` steps.

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)