uboot-rockchip: add SD card boot workaround for RK3576
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
(cherry picked from commit 83656be04e)
This commit is contained in:
@@ -591,6 +591,16 @@ UBOOT_MAKE_FLAGS += \
|
||||
BL31=$(STAGING_DIR_IMAGE)/$(ATF) \
|
||||
$(if $(TPL),ROCKCHIP_TPL=$(STAGING_DIR_IMAGE)/$(TPL))
|
||||
|
||||
define Build/Configure
|
||||
$(call Build/Configure/U-Boot)
|
||||
|
||||
ifneq ($(filter %rk3576,$(BUILD_VARIANT)),)
|
||||
$(TARGET_CC) -nostdlib -ffreestanding -Os -S -o $(PKG_BUILD_DIR)/rk3576-boost.S $(PKG_BUILD_DIR)/rk3576-boost.c
|
||||
$(TARGET_CROSS)as -o $(PKG_BUILD_DIR)/rk3576-boost.o $(PKG_BUILD_DIR)/rk3576-boost.S
|
||||
$(TARGET_CROSS)objcopy -O binary -j .text $(PKG_BUILD_DIR)/rk3576-boost.o $(PKG_BUILD_DIR)/rk3576-boost.bin
|
||||
endif
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
|
||||
ifneq ($(TPL),)
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
From cb682b364eb2d49c3ee2a1f7f33258919f5da688 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Wed, 29 Jan 2025 22:36:27 +0000
|
||||
Subject: [PATCH] rockchip: mkimage: Split size_and_off and size_and_nimage
|
||||
|
||||
Split 32-bit size_and_off and size_and_nimage fields of the v2 image
|
||||
format header into their own 16-bit size, offset and num_images fields.
|
||||
|
||||
Set num_images based on number of images passed by the datafile
|
||||
parameter and size based on the offset to the hash field to fix using a
|
||||
single init data file and no boot data file for the v2 image format.
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
tools/rkcommon.c | 44 ++++++++++++++++++++++++--------------------
|
||||
1 file changed, 24 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/tools/rkcommon.c
|
||||
+++ b/tools/rkcommon.c
|
||||
@@ -34,15 +34,16 @@ enum hash_type {
|
||||
/**
|
||||
* struct image_entry
|
||||
*
|
||||
- * @size_and_off: [31:16]image size;[15:0]image offset
|
||||
- * @address: default as 0xFFFFFFFF
|
||||
+ * @offset: image offset (unit as 512 byte blocks)
|
||||
+ * @size: image size (unit as 512 byte blocks)
|
||||
+ * @address: load address (default as 0xFFFFFFFF)
|
||||
* @flag: no use
|
||||
* @counter: no use
|
||||
* @hash: hash of image
|
||||
- *
|
||||
*/
|
||||
struct image_entry {
|
||||
- uint32_t size_and_off;
|
||||
+ uint16_t offset;
|
||||
+ uint16_t size;
|
||||
uint32_t address;
|
||||
uint32_t flag;
|
||||
uint32_t counter;
|
||||
@@ -56,16 +57,17 @@ struct image_entry {
|
||||
* This is stored at SD card block 64 (where each block is 512 bytes)
|
||||
*
|
||||
* @magic: Magic (must be RK_MAGIC_V2)
|
||||
- * @size_and_nimage: [31:16]number of images;[15:0]
|
||||
- * offset to hash field of header(unit as 4Byte)
|
||||
- * @boot_flag: [3:0]hash type(0:none,1:sha256,2:sha512)
|
||||
- * @signature: hash or signature for header info
|
||||
- *
|
||||
+ * @size: offset to hash field of header (unit as 4 bytes)
|
||||
+ * @num_images: number of images
|
||||
+ * @boot_flag: [3:0] hash type (0:none, 1:sha256, 2:sha512)
|
||||
+ * @images: images
|
||||
+ * @hash: hash or signature for header info
|
||||
*/
|
||||
struct header0_info_v2 {
|
||||
uint32_t magic;
|
||||
uint8_t reserved[4];
|
||||
- uint32_t size_and_nimage;
|
||||
+ uint16_t size;
|
||||
+ uint16_t num_images;
|
||||
uint32_t boot_flag;
|
||||
uint8_t reserved1[104];
|
||||
struct image_entry images[4];
|
||||
@@ -334,17 +336,18 @@ static void rkcommon_set_header0_v2(void
|
||||
printf("Image Type: Rockchip %s boot image\n",
|
||||
rkcommon_get_spl_hdr(params));
|
||||
memset(buf, '\0', RK_INIT_OFFSET * RK_BLK_SIZE);
|
||||
- hdr->magic = cpu_to_le32(RK_MAGIC_V2);
|
||||
- hdr->size_and_nimage = cpu_to_le32((2 << 16) + 384);
|
||||
+ hdr->magic = cpu_to_le32(RK_MAGIC_V2);
|
||||
hdr->boot_flag = cpu_to_le32(HASH_SHA256);
|
||||
sector_offset = 4;
|
||||
image_size_array[0] = spl_params.init_size;
|
||||
image_size_array[1] = spl_params.boot_size;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
+ if (!image_size_array[i])
|
||||
+ break;
|
||||
image_sector_count = image_size_array[i] / RK_BLK_SIZE;
|
||||
- hdr->images[i].size_and_off = cpu_to_le32((image_sector_count
|
||||
- << 16) + sector_offset);
|
||||
+ hdr->images[i].offset = cpu_to_le16(sector_offset);
|
||||
+ hdr->images[i].size = cpu_to_le16(image_sector_count);
|
||||
hdr->images[i].address = 0xFFFFFFFF;
|
||||
hdr->images[i].counter = cpu_to_le32(i + 1);
|
||||
image_ptr = buf + sector_offset * RK_BLK_SIZE;
|
||||
@@ -353,6 +356,8 @@ static void rkcommon_set_header0_v2(void
|
||||
sector_offset = sector_offset + image_sector_count;
|
||||
}
|
||||
|
||||
+ hdr->num_images = cpu_to_le16(i);
|
||||
+ hdr->size = cpu_to_le16(offsetof(typeof(*hdr), hash) / sizeof(uint32_t));
|
||||
do_sha256_hash(buf, (void *)hdr->hash - buf, hdr->hash);
|
||||
}
|
||||
|
||||
@@ -499,10 +504,8 @@ void rkcommon_print_header(const void *b
|
||||
return;
|
||||
}
|
||||
|
||||
- init_size = header0_v2.images[0].size_and_off >> 16;
|
||||
- init_size = init_size * RK_BLK_SIZE;
|
||||
- boot_size = header0_v2.images[1].size_and_off >> 16;
|
||||
- boot_size = boot_size * RK_BLK_SIZE;
|
||||
+ init_size = le16_to_cpu(header0_v2.images[0].size) * RK_BLK_SIZE;
|
||||
+ boot_size = le16_to_cpu(header0_v2.images[1].size) * RK_BLK_SIZE;
|
||||
} else {
|
||||
ret = rkcommon_parse_header(buf, &header0, &spl_info);
|
||||
|
||||
@@ -516,8 +519,9 @@ void rkcommon_print_header(const void *b
|
||||
}
|
||||
|
||||
image_type = ret;
|
||||
- init_size = header0.init_size * RK_BLK_SIZE;
|
||||
- boot_size = header0.init_boot_size * RK_BLK_SIZE - init_size;
|
||||
+ init_size = le16_to_cpu(header0.init_size) * RK_BLK_SIZE;
|
||||
+ boot_size = le16_to_cpu(header0.init_boot_size) * RK_BLK_SIZE -
|
||||
+ init_size;
|
||||
|
||||
printf("Image Type: Rockchip %s (%s) boot image\n",
|
||||
spl_info->spl_hdr,
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
From 0085f8509d62591560901c11fa9d63e34da4fa62 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Wed, 29 Jan 2025 22:36:28 +0000
|
||||
Subject: [PATCH] rockchip: mkimage: Print image information for all embedded
|
||||
images
|
||||
|
||||
The v2 image format can embed up to 4 data files compared to the two
|
||||
init and boot data files using the older image format.
|
||||
|
||||
Add support for displaying more of the image header information that
|
||||
exists in the v2 image format, e.g. image load address and flag.
|
||||
|
||||
Example for v2 image format:
|
||||
|
||||
> tools/mkimage -l rk3576_idblock_v1.09.107.img
|
||||
Rockchip Boot Image (v2)
|
||||
Image 1: 4096 @ 0x1000
|
||||
- Load address: 0x3ffc0000
|
||||
Image 2: 77824 @ 0x2000
|
||||
- Load address: 0x3ff81000
|
||||
Image 3: 262144 @ 0x15000
|
||||
|
||||
Example for older image format:
|
||||
|
||||
> tools/mkimage -l u-boot-rockchip.bin
|
||||
Rockchip RK32 (SD/MMC) Boot Image
|
||||
Init Data: 20480 @ 0x800
|
||||
Boot Data: 112640 @ 0x5800
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
tools/rkcommon.c | 41 +++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 31 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/tools/rkcommon.c
|
||||
+++ b/tools/rkcommon.c
|
||||
@@ -333,8 +333,6 @@ static void rkcommon_set_header0_v2(void
|
||||
uint8_t *image_ptr = NULL;
|
||||
int i;
|
||||
|
||||
- printf("Image Type: Rockchip %s boot image\n",
|
||||
- rkcommon_get_spl_hdr(params));
|
||||
memset(buf, '\0', RK_INIT_OFFSET * RK_BLK_SIZE);
|
||||
hdr->magic = cpu_to_le32(RK_MAGIC_V2);
|
||||
hdr->boot_flag = cpu_to_le32(HASH_SHA256);
|
||||
@@ -488,6 +486,29 @@ int rkcommon_verify_header(unsigned char
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
+static void rkcommon_print_header_v2(const struct header0_info_v2 *hdr)
|
||||
+{
|
||||
+ uint32_t val;
|
||||
+ int i;
|
||||
+
|
||||
+ printf("Rockchip Boot Image (v2)\n");
|
||||
+
|
||||
+ for (i = 0; i < le16_to_cpu(hdr->num_images); i++) {
|
||||
+ printf("Image %u: %u @ 0x%x\n",
|
||||
+ le32_to_cpu(hdr->images[i].counter),
|
||||
+ le16_to_cpu(hdr->images[i].size) * RK_BLK_SIZE,
|
||||
+ le16_to_cpu(hdr->images[i].offset) * RK_BLK_SIZE);
|
||||
+
|
||||
+ val = le32_to_cpu(hdr->images[i].address);
|
||||
+ if (val != 0xFFFFFFFF)
|
||||
+ printf("- Load address: 0x%x\n", val);
|
||||
+
|
||||
+ val = le32_to_cpu(hdr->images[i].flag);
|
||||
+ if (val)
|
||||
+ printf("- Flag: 0x%x\n", val);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void rkcommon_print_header(const void *buf, struct image_tool_params *params)
|
||||
{
|
||||
struct header0_info header0;
|
||||
@@ -504,8 +525,7 @@ void rkcommon_print_header(const void *b
|
||||
return;
|
||||
}
|
||||
|
||||
- init_size = le16_to_cpu(header0_v2.images[0].size) * RK_BLK_SIZE;
|
||||
- boot_size = le16_to_cpu(header0_v2.images[1].size) * RK_BLK_SIZE;
|
||||
+ rkcommon_print_header_v2(&header0_v2);
|
||||
} else {
|
||||
ret = rkcommon_parse_header(buf, &header0, &spl_info);
|
||||
|
||||
@@ -523,15 +543,16 @@ void rkcommon_print_header(const void *b
|
||||
boot_size = le16_to_cpu(header0.init_boot_size) * RK_BLK_SIZE -
|
||||
init_size;
|
||||
|
||||
- printf("Image Type: Rockchip %s (%s) boot image\n",
|
||||
- spl_info->spl_hdr,
|
||||
+ printf("Rockchip %s (%s) Boot Image\n", spl_info->spl_hdr,
|
||||
(image_type == IH_TYPE_RKSD) ? "SD/MMC" : "SPI");
|
||||
- }
|
||||
|
||||
- printf("Init Data Size: %d bytes\n", init_size);
|
||||
+ printf("Init Data: %d @ 0x%x\n", init_size,
|
||||
+ le16_to_cpu(header0.init_offset) * RK_BLK_SIZE);
|
||||
|
||||
- if (boot_size != RK_MAX_BOOT_SIZE)
|
||||
- printf("Boot Data Size: %d bytes\n", boot_size);
|
||||
+ if (boot_size != RK_MAX_BOOT_SIZE)
|
||||
+ printf("Boot Data: %d @ 0x%x\n", boot_size, init_size +
|
||||
+ le16_to_cpu(header0.init_offset) * RK_BLK_SIZE);
|
||||
+ }
|
||||
}
|
||||
|
||||
void rkcommon_rc4_encode_spl(void *buf, unsigned int offset, unsigned int size)
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
From 83326e18d15be1ac9b7daf7b472d0bcb8074da2b Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Wed, 29 Jan 2025 22:36:29 +0000
|
||||
Subject: [PATCH] rockchip: mkimage: Print boot0 and boot1 parameters
|
||||
|
||||
The v2 image format embeds boot0 and boot1 parameters, the vendor tool
|
||||
boot_merger may write these parameters based on the rkboot miniall.ini
|
||||
files.
|
||||
|
||||
E.g. a RK3576 boot image may contain a boot1 parameter that signals
|
||||
BootROM or vendor blobs to use 1 GHz instead of the regular 24 MHz rate
|
||||
for the high precision timer.
|
||||
|
||||
Add support for printing boot0 and boot1 parameters, e.g.:
|
||||
|
||||
> tools/mkimage -l rk3576_idblock_v1.09.107.img
|
||||
Rockchip Boot Image (v2)
|
||||
Boot1 2: 0x100
|
||||
Image 1: 4096 @ 0x1000
|
||||
- Load address: 0x3ffc0000
|
||||
Image 2: 77824 @ 0x2000
|
||||
- Load address: 0x3ff81000
|
||||
Image 3: 262144 @ 0x15000
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
tools/rkcommon.c | 18 +++++++++++++++++-
|
||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/tools/rkcommon.c
|
||||
+++ b/tools/rkcommon.c
|
||||
@@ -62,6 +62,8 @@ struct image_entry {
|
||||
* @boot_flag: [3:0] hash type (0:none, 1:sha256, 2:sha512)
|
||||
* @images: images
|
||||
* @hash: hash or signature for header info
|
||||
+ *
|
||||
+ * Other fields are not used by U-Boot
|
||||
*/
|
||||
struct header0_info_v2 {
|
||||
uint32_t magic;
|
||||
@@ -69,7 +71,9 @@ struct header0_info_v2 {
|
||||
uint16_t size;
|
||||
uint16_t num_images;
|
||||
uint32_t boot_flag;
|
||||
- uint8_t reserved1[104];
|
||||
+ uint8_t reserved1[32];
|
||||
+ uint32_t boot0_param[10];
|
||||
+ uint32_t boot1_param[8];
|
||||
struct image_entry images[4];
|
||||
uint8_t reserved2[1064];
|
||||
uint8_t hash[512];
|
||||
@@ -493,6 +497,18 @@ static void rkcommon_print_header_v2(con
|
||||
|
||||
printf("Rockchip Boot Image (v2)\n");
|
||||
|
||||
+ for (i = 0; i < ARRAY_SIZE(hdr->boot0_param); i++) {
|
||||
+ val = le32_to_cpu(hdr->boot0_param[i]);
|
||||
+ if (val)
|
||||
+ printf("Boot0 %d: 0x%x\n", i, val);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(hdr->boot1_param); i++) {
|
||||
+ val = le32_to_cpu(hdr->boot1_param[i]);
|
||||
+ if (val)
|
||||
+ printf("Boot1 %d: 0x%x\n", i, val);
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < le16_to_cpu(hdr->num_images); i++) {
|
||||
printf("Image %u: %u @ 0x%x\n",
|
||||
le32_to_cpu(hdr->images[i].counter),
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
From a9a5d21d926594a87e8db877d4b9261200c3f8fd Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Wed, 29 Jan 2025 22:36:30 +0000
|
||||
Subject: [PATCH] rockchip: mkimage: Add option to change image offset
|
||||
alignment
|
||||
|
||||
The vendor boot_merger tool support a ALIGN parameter that is used to
|
||||
define offset alignment of the embedded images.
|
||||
|
||||
Vendor use this for RK3576 to change offset alignment from the common
|
||||
2 KiB to 4 KiB, presumably it may have something to do with UFS.
|
||||
Testing with eMMC has shown that using a 512-byte alignment also work.
|
||||
|
||||
Add support for overriding offset alignment in case this is needed for
|
||||
e.g. RK3576 in the future.
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
tools/rkcommon.c | 75 +++++++++++++++++++++++++++++++-----------------
|
||||
tools/rkcommon.h | 2 --
|
||||
2 files changed, 49 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/tools/rkcommon.c
|
||||
+++ b/tools/rkcommon.c
|
||||
@@ -124,6 +124,7 @@ struct spl_info {
|
||||
const uint32_t spl_size;
|
||||
const bool spl_rc4;
|
||||
const uint32_t header_ver;
|
||||
+ const uint32_t align;
|
||||
};
|
||||
|
||||
static struct spl_info spl_infos[] = {
|
||||
@@ -183,14 +184,19 @@ static struct spl_info *rkcommon_get_spl
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static int rkcommon_get_aligned_size(struct image_tool_params *params,
|
||||
- const char *fname)
|
||||
+bool rkcommon_is_header_v2(struct image_tool_params *params)
|
||||
{
|
||||
- int size;
|
||||
+ struct spl_info *info = rkcommon_get_spl_info(params->imagename);
|
||||
|
||||
- size = imagetool_get_filesize(params, fname);
|
||||
- if (size < 0)
|
||||
- return -1;
|
||||
+ return (info->header_ver == RK_HEADER_V2);
|
||||
+}
|
||||
+
|
||||
+static int rkcommon_get_aligned_size(struct image_tool_params *params, int size)
|
||||
+{
|
||||
+ struct spl_info *info = rkcommon_get_spl_info(params->imagename);
|
||||
+
|
||||
+ if (info->align)
|
||||
+ return ROUND(size, info->align * RK_BLK_SIZE);
|
||||
|
||||
/*
|
||||
* Pad to a 2KB alignment, as required for init/boot size by the ROM
|
||||
@@ -199,6 +205,27 @@ static int rkcommon_get_aligned_size(str
|
||||
return ROUND(size, RK_SIZE_ALIGN);
|
||||
}
|
||||
|
||||
+static int rkcommon_get_header_size(struct image_tool_params *params)
|
||||
+{
|
||||
+ int header_size = rkcommon_is_header_v2(params) ?
|
||||
+ sizeof(struct header0_info_v2) :
|
||||
+ sizeof(struct header0_info);
|
||||
+
|
||||
+ return rkcommon_get_aligned_size(params, header_size);
|
||||
+}
|
||||
+
|
||||
+static int rkcommon_get_aligned_filesize(struct image_tool_params *params,
|
||||
+ const char *fname)
|
||||
+{
|
||||
+ int size;
|
||||
+
|
||||
+ size = imagetool_get_filesize(params, fname);
|
||||
+ if (size < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ return rkcommon_get_aligned_size(params, size);
|
||||
+}
|
||||
+
|
||||
int rkcommon_check_params(struct image_tool_params *params)
|
||||
{
|
||||
int i, size;
|
||||
@@ -221,14 +248,14 @@ int rkcommon_check_params(struct image_t
|
||||
spl_params.boot_file += 1;
|
||||
}
|
||||
|
||||
- size = rkcommon_get_aligned_size(params, spl_params.init_file);
|
||||
+ size = rkcommon_get_aligned_filesize(params, spl_params.init_file);
|
||||
if (size < 0)
|
||||
return EXIT_FAILURE;
|
||||
spl_params.init_size = size;
|
||||
|
||||
/* Boot file is optional, and only for back-to-bootrom functionality. */
|
||||
if (spl_params.boot_file) {
|
||||
- size = rkcommon_get_aligned_size(params, spl_params.boot_file);
|
||||
+ size = rkcommon_get_aligned_filesize(params, spl_params.boot_file);
|
||||
if (size < 0)
|
||||
return EXIT_FAILURE;
|
||||
spl_params.boot_size = size;
|
||||
@@ -285,13 +312,6 @@ bool rkcommon_need_rc4_spl(struct image_
|
||||
return info->spl_rc4;
|
||||
}
|
||||
|
||||
-bool rkcommon_is_header_v2(struct image_tool_params *params)
|
||||
-{
|
||||
- struct spl_info *info = rkcommon_get_spl_info(params->imagename);
|
||||
-
|
||||
- return (info->header_ver == RK_HEADER_V2);
|
||||
-}
|
||||
-
|
||||
static void do_sha256_hash(uint8_t *buf, uint32_t size, uint8_t *out)
|
||||
{
|
||||
sha256_context ctx;
|
||||
@@ -304,12 +324,13 @@ static void do_sha256_hash(uint8_t *buf,
|
||||
static void rkcommon_set_header0(void *buf, struct image_tool_params *params)
|
||||
{
|
||||
struct header0_info *hdr = buf;
|
||||
- uint32_t init_boot_size;
|
||||
+ uint32_t init_boot_size, init_offset;
|
||||
|
||||
- memset(buf, '\0', RK_INIT_OFFSET * RK_BLK_SIZE);
|
||||
+ init_offset = rkcommon_get_header_size(params) / RK_BLK_SIZE;
|
||||
+ memset(buf, '\0', init_offset * RK_BLK_SIZE);
|
||||
hdr->magic = cpu_to_le32(RK_MAGIC);
|
||||
hdr->disable_rc4 = cpu_to_le32(!rkcommon_need_rc4_spl(params));
|
||||
- hdr->init_offset = cpu_to_le16(RK_INIT_OFFSET);
|
||||
+ hdr->init_offset = cpu_to_le16(init_offset);
|
||||
hdr->init_size = cpu_to_le16(spl_params.init_size / RK_BLK_SIZE);
|
||||
|
||||
/*
|
||||
@@ -337,10 +358,10 @@ static void rkcommon_set_header0_v2(void
|
||||
uint8_t *image_ptr = NULL;
|
||||
int i;
|
||||
|
||||
- memset(buf, '\0', RK_INIT_OFFSET * RK_BLK_SIZE);
|
||||
+ sector_offset = rkcommon_get_header_size(params) / RK_BLK_SIZE;
|
||||
+ memset(buf, '\0', sector_offset * RK_BLK_SIZE);
|
||||
hdr->magic = cpu_to_le32(RK_MAGIC_V2);
|
||||
hdr->boot_flag = cpu_to_le32(HASH_SHA256);
|
||||
- sector_offset = 4;
|
||||
image_size_array[0] = spl_params.init_size;
|
||||
image_size_array[1] = spl_params.boot_size;
|
||||
|
||||
@@ -366,11 +387,12 @@ static void rkcommon_set_header0_v2(void
|
||||
void rkcommon_set_header(void *buf, struct stat *sbuf, int ifd,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
- struct header1_info *hdr = buf + RK_SPL_HDR_START;
|
||||
-
|
||||
if (rkcommon_is_header_v2(params)) {
|
||||
rkcommon_set_header0_v2(buf, params);
|
||||
} else {
|
||||
+ int header_size = rkcommon_get_header_size(params);
|
||||
+ struct header1_info *hdr = buf + header_size;
|
||||
+
|
||||
rkcommon_set_header0(buf, params);
|
||||
|
||||
/* Set up the SPL name (i.e. copy spl_hdr over) */
|
||||
@@ -378,12 +400,12 @@ void rkcommon_set_header(void *buf, str
|
||||
memcpy(&hdr->magic, rkcommon_get_spl_hdr(params), RK_SPL_HDR_SIZE);
|
||||
|
||||
if (rkcommon_need_rc4_spl(params))
|
||||
- rkcommon_rc4_encode_spl(buf, RK_SPL_HDR_START,
|
||||
+ rkcommon_rc4_encode_spl(buf, header_size,
|
||||
spl_params.init_size);
|
||||
|
||||
if (spl_params.boot_file) {
|
||||
if (rkcommon_need_rc4_spl(params))
|
||||
- rkcommon_rc4_encode_spl(buf + RK_SPL_HDR_START,
|
||||
+ rkcommon_rc4_encode_spl(buf + header_size,
|
||||
spl_params.init_size,
|
||||
spl_params.boot_size);
|
||||
}
|
||||
@@ -608,7 +630,7 @@ int rkcommon_vrec_header(struct image_to
|
||||
* 4 bytes of these images can safely be overwritten using the
|
||||
* boot magic.
|
||||
*/
|
||||
- tparams->header_size = RK_SPL_HDR_START;
|
||||
+ tparams->header_size = rkcommon_get_header_size(params);
|
||||
|
||||
/* Allocate, clear and install the header */
|
||||
tparams->hdr = malloc(tparams->header_size);
|
||||
@@ -626,7 +648,8 @@ int rkcommon_vrec_header(struct image_to
|
||||
params->orig_file_size = tparams->header_size +
|
||||
spl_params.init_size + spl_params.boot_size;
|
||||
|
||||
- params->file_size = ROUND(params->orig_file_size, RK_SIZE_ALIGN);
|
||||
+ params->file_size = rkcommon_get_aligned_size(params,
|
||||
+ params->orig_file_size);
|
||||
|
||||
/* Ignoring pad len, since we are using our own copy_image() */
|
||||
return 0;
|
||||
--- a/tools/rkcommon.h
|
||||
+++ b/tools/rkcommon.h
|
||||
@@ -10,9 +10,7 @@
|
||||
enum {
|
||||
RK_BLK_SIZE = 512,
|
||||
RK_SIZE_ALIGN = 2048,
|
||||
- RK_INIT_OFFSET = 4,
|
||||
RK_MAX_BOOT_SIZE = 512 << 10,
|
||||
- RK_SPL_HDR_START = RK_INIT_OFFSET * RK_BLK_SIZE,
|
||||
RK_SPL_HDR_SIZE = 4,
|
||||
};
|
||||
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
From 31255e35146c279696c51cde45facd1ea10eed28 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Wed, 29 Jan 2025 22:36:31 +0000
|
||||
Subject: [PATCH] rockchip: mkimage: Add support for up to 4 input files
|
||||
|
||||
The v2 image format can support up to 4 embedded images that can be
|
||||
loaded by the BootROM using the back-to-bootrom method.
|
||||
|
||||
Currently two input files can be passed in using the datafile parameter,
|
||||
separated by a colon (":").
|
||||
|
||||
Extend the datafile parameter parsing to support up to 4 input files
|
||||
separated by a colon (":") for use with the v2 image format.
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
tools/rkcommon.c | 93 +++++++++++++++++++++++-------------------------
|
||||
1 file changed, 44 insertions(+), 49 deletions(-)
|
||||
|
||||
--- a/tools/rkcommon.c
|
||||
+++ b/tools/rkcommon.c
|
||||
@@ -150,17 +150,15 @@ static struct spl_info spl_infos[] = {
|
||||
/**
|
||||
* struct spl_params - spl params parsed in check_params()
|
||||
*
|
||||
- * @init_file: Init data file path
|
||||
- * @init_size: Aligned size of init data in bytes
|
||||
- * @boot_file: Boot data file path
|
||||
- * @boot_size: Aligned size of boot data in bytes
|
||||
+ * @file: image file path
|
||||
+ * @size: aligned size of image in bytes
|
||||
*/
|
||||
|
||||
struct spl_params {
|
||||
- char *init_file;
|
||||
- uint32_t init_size;
|
||||
- char *boot_file;
|
||||
- uint32_t boot_size;
|
||||
+ struct {
|
||||
+ char *file;
|
||||
+ uint32_t size;
|
||||
+ } images[4];
|
||||
};
|
||||
|
||||
static struct spl_params spl_params = { 0 };
|
||||
@@ -240,31 +238,32 @@ int rkcommon_check_params(struct image_t
|
||||
if (!rkcommon_get_spl_info(params->imagename))
|
||||
goto err_spl_info;
|
||||
|
||||
- spl_params.init_file = params->datafile;
|
||||
+ spl_params.images[0].file = params->datafile;
|
||||
+ for (i = 1; i < ARRAY_SIZE(spl_params.images); i++) {
|
||||
+ spl_params.images[i].file =
|
||||
+ strchr(spl_params.images[i - 1].file, ':');
|
||||
+ if (!spl_params.images[i].file)
|
||||
+ break;
|
||||
|
||||
- spl_params.boot_file = strchr(spl_params.init_file, ':');
|
||||
- if (spl_params.boot_file) {
|
||||
- *spl_params.boot_file = '\0';
|
||||
- spl_params.boot_file += 1;
|
||||
+ *spl_params.images[i].file = '\0';
|
||||
+ spl_params.images[i].file += 1;
|
||||
}
|
||||
|
||||
- size = rkcommon_get_aligned_filesize(params, spl_params.init_file);
|
||||
- if (size < 0)
|
||||
- return EXIT_FAILURE;
|
||||
- spl_params.init_size = size;
|
||||
+ for (i = 0; i < ARRAY_SIZE(spl_params.images); i++) {
|
||||
+ if (!spl_params.images[i].file)
|
||||
+ break;
|
||||
|
||||
- /* Boot file is optional, and only for back-to-bootrom functionality. */
|
||||
- if (spl_params.boot_file) {
|
||||
- size = rkcommon_get_aligned_filesize(params, spl_params.boot_file);
|
||||
+ size = rkcommon_get_aligned_filesize(params,
|
||||
+ spl_params.images[i].file);
|
||||
if (size < 0)
|
||||
return EXIT_FAILURE;
|
||||
- spl_params.boot_size = size;
|
||||
+ spl_params.images[i].size = size;
|
||||
}
|
||||
|
||||
- if (spl_params.init_size > rkcommon_get_spl_size(params)) {
|
||||
+ if (spl_params.images[0].size > rkcommon_get_spl_size(params)) {
|
||||
fprintf(stderr,
|
||||
"Error: SPL image is too large (size %#x than %#x)\n",
|
||||
- spl_params.init_size, rkcommon_get_spl_size(params));
|
||||
+ spl_params.images[0].size, rkcommon_get_spl_size(params));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -331,7 +330,7 @@ static void rkcommon_set_header0(void *b
|
||||
hdr->magic = cpu_to_le32(RK_MAGIC);
|
||||
hdr->disable_rc4 = cpu_to_le32(!rkcommon_need_rc4_spl(params));
|
||||
hdr->init_offset = cpu_to_le16(init_offset);
|
||||
- hdr->init_size = cpu_to_le16(spl_params.init_size / RK_BLK_SIZE);
|
||||
+ hdr->init_size = cpu_to_le16(spl_params.images[0].size / RK_BLK_SIZE);
|
||||
|
||||
/*
|
||||
* init_boot_size needs to be set, as it is read by the BootROM
|
||||
@@ -341,10 +340,11 @@ static void rkcommon_set_header0(void *b
|
||||
* see https://lists.denx.de/pipermail/u-boot/2017-May/293267.html
|
||||
* for a more detailed explanation by Andy Yan
|
||||
*/
|
||||
- if (spl_params.boot_file)
|
||||
- init_boot_size = spl_params.init_size + spl_params.boot_size;
|
||||
+ if (spl_params.images[1].file)
|
||||
+ init_boot_size = spl_params.images[0].size +
|
||||
+ spl_params.images[1].size;
|
||||
else
|
||||
- init_boot_size = spl_params.init_size + RK_MAX_BOOT_SIZE;
|
||||
+ init_boot_size = spl_params.images[0].size + RK_MAX_BOOT_SIZE;
|
||||
hdr->init_boot_size = cpu_to_le16(init_boot_size / RK_BLK_SIZE);
|
||||
|
||||
rc4_encode(buf, RK_BLK_SIZE, rc4_key);
|
||||
@@ -354,7 +354,6 @@ static void rkcommon_set_header0_v2(void
|
||||
{
|
||||
struct header0_info_v2 *hdr = buf;
|
||||
uint32_t sector_offset, image_sector_count;
|
||||
- uint32_t image_size_array[2];
|
||||
uint8_t *image_ptr = NULL;
|
||||
int i;
|
||||
|
||||
@@ -362,19 +361,17 @@ static void rkcommon_set_header0_v2(void
|
||||
memset(buf, '\0', sector_offset * RK_BLK_SIZE);
|
||||
hdr->magic = cpu_to_le32(RK_MAGIC_V2);
|
||||
hdr->boot_flag = cpu_to_le32(HASH_SHA256);
|
||||
- image_size_array[0] = spl_params.init_size;
|
||||
- image_size_array[1] = spl_params.boot_size;
|
||||
|
||||
- for (i = 0; i < 2; i++) {
|
||||
- if (!image_size_array[i])
|
||||
+ for (i = 0; i < ARRAY_SIZE(spl_params.images); i++) {
|
||||
+ if (!spl_params.images[i].size)
|
||||
break;
|
||||
- image_sector_count = image_size_array[i] / RK_BLK_SIZE;
|
||||
+ image_sector_count = spl_params.images[i].size / RK_BLK_SIZE;
|
||||
hdr->images[i].offset = cpu_to_le16(sector_offset);
|
||||
hdr->images[i].size = cpu_to_le16(image_sector_count);
|
||||
hdr->images[i].address = 0xFFFFFFFF;
|
||||
hdr->images[i].counter = cpu_to_le32(i + 1);
|
||||
image_ptr = buf + sector_offset * RK_BLK_SIZE;
|
||||
- do_sha256_hash(image_ptr, image_size_array[i],
|
||||
+ do_sha256_hash(image_ptr, spl_params.images[i].size,
|
||||
hdr->images[i].hash);
|
||||
sector_offset = sector_offset + image_sector_count;
|
||||
}
|
||||
@@ -401,13 +398,13 @@ void rkcommon_set_header(void *buf, str
|
||||
|
||||
if (rkcommon_need_rc4_spl(params))
|
||||
rkcommon_rc4_encode_spl(buf, header_size,
|
||||
- spl_params.init_size);
|
||||
+ spl_params.images[0].size);
|
||||
|
||||
- if (spl_params.boot_file) {
|
||||
+ if (spl_params.images[1].file) {
|
||||
if (rkcommon_need_rc4_spl(params))
|
||||
rkcommon_rc4_encode_spl(buf + header_size,
|
||||
- spl_params.init_size,
|
||||
- spl_params.boot_size);
|
||||
+ spl_params.images[0].size,
|
||||
+ spl_params.images[1].size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -645,8 +642,9 @@ int rkcommon_vrec_header(struct image_to
|
||||
* We need to store the original file-size (i.e. before padding), as
|
||||
* imagetool does not set this during its adjustment of file_size.
|
||||
*/
|
||||
- params->orig_file_size = tparams->header_size +
|
||||
- spl_params.init_size + spl_params.boot_size;
|
||||
+ params->orig_file_size = tparams->header_size;
|
||||
+ for (int i = 0; i < ARRAY_SIZE(spl_params.images); i++)
|
||||
+ params->orig_file_size += spl_params.images[i].size;
|
||||
|
||||
params->file_size = rkcommon_get_aligned_size(params,
|
||||
params->orig_file_size);
|
||||
@@ -733,16 +731,13 @@ err_close:
|
||||
|
||||
int rockchip_copy_image(int ifd, struct image_tool_params *params)
|
||||
{
|
||||
- int ret;
|
||||
-
|
||||
- ret = copy_file(params, ifd, spl_params.init_file,
|
||||
- spl_params.init_size);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+ int i, ret;
|
||||
|
||||
- if (spl_params.boot_file) {
|
||||
- ret = copy_file(params, ifd, spl_params.boot_file,
|
||||
- spl_params.boot_size);
|
||||
+ for (i = 0; i < ARRAY_SIZE(spl_params.images); i++) {
|
||||
+ if (!spl_params.images[i].size)
|
||||
+ break;
|
||||
+ ret = copy_file(params, ifd, spl_params.images[i].file,
|
||||
+ spl_params.images[i].size);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
From 3e252cae2b5b95c483104318120338d5a51a6b4d Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Wed, 29 Jan 2025 22:36:32 +0000
|
||||
Subject: [PATCH] rockchip: mkimage: Add option for image load address and flag
|
||||
|
||||
The v2 image format supports defining a load address and flag for each
|
||||
embedded image.
|
||||
|
||||
Add initial support for writing the image load address and flag to the
|
||||
v2 image format header.
|
||||
|
||||
This may later be used for RK3576 to embed a minimal initial image that
|
||||
if required to fix booting from SD-card due to a BootROM issue.
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
tools/rkcommon.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/tools/rkcommon.c
|
||||
+++ b/tools/rkcommon.c
|
||||
@@ -152,12 +152,16 @@ static struct spl_info spl_infos[] = {
|
||||
*
|
||||
* @file: image file path
|
||||
* @size: aligned size of image in bytes
|
||||
+ * @address: image load address
|
||||
+ * @flag: no use
|
||||
*/
|
||||
|
||||
struct spl_params {
|
||||
struct {
|
||||
char *file;
|
||||
uint32_t size;
|
||||
+ uint32_t address;
|
||||
+ uint32_t flag;
|
||||
} images[4];
|
||||
};
|
||||
|
||||
@@ -368,7 +372,8 @@ static void rkcommon_set_header0_v2(void
|
||||
image_sector_count = spl_params.images[i].size / RK_BLK_SIZE;
|
||||
hdr->images[i].offset = cpu_to_le16(sector_offset);
|
||||
hdr->images[i].size = cpu_to_le16(image_sector_count);
|
||||
- hdr->images[i].address = 0xFFFFFFFF;
|
||||
+ hdr->images[i].address = spl_params.images[i].address ?: 0xFFFFFFFF;
|
||||
+ hdr->images[i].flag = spl_params.images[i].flag;
|
||||
hdr->images[i].counter = cpu_to_le32(i + 1);
|
||||
image_ptr = buf + sector_offset * RK_BLK_SIZE;
|
||||
do_sha256_hash(image_ptr, spl_params.images[i].size,
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
From f6f1066339a58444d515f1ed72a172610995d090 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Tue, 28 Jan 2025 01:30:12 +0000
|
||||
Subject: [PATCH] WIP: rockchip: mkimage: Add rk3576 align and sd-card
|
||||
workaround
|
||||
|
||||
The BootROM on RK3576 has an issue loading boot images from an SD-card.
|
||||
This issue can be worked around by injecting an initial boot image
|
||||
before TPL that:
|
||||
|
||||
writel(0x3ffff800, 0x3ff803b0)
|
||||
|
||||
Prepend an image containing binary code that does this and return to
|
||||
BootROM to load next image, TPL.
|
||||
|
||||
TODO: embed the binary code into rkcommon.c
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
rk3576-boost.bin | Bin 0 -> 24 bytes
|
||||
rk3576-boost.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
tools/rkcommon.c | 18 ++++++++++++++++-
|
||||
3 files changed, 66 insertions(+), 1 deletion(-)
|
||||
create mode 100644 rk3576-boost.bin
|
||||
create mode 100644 rk3576-boost.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/rk3576-boost.c
|
||||
@@ -0,0 +1,49 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+// Copyright Contributors to the U-Boot project.
|
||||
+
|
||||
+/*
|
||||
+ * Generate assembly code for the c code in this file:
|
||||
+ * aarch64-linux-gnu-gcc -nostdlib -ffreestanding -Os -S -o rk3576-boost.S rk3576-boost.c
|
||||
+ *
|
||||
+ * Compile assembly code and extract the AArch64 binary code:
|
||||
+ * aarch64-linux-gnu-as -o rk3576-boost.o rk3576-boost.S
|
||||
+ * aarch64-linux-gnu-objcopy -O binary -j .text rk3576-boost.o rk3576-boost.bin
|
||||
+ */
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#define SYS_SRAM_BASE 0x3ff80000
|
||||
+#define OFFSET 0x03b0
|
||||
+
|
||||
+int _start(void)
|
||||
+{
|
||||
+ uint32_t *sram = (void*)(SYS_SRAM_BASE + OFFSET);
|
||||
+
|
||||
+ /* set unknown value in sram to fix boot from sdmmc */
|
||||
+ *(sram) = 0x3ffff800;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ .arch armv8-a
|
||||
+ .file "rk3576-boost.c"
|
||||
+ .text
|
||||
+ .align 2
|
||||
+ .global _start
|
||||
+ .type _start, %function
|
||||
+_start:
|
||||
+.LFB0:
|
||||
+ .cfi_startproc
|
||||
+ mov x0, 944
|
||||
+ mov w1, 1073739776
|
||||
+ movk x0, 0x3ff8, lsl 16
|
||||
+ str w1, [x0]
|
||||
+ mov w0, 0
|
||||
+ ret
|
||||
+ .cfi_endproc
|
||||
+.LFE0:
|
||||
+ .size _start, .-_start
|
||||
+ .ident "GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"
|
||||
+ .section .note.GNU-stack,"",@progbits
|
||||
+*/
|
||||
--- a/tools/rkcommon.c
|
||||
+++ b/tools/rkcommon.c
|
||||
@@ -143,7 +143,7 @@ static struct spl_info spl_infos[] = {
|
||||
{ "rv1126", "110B", 0x10000 - 0x1000, false, RK_HEADER_V1 },
|
||||
{ "rk3528", "RK35", 0x10000 - 0x1000, false, RK_HEADER_V2 },
|
||||
{ "rk3568", "RK35", 0x10000 - 0x1000, false, RK_HEADER_V2 },
|
||||
- { "rk3576", "RK35", 0x80000 - 0x1000, false, RK_HEADER_V2 },
|
||||
+ { "rk3576", "RK35", 0x80000 - 0x1000, false, RK_HEADER_V2, 8 },
|
||||
{ "rk3588", "RK35", 0x100000 - 0x1000, false, RK_HEADER_V2 },
|
||||
};
|
||||
|
||||
@@ -271,6 +271,22 @@ int rkcommon_check_params(struct image_t
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
+ if (!strcmp(params->imagename, "rk3576")) {
|
||||
+ size = rkcommon_get_aligned_filesize(params, "rk3576-boost.bin");
|
||||
+ if (size < 0)
|
||||
+ return EXIT_SUCCESS;
|
||||
+
|
||||
+ for (i = ARRAY_SIZE(spl_params.images) - 1; i > 0; i--) {
|
||||
+ spl_params.images[i] = spl_params.images[i - 1];
|
||||
+ }
|
||||
+
|
||||
+ spl_params.images[0].file = "rk3576-boost.bin";
|
||||
+ spl_params.images[0].size = size;
|
||||
+
|
||||
+ spl_params.images[0].address = 0x3ffc0000;
|
||||
+ spl_params.images[1].address = 0x3ff81000;
|
||||
+ }
|
||||
+
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
err_spl_info:
|
||||
Reference in New Issue
Block a user