Skip to content

Commit 2345138

Browse files
julek-wolfssldanielinux
authored andcommitted
Implement filesystem-based partition state access and CLI tools
- Add filesystem access implementation in HAL (`hal/filesystem.c`) - Introduce new library_fs target and build rules for filesystem-backed partition management - Provide example configuration for library_fs - Add CLI application (`hal/library_fs.c`) to query and manage partitions - Update documentation with usage instructions and build steps for the new CLI tool - Update .gitignore
1 parent b795cce commit 2345138

File tree

15 files changed

+689
-5
lines changed

15 files changed

+689
-5
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ tools/tpm/policy_create
118118
tools/tpm/policy_sign
119119
config/*.ld
120120
test-lib
121+
lib-fs
121122

122123
# Elf preprocessing tools
123124
tools/squashelf/**
@@ -275,3 +276,7 @@ language.settings.xml
275276
/**/build
276277
/**/build-**
277278

279+
# Eclipse
280+
.cproject
281+
.project
282+
.settings/

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ ifeq ($(TARGET),library)
164164
MAIN_TARGET:=libwolfboot.a
165165
endif
166166

167+
ifeq ($(TARGET),library_fs)
168+
MAIN_TARGET:=libwolfboot.a
169+
endif
170+
167171
ifeq ($(TARGET),raspi3)
168172
MAIN_TARGET:=wolfboot.bin
169173
endif
@@ -214,6 +218,10 @@ test-lib: libwolfboot.a hal/library.o
214218
@echo "\t[BIN] $@"
215219
$(Q)$(CC) $(CFLAGS) -o $@ hal/library.o libwolfboot.a
216220

221+
lib-fs: libwolfboot.a hal/library_fs.o hal/filesystem.o
222+
@echo "\t[BIN] $@"
223+
$(Q)$(CC) $(CFLAGS) -o $@ hal/library_fs.o hal/filesystem.o libwolfboot.a
224+
217225
wolfboot.efi: wolfboot.elf
218226
@echo "\t[BIN] $@"
219227
$(Q)$(OBJCOPY) -j .rodata -j .text -j .sdata -j .data \
@@ -440,6 +448,8 @@ clean:
440448
$(Q)rm -f tools/keytools/otp/otp-keystore-gen
441449
$(Q)rm -f .stack_usage
442450
$(Q)rm -f $(WH_NVM_BIN) $(WH_NVM_HEX)
451+
$(Q)rm -f test-lib
452+
$(Q)rm -f lib-fs
443453
$(Q)$(MAKE) -C test-app clean V=$(V)
444454
$(Q)$(MAKE) -C tools/check_config -s clean
445455
$(Q)$(MAKE) -C stage1 -s clean

arch.mk

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,8 +1101,13 @@ ifeq ($(ARCH),sim)
11011101
USE_GCC_HEADLESS=0
11021102
LD = gcc
11031103
ifneq ($(TARGET),library)
1104+
ifneq ($(TARGET),library_fs)
11041105
UPDATE_OBJS:=src/update_flash.o
11051106
endif
1107+
endif
1108+
ifeq ($(TARGET),library_fs)
1109+
UPDATE_OBJS += hal/filesystem.o
1110+
endif
11061111
LD_START_GROUP=
11071112
LD_END_GROUP=
11081113
BOOT_IMG=test-app/image.elf
@@ -1318,6 +1323,14 @@ ifeq ($(TARGET),library)
13181323
NO_LOADER=1
13191324
endif
13201325

1326+
ifeq ($(TARGET),library_fs)
1327+
EXT_FLASH=1
1328+
# Force all partitions to be marked as external
1329+
NO_XIP=1
1330+
NO_SWAP_EXT=
1331+
endif
1332+
1333+
13211334
## Set default update object
13221335
ifneq ($(WOLFBOOT_NO_PARTITIONS),1)
13231336
ifeq ($(UPDATE_OBJS),)

config/examples/library_fs.config

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
ARCH=sim
2+
TARGET=library_fs
3+
4+
SIGN?=ED25519
5+
HASH?=SHA256
6+
IMAGE_HEADER_SIZE?=256
7+
DEBUG=0
8+
SPMATH?=0
9+
SPMATHALL?=0
10+
11+
# Flash Partition Filename
12+
WOLFBOOT_PARTITION_FILENAME=\"internal_flash.dd\"
13+
EXT_FLASH=1
14+
15+
# Flash Sector Size
16+
WOLFBOOT_SECTOR_SIZE=0x1000
17+
# Application Partition Size
18+
WOLFBOOT_PARTITION_SIZE=0x40000
19+
# Location in flash for boot partition
20+
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x80000
21+
# Location in flash for update partition
22+
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x100000
23+
# Location in flash for swap
24+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x180000

