mirror of https://github.com/wolfSSL/wolfBoot.git
Peer review fixes
parent
00313b3e43
commit
bc454d9f4b
2
Makefile
2
Makefile
|
|
@ -336,7 +336,7 @@ wolfboot.bin: wolfboot.elf
|
|||
$(Q)$(OBJCOPY) $(OBJCOPY_FLAGS) -O binary $^ $@
|
||||
ifeq ($(TARGET),nxp_lpc54s0xx)
|
||||
@echo "\t[LPC] enhanced boot block"
|
||||
$(Q)python3 -c "import struct,os;f=open('$@','r+b');sz=os.path.getsize('$@');f.seek(0x24);f.write(struct.pack('<2I',0xEDDC94BD,0x160));f.seek(0x160);f.write(struct.pack('<25I',0xFEEDA5A5,3,0x10000000,sz-4,0,0,0,0,0,0xEDDC94BD,0,0,0,0x001640EF,0,0,0x1301001D,0,0,0,0x00000100,0,0,0x04030050,0x14110D09));f.seek(0);d=f.read(28);w=struct.unpack('<7I',d);s=sum(w)&0xFFFFFFFF;ck=(0x100000000-s)&0xFFFFFFFF;f.seek(0x1C);f.write(struct.pack('<I',ck));f.close();print('\tvector checksum: 0x%08X'%ck)"
|
||||
$(Q)python3 tools/scripts/lpc54s0xx_patch_boot_block.py $@
|
||||
endif
|
||||
@echo
|
||||
@echo "\t[SIZE]"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
# Boot: ROM boot loads wolfBoot from external SPIFI QSPI flash at 0x10000000
|
||||
# HAL: Bare-metal (hal/nxp_lpc54s0xx.c) — no NXP MCUXpresso SDK required
|
||||
#
|
||||
# Flash layout (SPIFI QSPI, 16 MB total):
|
||||
# Flash layout (SPIFI QSPI, 4 MB total — Winbond W25Q32JV):
|
||||
# 0x10000000 wolfBoot (up to BOOT partition base)
|
||||
# 0x10010000 BOOT partition (960 KB, signed application)
|
||||
# 0x10100000 UPDATE partition (960 KB)
|
||||
|
|
|
|||
|
|
@ -440,6 +440,9 @@ static void RAMFUNCTION spifi_wait_busy(void)
|
|||
SPIFI_IDATA = 0x00; /* expect BUSY=0 */
|
||||
SPIFI_CLIMIT = (saved_climit & 0xFFFFFF00) | W25Q_STATUS_BUSY; /* mask bit 0 */
|
||||
|
||||
/* Callers (hal_flash_write / hal_flash_erase) always issue a non-MCMD
|
||||
* command before reaching here, so MCINIT is clear and the reset path in
|
||||
* spifi_set_cmd() does not run — IDATA/CLIMIT programmed above survive. */
|
||||
spifi_set_cmd(CMD_READ_STATUS); /* POLL mode command */
|
||||
|
||||
/* SPIFI hardware polls flash status internally.
|
||||
|
|
|
|||
|
|
@ -22,9 +22,15 @@
|
|||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* Forward declaration of vsnprintf. We intentionally do not include <stdio.h>
|
||||
* because this file redefines stdout/stderr/fputs/fflush with bare-metal
|
||||
* (void *) stubs that collide with the libc FILE-based prototypes. */
|
||||
extern int vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
|
||||
|
||||
/* Provide our own errno for bare-metal.
|
||||
* Using the libc errno via <errno.h> can conflict with TLS-based errno
|
||||
* on cross-toolchains (e.g. powerpc-linux-gnu glibc). */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env python3
|
||||
# lpc54s0xx_patch_boot_block.py
|
||||
#
|
||||
# Patch a wolfBoot binary for the NXP LPC540xx / LPC54S0xx SPIFI (XIP) boot
|
||||
# ROM. The ROM expects an "enhanced boot block":
|
||||
# - offset 0x1C: vector table checksum (negated sum of the first 7 words)
|
||||
# - offset 0x24: boot block marker + offset to descriptor
|
||||
# - offset 0x160: 25-word descriptor (magic, mode, image base, image size, ...)
|
||||
#
|
||||
# Usage: lpc54s0xx_patch_boot_block.py <wolfboot.bin>
|
||||
#
|
||||
# Copyright (C) 2025 wolfSSL Inc.
|
||||
# This file is part of wolfBoot (GPL-2.0-or-later).
|
||||
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
HEADER_MARKER_OFFSET = 0x24
|
||||
BOOT_BLOCK_OFFSET = 0x160
|
||||
VECTOR_CHECKSUM_OFFSET = 0x1C
|
||||
IMAGE_BASE_ADDR = 0x10000000 # SPIFI XIP base
|
||||
|
||||
HEADER_MARKER_FMT = "<2I" # 0xEDDC94BD, 0x160
|
||||
BOOT_BLOCK_FMT = "<25I"
|
||||
VECTOR_TABLE_FMT = "<7I" # first 7 words covered by checksum
|
||||
|
||||
|
||||
def patch(path):
|
||||
size = os.path.getsize(path)
|
||||
header_marker_size = struct.calcsize(HEADER_MARKER_FMT)
|
||||
boot_block_size = struct.calcsize(BOOT_BLOCK_FMT)
|
||||
vector_table_size = struct.calcsize(VECTOR_TABLE_FMT)
|
||||
|
||||
min_size = max(
|
||||
vector_table_size,
|
||||
HEADER_MARKER_OFFSET + header_marker_size,
|
||||
BOOT_BLOCK_OFFSET + boot_block_size,
|
||||
)
|
||||
if size < min_size:
|
||||
raise SystemExit(
|
||||
"error: %s is too small for LPC54S0xx boot block patching "
|
||||
"(size=%d, need at least %d bytes)" % (path, size, min_size)
|
||||
)
|
||||
|
||||
with open(path, "r+b") as f:
|
||||
f.seek(HEADER_MARKER_OFFSET)
|
||||
f.write(struct.pack(HEADER_MARKER_FMT, 0xEDDC94BD, BOOT_BLOCK_OFFSET))
|
||||
|
||||
f.seek(BOOT_BLOCK_OFFSET)
|
||||
f.write(struct.pack(
|
||||
BOOT_BLOCK_FMT,
|
||||
0xFEEDA5A5, # magic
|
||||
3, # image type
|
||||
IMAGE_BASE_ADDR, # image base
|
||||
size - 4, # image size (minus CRC slot)
|
||||
0, 0, 0, 0, 0,
|
||||
0xEDDC94BD, # header marker echo
|
||||
0, 0, 0,
|
||||
0x001640EF, # SPIFI config
|
||||
0, 0,
|
||||
0x1301001D, # clock/flash timing word
|
||||
0, 0, 0,
|
||||
0x00000100, # options
|
||||
0, 0,
|
||||
0x04030050, # PLL config
|
||||
0x14110D09, # clock divider config
|
||||
))
|
||||
|
||||
f.seek(0)
|
||||
words = struct.unpack(VECTOR_TABLE_FMT, f.read(vector_table_size))
|
||||
checksum = (0x100000000 - (sum(words) & 0xFFFFFFFF)) & 0xFFFFFFFF
|
||||
f.seek(VECTOR_CHECKSUM_OFFSET)
|
||||
f.write(struct.pack("<I", checksum))
|
||||
|
||||
print("\tvector checksum: 0x%08X" % checksum)
|
||||
|
||||
|
||||
def main(argv):
|
||||
if len(argv) != 2:
|
||||
raise SystemExit("usage: %s <wolfboot.bin>" % argv[0])
|
||||
patch(argv[1])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
# Configuration (can be overridden via environment variables)
|
||||
CONFIG_FILE="${CONFIG_FILE:-config/examples/nxp_lpc54s0xx.config}"
|
||||
|
|
@ -110,10 +111,15 @@ parse_config() {
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Helper function to extract config value
|
||||
# Helper function to extract config value.
|
||||
# Anchor the regex to `KEY=` or `KEY?=` so e.g. SIGN does not match SIGN_ALG.
|
||||
# grep with --max-count=1 keeps the pipeline single-stage so pipefail catches
|
||||
# a truly missing key (exit 1) rather than relying on `head` to mask it.
|
||||
get_config_value() {
|
||||
local key="$1"
|
||||
grep -E "^${key}" "$config_file" | head -1 | sed -E "s/^${key}\??=//" | tr -d '[:space:]'
|
||||
local line
|
||||
line=$(grep -E "^${key}\\??=" "$config_file" --max-count=1) || return 0
|
||||
printf '%s' "${line#*=}" | tr -d '[:space:]'
|
||||
}
|
||||
|
||||
# Extract SIGN and HASH
|
||||
|
|
@ -146,9 +152,9 @@ parse_config() {
|
|||
|
||||
# Ensure partition addresses have 0x prefix for bash arithmetic
|
||||
for var in WOLFBOOT_PARTITION_BOOT_ADDRESS WOLFBOOT_PARTITION_UPDATE_ADDRESS WOLFBOOT_PARTITION_SIZE WOLFBOOT_SECTOR_SIZE; do
|
||||
eval "val=\$$var"
|
||||
local val="${!var}"
|
||||
if [[ ! "$val" =~ ^0x ]]; then
|
||||
eval "$var=\"0x\${val}\""
|
||||
printf -v "$var" '0x%s' "$val"
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue