mirror of https://github.com/wolfSSL/wolfBoot.git
tools: Add bin-assemble for pasting together binary blobs
parent
1a33885cfb
commit
36c50a7e4a
10
Makefile
10
Makefile
|
@ -94,14 +94,10 @@ test-app/image_v1_signed.bin: test-app/image.bin
|
|||
@echo "\t[SIGN] $(BOOT_IMG)"
|
||||
$(Q)$(SIGN_TOOL) $(SIGN_OPTIONS) $(BOOT_IMG) $(PRIVATE_KEY) 1
|
||||
|
||||
factory.bin: $(BOOT_IMG) wolfboot-align.bin $(PRIVATE_KEY) test-app/image_v1_signed.bin
|
||||
factory.bin: $(BOOT_IMG) wolfboot-align.bin $(PRIVATE_KEY) test-app/image_v1_signed.bin $(BINASSEMBLE)
|
||||
@echo "\t[MERGE] $@"
|
||||
$(Q)$(OBJCOPY) --set-start=$(ARCH_OFFSET) \
|
||||
--add-section .signed_image=test-app/image_v1_signed.bin \
|
||||
--change-section-vma .signed_image=$(WOLFBOOT_PARTITION_BOOT_ADDRESS) \
|
||||
--set-section-flags .signed_image=alloc,readonly \
|
||||
wolfboot.elf factory.elf
|
||||
$(Q)$(OBJCOPY) --gap-fill=255 -O binary factory.elf $@
|
||||
$(Q)$(BINASSEMBLE) $@ $(ARCH_FLASH_OFFSET) wolfboot-align.bin \
|
||||
$(WOLFBOOT_PARTITION_BOOT_ADDRESS) test-app/image_v1_signed.bin
|
||||
|
||||
wolfboot.elf: include/target.h $(OBJS) $(LSCRIPT) FORCE
|
||||
@echo "\t[LD] $@"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
CC=gcc
|
||||
CFLAGS=-Wall -g -ggdb
|
||||
EXE=bin-assemble
|
||||
|
||||
LIBS=
|
||||
|
||||
$(EXE): $(EXE).o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f *.o $(EXE)
|
|
@ -0,0 +1,205 @@
|
|||
/* bin-assemble.c
|
||||
*
|
||||
* Copyright (C) 2006-2020 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 2 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-1301, USA
|
||||
*
|
||||
*=============================================================================
|
||||
*
|
||||
* assemble binary parts based on address
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#define BLOCK_SZ 1024
|
||||
|
||||
void usage(const char* execname)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s output [<address> <input>]\n"
|
||||
"assemble binary parts with addresses",
|
||||
execname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char* fname;
|
||||
size_t address;
|
||||
size_t nbytes;
|
||||
} binentry_t;
|
||||
|
||||
int binentry_address_compare(const void* a, const void* b)
|
||||
{
|
||||
const binentry_t* ba = (const binentry_t*)a;
|
||||
const binentry_t* bb = (const binentry_t*)b;
|
||||
|
||||
if (ba->address < bb->address) {
|
||||
return -1;
|
||||
} else if (ba->address > bb->address) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
const char* outname = NULL;
|
||||
size_t i = 0;
|
||||
size_t num_entries = 0;
|
||||
binentry_t* entries = NULL;
|
||||
size_t cur_add = 0;
|
||||
char fill = '\xff';
|
||||
size_t nr = 0;
|
||||
size_t nw = 0;
|
||||
char data[BLOCK_SZ];
|
||||
int err = 0;
|
||||
|
||||
/* require at least 1 input file */
|
||||
if (argc < 4 || (argc % 2) != 0) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
outname = argv[1];
|
||||
num_entries = (argc - 2) / 2;
|
||||
|
||||
entries = malloc( sizeof(binentry_t) * num_entries);
|
||||
if (entries == NULL) {
|
||||
fprintf(stderr, "unable to allocate %zu entries\n;", num_entries);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (i=0; i<num_entries; i++) {
|
||||
char* endptr = NULL;
|
||||
struct stat st;
|
||||
|
||||
entries[i].address = strtol(argv[2*i + 2], &endptr, 0);
|
||||
if (*endptr) {
|
||||
fprintf(stderr,
|
||||
"Remaining characters in adderss field %s\n", endptr);
|
||||
}
|
||||
entries[i].fname = argv[2*i + 3];
|
||||
|
||||
if (stat(entries[i].fname, &st)) {
|
||||
fprintf(stderr, "unable to stat %s: %s\n", entries[i].fname,
|
||||
strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
entries[i].nbytes = st.st_size;
|
||||
|
||||
#if VERBOSE
|
||||
printf("%s %zu %zu\n",
|
||||
entries[i].fname,
|
||||
entries[i].address,
|
||||
entries[i].nbytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
qsort(entries, num_entries, sizeof(binentry_t), binentry_address_compare);
|
||||
|
||||
// check for overlap
|
||||
for (i=1; i<num_entries; i++) {
|
||||
size_t endaddr = entries[i-1].address + entries[i-1].nbytes;
|
||||
if (endaddr > entries[i].address) {
|
||||
fprintf(stderr,
|
||||
"overlap with %s(end address 0x%zx) and %s (start address 0x%zx \n",
|
||||
entries[i-1].fname, endaddr,
|
||||
entries[i].fname, entries[i].address);
|
||||
err = 1;
|
||||
}
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: consider handling stdout "-"
|
||||
|
||||
FILE* fo = fopen(outname, "wb");
|
||||
if (fo == NULL){
|
||||
fprintf(stderr, "opening %s failed %s\n",
|
||||
outname, strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
cur_add = entries[0].address;
|
||||
for (i=0; i<num_entries; i++) {
|
||||
FILE* fi = fopen(entries[i].fname, "rb");
|
||||
if (fi == NULL){
|
||||
fprintf(stderr, "opening %s failed %s\n",
|
||||
entries[i].fname, strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* fill until address */
|
||||
while(cur_add < entries[i].address) {
|
||||
nw = fwrite(&fill, 1, 1, fo);
|
||||
if (nw != 1) {
|
||||
fprintf(stderr,
|
||||
"Failed to write fill bytes at 0x%zu\n",
|
||||
cur_add);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
cur_add++;
|
||||
}
|
||||
|
||||
while (!feof(fi)) {
|
||||
nr = fread(data, 1, BLOCK_SZ, fi);
|
||||
nw = fwrite(data, 1, nr, fo);
|
||||
cur_add += nw;
|
||||
if (nr != nw) {
|
||||
fprintf(stderr,
|
||||
"Failed to wrote %zu bytes of the %zu bytes read from %s\n",
|
||||
nw, nr, entries[i].fname);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (ferror(fi)) {
|
||||
fprintf(stderr,
|
||||
"error reading from %s\n",
|
||||
entries[i].fname);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (ferror(fo)) {
|
||||
fprintf(stderr,
|
||||
"error writing to %s\n",
|
||||
entries[i].fname);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
fclose(fi);
|
||||
}
|
||||
|
||||
fclose(fo);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
TEST_UPDATE_VERSION?=2
|
||||
WOLFBOOT_VERSION?=0
|
||||
EXPVER=tools/test-expect-version/test-expect-version
|
||||
BINASSEMBLE=tools/bin-assemble/bin-assemble
|
||||
SPI_CHIP=SST25VF080B
|
||||
SPI_OPTIONS=SPI_FLASH=1 WOLFBOOT_PARTITION_SIZE=0x80000 WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x00000 WOLFBOOT_PARTITION_SWAP_ADDRESS=0x80000
|
||||
SIGN_ARGS=
|
||||
|
@ -49,7 +50,10 @@ ifeq ($(HASH),SHA3)
|
|||
endif
|
||||
|
||||
$(EXPVER):
|
||||
make -C tools/test-expect-version
|
||||
$(MAKE) -C $(dir $@)
|
||||
|
||||
$(BINASSEMBLE):
|
||||
$(MAKE) -C $(dir $@)
|
||||
|
||||
# Testbed actions
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue