Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ tools/tpm/policy_create
tools/tpm/policy_sign
config/*.ld
test-lib
lib-fs

# Elf preprocessing tools
tools/squashelf/**
Expand Down Expand Up @@ -275,3 +276,7 @@ language.settings.xml
/**/build
/**/build-**

# Eclipse
.cproject
.project
.settings/
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ ifeq ($(TARGET),library)
MAIN_TARGET:=libwolfboot.a
endif

ifeq ($(TARGET),library_fs)
MAIN_TARGET:=libwolfboot.a
endif

ifeq ($(TARGET),raspi3)
MAIN_TARGET:=wolfboot.bin
endif
Expand Down Expand Up @@ -214,6 +218,10 @@ test-lib: libwolfboot.a hal/library.o
@echo "\t[BIN] $@"
$(Q)$(CC) $(CFLAGS) -o $@ hal/library.o libwolfboot.a

lib-fs: libwolfboot.a hal/library_fs.o hal/filesystem.o
@echo "\t[BIN] $@"
$(Q)$(CC) $(CFLAGS) -o $@ hal/library_fs.o hal/filesystem.o libwolfboot.a

wolfboot.efi: wolfboot.elf
@echo "\t[BIN] $@"
$(Q)$(OBJCOPY) -j .rodata -j .text -j .sdata -j .data \
Expand Down Expand Up @@ -440,6 +448,8 @@ clean:
$(Q)rm -f tools/keytools/otp/otp-keystore-gen
$(Q)rm -f .stack_usage
$(Q)rm -f $(WH_NVM_BIN) $(WH_NVM_HEX)
$(Q)rm -f test-lib
$(Q)rm -f lib-fs
$(Q)$(MAKE) -C test-app clean V=$(V)
$(Q)$(MAKE) -C tools/check_config -s clean
$(Q)$(MAKE) -C stage1 -s clean
Expand Down
13 changes: 13 additions & 0 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -1109,8 +1109,13 @@ ifeq ($(ARCH),sim)
USE_GCC_HEADLESS=0
LD = gcc
ifneq ($(TARGET),library)
ifneq ($(TARGET),library_fs)
UPDATE_OBJS:=src/update_flash.o
endif
endif
ifeq ($(TARGET),library_fs)
UPDATE_OBJS += hal/filesystem.o
endif
LD_START_GROUP=
LD_END_GROUP=
BOOT_IMG=test-app/image.elf
Expand Down Expand Up @@ -1326,6 +1331,14 @@ ifeq ($(TARGET),library)
NO_LOADER=1
endif

ifeq ($(TARGET),library_fs)
EXT_FLASH=1
# Force all partitions to be marked as external
NO_XIP=1
NO_SWAP_EXT=
endif


## Set default update object
ifneq ($(WOLFBOOT_NO_PARTITIONS),1)
ifeq ($(UPDATE_OBJS),)
Expand Down
24 changes: 24 additions & 0 deletions config/examples/library_fs.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ARCH=sim
TARGET=library_fs

SIGN?=ED25519
HASH?=SHA256
IMAGE_HEADER_SIZE?=256
DEBUG=0
SPMATH?=0
SPMATHALL?=0

# Flash Partition Filename
WOLFBOOT_PARTITION_FILENAME=\"internal_flash.dd\"
EXT_FLASH=1

# Flash Sector Size
WOLFBOOT_SECTOR_SIZE=0x1000
# Application Partition Size
WOLFBOOT_PARTITION_SIZE=0x40000
# Location in flash for boot partition
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x80000
# Location in flash for update partition
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x100000
# Location in flash for swap
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x180000
2 changes: 2 additions & 0 deletions config/examples/zynqmp.config
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ WOLFBOOT_SECTOR_SIZE=0x20000
# Application Partition Size
WOLFBOOT_PARTITION_SIZE=0x2A00000
# Location in Flash for wolfBoot
WOLFBOOT_ORIGIN=0x0
# Location in Flash for Primary Boot Partition
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x800000
# Load Partition to RAM Address
WOLFBOOT_LOAD_ADDRESS?=0x10000000
Expand Down
97 changes: 96 additions & 1 deletion docs/lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ of the manifest header.


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


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

## Library mode: Partition Manager CLI Example

An example application using filesystem access is provided in `hal/library_fs.c`.

The CLI application `lib-fs` allow querying partition states, triggering updates, and marking the boot partition as successful.

### Building the lib-fs example

To generate and verify a signed boot partition using simulation and library_fs targets, follow these steps.
You can run these steps using the provided script at `tools/scripts/build_lib_fs_example.sh`:

```
./tools/scripts/build_lib_fs_example.sh
```

Alternatively, you can perform the steps manually as described below:

Step 1: Copy the configuration for simulation and build the signed boot partition:
```
cp config/examples/sim.config .config
make
```
This will generate a file with a signed boot partition named `internal_flash.dd`.

Step 2: Change the target back to `library_fs`:
```
cp config/examples/library_fs.config .config
```

