board: spacemit-k3: BROM loadable SPL build

bootinfo.bin generation is added but not implemented
This commit is contained in:
2026-05-10 03:50:13 +08:00
parent 6cab30ddfb
commit c5afbce6f0
6 changed files with 263 additions and 0 deletions
+26
View File
@@ -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";
};
};
};
};
};
+2
View File
@@ -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, "", "", },
};
+2
View File
@@ -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 */
};
+3
View File
@@ -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 \
+101
View File
@@ -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 */
);
+129
View File
@@ -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 */
);