board: spacemit-k3: BROM loadable SPL build
bootinfo.bin generation is added but not implemented
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
&binman {
|
||||
bootinfo_nor {
|
||||
filename = "bootinfo_nor.bin";
|
||||
|
||||
mkimage {
|
||||
args = "-s -T spacemit-binfo";
|
||||
};
|
||||
};
|
||||
|
||||
spl {
|
||||
filename = "spacemit-spl-unsigned.bin";
|
||||
|
||||
mkimage {
|
||||
args = "-T spacemit-spl";
|
||||
offset = <0xFE0>;
|
||||
|
||||
section {
|
||||
// Use a section to pad SPL at 32B align-size, before passing to mkimage
|
||||
blob {
|
||||
align-size = <32>;
|
||||
filename = "spl/u-boot-spl.bin";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -185,6 +185,8 @@ static const table_entry_t uimage_type[] = {
|
||||
{ IH_TYPE_STARFIVE_SPL, "sfspl", "StarFive SPL Image" },
|
||||
{ IH_TYPE_TFA_BL31, "tfa-bl31", "TFA BL31 Image", },
|
||||
{ IH_TYPE_STM32IMAGE_V2, "stm32imagev2", "STMicroelectronics STM32 Image V2.0" },
|
||||
{ IH_TYPE_SPACEMIT_BOOTINFO, "spacemit-binfo", "SpacemiT BootInfo Binary Header" },
|
||||
{ IH_TYPE_SPACEMIT_SPL, "spacemit-spl", "SpacemiT BootROM loadable Image" },
|
||||
{ -1, "", "", },
|
||||
};
|
||||
|
||||
|
||||
@@ -234,6 +234,8 @@ enum image_type_t {
|
||||
IH_TYPE_STARFIVE_SPL, /* StarFive SPL image */
|
||||
IH_TYPE_TFA_BL31, /* TFA BL31 image */
|
||||
IH_TYPE_STM32IMAGE_V2, /* STMicroelectronics STM32 Image V2.0 */
|
||||
IH_TYPE_SPACEMIT_BOOTINFO, /* SpacemiT BootInfo Binary Header */
|
||||
IH_TYPE_SPACEMIT_SPL, /* SpacemiT BootROM loadable Image */
|
||||
|
||||
IH_TYPE_COUNT, /* Number of image types */
|
||||
};
|
||||
|
||||
@@ -108,6 +108,8 @@ KWB_IMAGE_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := kwbimage.o
|
||||
|
||||
ROCKCHIP_OBS = generated/lib/rc4.o rkcommon.o rkimage.o rksd.o rkspi.o
|
||||
|
||||
SPACEMIT_OBJS = spacemit-boot.o spacemit-spl.o
|
||||
|
||||
# common objs for dumpimage and mkimage
|
||||
dumpimage-mkimage-objs := aisimage.o \
|
||||
atmelimage.o \
|
||||
@@ -140,6 +142,7 @@ dumpimage-mkimage-objs := aisimage.o \
|
||||
stm32image.o \
|
||||
$(ROCKCHIP_OBS) \
|
||||
socfpgaimage.o \
|
||||
$(SPACEMIT_OBJS) \
|
||||
sunxi_egon.o \
|
||||
generated/lib/crc16-ccitt.o \
|
||||
generated/lib/hash-checksum.o \
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
|
||||
#include "imagetool.h"
|
||||
|
||||
struct bootinfo_hdr {
|
||||
struct {
|
||||
/** @magic: MAGIC value, always 0xB00714F0 */
|
||||
uint32_t magic;
|
||||
/** @version: ???*/
|
||||
uint32_t version;
|
||||
/** @flash_type: oneof "NORF", "BLCK" */
|
||||
uint32_t flash_type;
|
||||
/** @mid: ???*/
|
||||
uint8_t mid;
|
||||
uint8_t _reserved_0[1];
|
||||
/** @did: ???*/
|
||||
uint16_t did;
|
||||
/** @page_size: ???*/
|
||||
uint32_t page_size;
|
||||
/** @block_size: ???*/
|
||||
uint32_t block_size;
|
||||
/** @total_size: ???*/
|
||||
uint32_t total_size;
|
||||
/** @multi_plane: ???*/
|
||||
uint8_t multi_plane;
|
||||
uint8_t _reserved_1[3];
|
||||
/** @spl0_offset: Offset to primary SPL image */
|
||||
uint32_t spl0_offset;
|
||||
/** @spl1_offset: Offset to backup SPL image */
|
||||
uint32_t spl1_offset;
|
||||
/** @spl_size_limit: Max size of SPL image */
|
||||
uint32_t spl_size_limit;
|
||||
/** @partitiontable0_offset: ??? */
|
||||
uint32_t partitiontable0_offset;
|
||||
/** @partitiontable1_offset: ??? */
|
||||
uint32_t partitiontable1_offset;
|
||||
uint8_t _reserved_2[12];
|
||||
} data;
|
||||
struct {
|
||||
/** @crc32: crc32 of data */
|
||||
uint32_t crc32;
|
||||
uint8_t _reserved_0[12];
|
||||
} checksum;
|
||||
};
|
||||
|
||||
static int spacemit_bootinfo_check_params(struct image_tool_params *params)
|
||||
{
|
||||
/* Only the RISC-V architecture is supported */
|
||||
if (params->Aflag && params->arch != IH_ARCH_RISCV)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int spacemit_bootinfo_verify_header(unsigned char *buf, int size,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
printf("spacemit_bootinfo_verify_header\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void spacemit_bootinfo_print_header(const void *buf,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
printf("spacemit_bootinfo_print_header\n");
|
||||
}
|
||||
|
||||
static void spacemit_bootinfo_set_header(void *buf, struct stat *sbuf, int infd,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
printf("spacemit_bootinfo_set_header\n");
|
||||
}
|
||||
|
||||
static int spacemit_bootinfo_check_image_type(uint8_t type)
|
||||
{
|
||||
if (type == IH_TYPE_SPACEMIT_BOOTINFO)
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static struct bootinfo_hdr spacemit_bootinfo_hdr;
|
||||
|
||||
U_BOOT_IMAGE_TYPE(
|
||||
spacemit_bootinfo, /* id */
|
||||
"SpacemiT BootInfo Header", /* name */
|
||||
sizeof(struct bootinfo_hdr), /* header_size */
|
||||
&spacemit_bootinfo_hdr, /* header */
|
||||
spacemit_bootinfo_check_params, /* check_params */
|
||||
spacemit_bootinfo_verify_header, /* verify header */
|
||||
spacemit_bootinfo_print_header, /* print header */
|
||||
spacemit_bootinfo_set_header, /* set header */
|
||||
NULL, /* extract_subimage */
|
||||
spacemit_bootinfo_check_image_type, /* check_image_type */
|
||||
NULL, /* fflag_handle */
|
||||
NULL /* vrec_header */
|
||||
);
|
||||
@@ -0,0 +1,129 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
|
||||
#include "imagetool.h"
|
||||
#include <u-boot/crc.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
#define SPACEMIT_SPL_HDR_MAGIC_LE32 0x44484941
|
||||
|
||||
struct spl_hdr {
|
||||
struct {
|
||||
/** @magic: MAGIC value, always 0x44484941 */
|
||||
uint32_t magic;
|
||||
/** @version: ??? */
|
||||
uint8_t version;
|
||||
/** @secure: ??? */
|
||||
uint8_t secure;
|
||||
uint8_t _reserved_0[2];
|
||||
/** @payload_size: Size of payload only */
|
||||
uint64_t payload_size;
|
||||
/** @loadaddr: Target load address */
|
||||
uint64_t loadaddr;
|
||||
} header;
|
||||
struct {
|
||||
/** @header: crc32 of header data */
|
||||
uint32_t header;
|
||||
/** @payload: crc32 of payload image */
|
||||
uint32_t payload;
|
||||
} checksum;
|
||||
// Useful for mmap-ed output file
|
||||
uint8_t payload[0];
|
||||
};
|
||||
|
||||
static int spacemit_spl_check_params(struct image_tool_params *params)
|
||||
{
|
||||
/* Only the RISC-V architecture is supported */
|
||||
if (params->Aflag && params->arch != IH_ARCH_RISCV)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int spacemit_spl_verify_header(unsigned char *buf, int size,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
const struct spl_hdr *hdr = (void *)buf;
|
||||
if (le32_to_cpu(hdr->header.magic) != SPACEMIT_SPL_HDR_MAGIC_LE32) {
|
||||
printf("Unmatched header MAGIC value: %08x\n", le32_to_cpu(hdr->header.magic));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (le32_to_cpu(hdr->checksum.header) != crc32(0, (void *)&hdr->header, sizeof(hdr->header))) {
|
||||
printf("Unmatched header checksum\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (le32_to_cpu(hdr->header.payload_size) + sizeof(struct spl_hdr) > params->file_size) {
|
||||
printf("Payload size (%lu) exceeds file size (%u) - header size (%lu)\n",
|
||||
le32_to_cpu(hdr->header.payload_size), params->file_size, sizeof(struct spl_hdr));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (le32_to_cpu(hdr->checksum.payload) != crc32(0, (void *)&hdr->payload, le32_to_cpu(hdr->header.payload_size))) {
|
||||
printf("Unmatched payload checksum\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void spacemit_spl_print_header(const void *buf,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
const struct spl_hdr *hdr = buf;
|
||||
printf("SpacemiT BootROM Loadable Image\n");
|
||||
printf("-> Header Version: 0x%02x\n", hdr->header.version);
|
||||
printf("-> Secure Mode: ");
|
||||
if (hdr->header.secure == 0) {
|
||||
printf("Disabled\n");
|
||||
} else {
|
||||
printf("Enabled (0x%02x)\n", hdr->header.secure);
|
||||
}
|
||||
printf("-> Payload Size: %lu\n", le64_to_cpu(hdr->header.payload_size));
|
||||
printf("-> Payload Load Addr: %lu\n", le64_to_cpu(hdr->header.loadaddr));
|
||||
}
|
||||
|
||||
static void spacemit_spl_set_header(void *buf, struct stat *sbuf, int infd,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
// Filling header info
|
||||
struct spl_hdr *hdr = buf;
|
||||
memset((void *)hdr, 0, sizeof(struct spl_hdr));
|
||||
hdr->header.magic = cpu_to_le32(SPACEMIT_SPL_HDR_MAGIC_LE32);
|
||||
hdr->header.version = 0x01;
|
||||
hdr->header.secure = 0;
|
||||
hdr->header.payload_size = cpu_to_le64(params->file_size - sizeof(struct spl_hdr));
|
||||
hdr->header.loadaddr = cpu_to_le64(0x0);
|
||||
hdr->checksum.header = cpu_to_le32(crc32(0, (void *)&hdr->header, sizeof(hdr->header)));
|
||||
hdr->checksum.payload = cpu_to_le32(crc32(0, (void *)hdr->payload, le64_to_cpu(hdr->header.payload_size)));
|
||||
|
||||
// Payload is already copied by mkimage
|
||||
|
||||
// Generate signature
|
||||
// Here we directly call into OpenSSL to avoid U-Boot overheads
|
||||
}
|
||||
|
||||
static int spacemit_spl_check_image_type(uint8_t type)
|
||||
{
|
||||
if (type == IH_TYPE_SPACEMIT_SPL)
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static struct spl_hdr spacemit_spl_hdr;
|
||||
|
||||
U_BOOT_IMAGE_TYPE(
|
||||
spacemit_spl, /* id */
|
||||
"SpacemiT BROM loadable Image", /* name */
|
||||
sizeof(struct spl_hdr), /* header_size */
|
||||
&spacemit_spl_hdr, /* header */
|
||||
spacemit_spl_check_params, /* check_params */
|
||||
spacemit_spl_verify_header, /* verify header */
|
||||
spacemit_spl_print_header, /* print header */
|
||||
spacemit_spl_set_header, /* set header */
|
||||
NULL, /* extract_subimage */
|
||||
spacemit_spl_check_image_type, /* check_image_type */
|
||||
NULL, /* fflag_handle */
|
||||
NULL /* vrec_header */
|
||||
);
|
||||
Reference in New Issue
Block a user