Step 3: Ensure that the partition layout in `sim.config` matches the layout in `library_fs.config`.

Step 4: Clean previous build artifacts and build the CLI application:
```
make clean
make lib-fs
```
This will produce the `lib-fs` executable.

Step 5: Mark the BOOT partition as successfully loaded:
```
./lib-fs success
```

Step 6: Verify the integrity and authenticity of the BOOT partition:
```
./lib-fs verify-boot
```

### Using the Partition Manager CLI

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.

Run the application with one of the supported commands:

```
./lib-fs <command>
```

Available commands:

- `status` : Show state of all partitions
- `get-boot` : Get BOOT partition state
- `get-update` : Get UPDATE partition state
- `update-trigger` : Trigger an update (sets UPDATE partition to UPDATING)
- `success` : Mark BOOT partition as SUCCESS
- `verify-boot` : Verify integrity and authenticity of BOOT partition
- `verify-update` : Verify integrity and authenticity of UPDATE partition
- `help` : Show usage information

#### Example usage

Show all partition states:
```
./lib-fs status
```

Trigger an update:
```
./lib-fs update-trigger
```

Mark the boot partition as successful:
```
./lib-fs success
```

Verify BOOT partition:
```
./lib-fs verify-boot
```

Verify UPDATE partition:
```
./lib-fs verify-update
```
145 changes: 145 additions & 0 deletions hal/filesystem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/* filesystem.c
*
* Copyright (C) 2025 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/


#include "hal.h"
#include "wolfboot/wolfboot.h"
#include "printf.h"

#ifndef WOLFBOOT_PARTITION_FILENAME
#error "WOLFBOOT_PARTITION_FILENAME needs to be defined for filesystem HAL"
#endif

#ifndef MIN
#define MIN(x,y) ((x)<(y)?(x):(y))
#endif

/* HAL Stubs */
void hal_init(void)
{
return;
}

int hal_flash_write(haladdr_t address, const uint8_t *data, int len)
{
(void)address;
(void)data;
(void)len;
return -1;
}
int hal_flash_erase(haladdr_t address, int len)
{
(void)address;
(void)len;
return -1;
}
void hal_flash_unlock(void)
{
return;
}
void hal_flash_lock(void)
{
return;
}
void hal_prepare_boot(void)
{
return;
}

#ifdef MMU
void do_boot(const uint32_t *app_offset, const uint32_t* dts_offset)
#else
void do_boot(const uint32_t *app_offset)
#endif
{
(void)app_offset;
}

/* filesystem access */
static XFILE fp = XBADFILE;
static byte fp_write = 0;
static long fp_size = 0;

static int setup_file(byte read_only)
{
if (fp != XBADFILE) {
if (!read_only && !fp_write) {
/* Need to reopen to allow writing */
XFCLOSE(fp);
fp = XBADFILE;
}
}
if (fp == XBADFILE) {
fp = XFOPEN(WOLFBOOT_PARTITION_FILENAME, read_only ? "rb" : "r+b");
if (fp != XBADFILE) {
fp_write = !read_only;
if (XFSEEK(fp, 0, XSEEK_END) < 0 || (fp_size = XFTELL(fp)) < 0 ||
XFSEEK(fp, 0, XSEEK_SET) < 0) {
/* Failed to get the file size */
XFCLOSE(fp);
fp = XBADFILE;
}
}
}
return fp != XBADFILE ? 0 : -1;
}

int ext_flash_write(uintptr_t address, const uint8_t *data, int len)
{
if (setup_file(0) != 0)
return -1;
if (address + len > (uintptr_t)fp_size)
return -1; /* Don't allow writing past the file size */
if (XFSEEK(fp, address, XSEEK_SET) < 0)
return -1;
if ((int)XFWRITE(data, 1, len, fp) != len)
return -1;
if (XFFLUSH(fp) != 0)
return -1;
return 0;
}

int ext_flash_read(uintptr_t address, uint8_t *data, int len)
{
if (setup_file(1) != 0)
return -1;
if (XFSEEK(fp, address, XSEEK_SET) < 0)
return -1;
return (int)XFREAD(data, 1, len, fp);
}
int ext_flash_erase(uintptr_t address, int len)
{
byte zeros[256];
XMEMSET(zeros, 0, sizeof(zeros));
for (; len > 0; len -= sizeof(zeros), address += sizeof(zeros)) {
if (ext_flash_write(address, zeros, (int)MIN((int)sizeof(zeros), len)) != 0)
return -1;
}
return 0;
}
void ext_flash_lock(void)
{
return;
}
void ext_flash_unlock(void)
{
return;
}
3 changes: 2 additions & 1 deletion hal/library.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ int wolfBoot_start(void)
exit:
if (ret < 0) {
wolfBoot_printf("Failure %d: Hdr %d, Hash %d, Sig %d\n", ret,
os_image.hdr_ok, os_image.sha_ok, os_image.signature_ok);
(int)os_image.hdr_ok, (int)os_image.sha_ok,
(int)os_image.signature_ok);
}

return 0;
Expand Down
Loading