config/examples/zynqmp.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ WOLFBOOT_SECTOR_SIZE=0x20000
6363
# Application Partition Size
6464
WOLFBOOT_PARTITION_SIZE=0x2A00000
6565
# Location in Flash for wolfBoot
66+
WOLFBOOT_ORIGIN=0x0
67+
# Location in Flash for Primary Boot Partition
6668
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x800000
6769
# Load Partition to RAM Address
6870
WOLFBOOT_LOAD_ADDRESS?=0x10000000

docs/lib.md

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ of the manifest header.
2121

2222

2323
On success, zero is returned. If the image does not contain a valid 'magic number' at the beginning
24-
of the manifest, or if the size of the image is bigger than `WOLFBOOT_PARTITION_SIZE`, -1 is returned.
24+
of the manifest, or if the size of the image is bigger than `WOLFBOOT_PARTITION_SIZE`, -1 is returned.
2525

2626

2727
If the `open_image_address` operation is successful, two other functions can be invoked:
@@ -123,3 +123,98 @@ Firmware Valid
123123
booting 0x5609e3526590(actually exiting)
124124
```
125125

126+
## Library mode: Partition Manager CLI Example
127+
128+
An example application using filesystem access is provided in `hal/library_fs.c`.
129+
130+
The CLI application `lib-fs` allow querying partition states, triggering updates, and marking the boot partition as successful.
131+
132+
### Building the lib-fs example
133+
134+
To generate and verify a signed boot partition using simulation and library_fs targets, follow these steps.
135+
You can run these steps using the provided script at `tools/scripts/build_lib_fs_example.sh`:
136+
137+
```
138+
./tools/scripts/build_lib_fs_example.sh
139+
```
140+
141+
Alternatively, you can perform the steps manually as described below:
142+
143+
Step 1: Copy the configuration for simulation and build the signed boot partition:
144+
```
145+
cp config/examples/sim.config .config
146+
make
147+
```
148+
This will generate a file with a signed boot partition named `internal_flash.dd`.
149+
150+
Step 2: Change the target back to `library_fs`:
151+
```
152+
cp config/examples/library_fs.config .config
153+
```
154+
155+
Step 3: Ensure that the partition layout in `sim.config` matches the layout in `library_fs.config`.
156+
157+
Step 4: Clean previous build artifacts and build the CLI application:
158+
```
159+
make clean
160+
make lib-fs
161+
```
162+
This will produce the `lib-fs` executable.
163+
164+
Step 5: Mark the BOOT partition as successfully loaded:
165+
```
166+
./lib-fs success
167+
```
168+
169+
Step 6: Verify the integrity and authenticity of the BOOT partition:
170+
```
171+
./lib-fs verify-boot
172+
```
173+
174+
### Using the Partition Manager CLI
175+
176+
The example configuration points the binary to access `/dev/mtd0` for partition data. You can simulate this file path with `modprobe mtdram total_size=16384 erase_size=128`. You may need to adjust the file permissions to allow read/write access.
177+
178+
Run the application with one of the supported commands:
179+
180+
```
181+
./lib-fs <command>
182+
```
183+
184+
Available commands:
185+
186+
- `status` : Show state of all partitions
187+
- `get-boot` : Get BOOT partition state
188+
- `get-update` : Get UPDATE partition state
189+
- `update-trigger` : Trigger an update (sets UPDATE partition to UPDATING)
190+
- `success` : Mark BOOT partition as SUCCESS
191+
- `verify-boot` : Verify integrity and authenticity of BOOT partition
192+
- `verify-update` : Verify integrity and authenticity of UPDATE partition
193+
- `help` : Show usage information
194+
195+
#### Example usage
196+
197+
Show all partition states:
198+
```
199+
./lib-fs status
200+
```
201+
202+
Trigger an update:
203+
```
204+
./lib-fs update-trigger
205+
```
206+
207+
Mark the boot partition as successful:
208+
```
209+
./lib-fs success
210+
```
211+
212+
Verify BOOT partition:
213+
```
214+
./lib-fs verify-boot
215+
```
216+
217+
Verify UPDATE partition:
218+
```
219+
./lib-fs verify-update
220+
```

hal/filesystem.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/* filesystem.c
2+
*
3+
* Copyright (C) 2025 wolfSSL Inc.
4+
*
5+
* This file is part of wolfBoot.
6+
*
7+
* wolfBoot is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfBoot is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*/
21+
22+
23+
#include "hal.h"
24+
#include "wolfboot/wolfboot.h"
25+
#include "printf.h"
26+
27+
#ifndef WOLFBOOT_PARTITION_FILENAME
28+
#error "WOLFBOOT_PARTITION_FILENAME needs to be defined for filesystem HAL"
29+
#endif
30+
31+
#ifndef MIN
32+
#define MIN(x,y) ((x)<(y)?(x):(y))
33+
#endif
34+
35+
/* HAL Stubs */
36+
void hal_init(void)
37+
{
38+
return;
39+
}
40+
int hal_flash_write(uintptr_t address, const uint8_t *data, int len)
41+
{
42+
(void)address;
43+
(void)data;
44+
(void)len;
45+
return -1;
46+
}
47+
int hal_flash_erase(uintptr_t address, int len)
48+
{
49+
(void)address;
50+
(void)len;
51+
return -1;
52+
}
53+
void hal_flash_unlock(void)
54+
{
55+
return;
56+
}
57+
void hal_flash_lock(void)
58+
{
59+
return;
60+
}
61+
void hal_prepare_boot(void)
62+
{
63+
return;
64+
}
65+
void do_boot(const uint32_t *app_offset)
66+
{
67+
(void)app_offset;
68+
}
69+
70+
/* filesystem access */
71+
static XFILE fp = XBADFILE;
72+
static byte fp_write = 0;
73+
static long fp_size = 0;
74+
75+
static int setup_file(byte read_only)
76+
{
77+
if (fp != XBADFILE) {
78+
if (!read_only && !fp_write) {
79+
/* Need to reopen to allow writing */
80+
XFCLOSE(fp);
81+
fp = XBADFILE;
82+
}
83+
}
84+
if (fp == XBADFILE) {
85+
fp = XFOPEN(WOLFBOOT_PARTITION_FILENAME, read_only ? "rb" : "r+b");
86+
if (fp != XBADFILE) {
87+
fp_write = !read_only;
88+
if (XFSEEK(fp, 0, XSEEK_END) < 0 || (fp_size = XFTELL(fp)) < 0 ||
89+
XFSEEK(fp, 0, XSEEK_SET) < 0) {
90+
/* Failed to get the file size */
91+
XFCLOSE(fp);
92+
fp = XBADFILE;
93+
}
94+
}
95+
}
96+
return fp != XBADFILE ? 0 : -1;
97+
}
98+
99+
int ext_flash_write(uintptr_t address, const uint8_t *data, int len)
100+
{
101+
if (setup_file(0) != 0)
102+
return -1;
103+
if (address + len > (uintptr_t)fp_size)
104+
return -1; /* Don't allow writing past the file size */
105+
if (XFSEEK(fp, address, XSEEK_SET) < 0)
106+
return -1;
107+
if ((int)XFWRITE(data, 1, len, fp) != len)
108+
return -1;
109+
if (XFFLUSH(fp) != 0)
110+
return -1;
111+
return 0;
112+
}
113+
114+
int ext_flash_read(uintptr_t address, uint8_t *data, int len)
115+
{
116+
if (setup_file(1) != 0)
117+
return -1;
118+
if (XFSEEK(fp, address, XSEEK_SET) < 0)
119+
return -1;
120+
return (int)XFREAD(data, 1, len, fp);
121+
}
122+
int ext_flash_erase(uintptr_t address, int len)
123+
{
124+
byte zeros[256];
125+
XMEMSET(zeros, 0, sizeof(zeros));
126+
for (; len > 0; len -= sizeof(zeros), address += sizeof(zeros)) {
127+
if (ext_flash_write(address, zeros, (int)MIN((int)sizeof(zeros), len)) != 0)
128+
return -1;
129+
}
130+
return 0;
131+
}
132+
void ext_flash_lock(void)
133+
{
134+
return;
135+
}
136+
void ext_flash_unlock(void)
137+
{
138+
return;
139+
}

hal/library.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ int wolfBoot_start(void)
142142
exit:
143143
if (ret < 0) {
144144
wolfBoot_printf("Failure %d: Hdr %d, Hash %d, Sig %d\n", ret,
145-
os_image.hdr_ok, os_image.sha_ok, os_image.signature_ok);
145+
(int)os_image.hdr_ok, (int)os_image.sha_ok,
146+
(int)os_image.signature_ok);
146147
}
147148

148149
return 0;

0 commit comments

Comments
 (0)