diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile index c43c0fef4f..e94f058998 100644 --- a/package/boot/uboot-rockchip/Makefile +++ b/package/boot/uboot-rockchip/Makefile @@ -480,6 +480,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) $(CP) $(PKG_BUILD_DIR)/u-boot-rockchip.bin $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-u-boot-rockchip.bin diff --git a/package/boot/uboot-rockchip/patches/108-01-rockchip-mkimage-Split-size_and_off-and-size_and_nim.patch b/package/boot/uboot-rockchip/patches/108-01-rockchip-mkimage-Split-size_and_off-and-size_and_nim.patch new file mode 100644 index 0000000000..b69d95ed0f --- /dev/null +++ b/package/boot/uboot-rockchip/patches/108-01-rockchip-mkimage-Split-size_and_off-and-size_and_nim.patch @@ -0,0 +1,119 @@ +From cb682b364eb2d49c3ee2a1f7f33258919f5da688 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 29 Jan 2025 22:36:27 +0000 +Subject: [PATCH 1/7] 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 +--- + +--- 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]; +@@ -350,17 +352,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; +@@ -369,6 +372,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); + } + +@@ -515,10 +520,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); + +@@ -532,8 +535,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, diff --git a/package/boot/uboot-rockchip/patches/108-02-rockchip-mkimage-Print-image-information-for-all-emb.patch b/package/boot/uboot-rockchip/patches/108-02-rockchip-mkimage-Print-image-information-for-all-emb.patch new file mode 100644 index 0000000000..b9bd6949ba --- /dev/null +++ b/package/boot/uboot-rockchip/patches/108-02-rockchip-mkimage-Print-image-information-for-all-emb.patch @@ -0,0 +1,106 @@ +From 0085f8509d62591560901c11fa9d63e34da4fa62 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 29 Jan 2025 22:36:28 +0000 +Subject: [PATCH 2/7] 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 +--- + +--- a/tools/rkcommon.c ++++ b/tools/rkcommon.c +@@ -349,8 +349,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); +@@ -504,6 +502,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; +@@ -520,8 +541,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); + +@@ -539,15 +559,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) diff --git a/package/boot/uboot-rockchip/patches/108-03-rockchip-mkimage-Print-boot0-and-boot1-parameters.patch b/package/boot/uboot-rockchip/patches/108-03-rockchip-mkimage-Print-boot0-and-boot1-parameters.patch new file mode 100644 index 0000000000..bd9070844b --- /dev/null +++ b/package/boot/uboot-rockchip/patches/108-03-rockchip-mkimage-Print-boot0-and-boot1-parameters.patch @@ -0,0 +1,68 @@ +From 83326e18d15be1ac9b7daf7b472d0bcb8074da2b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 29 Jan 2025 22:36:29 +0000 +Subject: [PATCH 3/7] 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 +--- + +--- 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]; +@@ -509,6 +513,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), diff --git a/package/boot/uboot-rockchip/patches/108-04-rockchip-mkimage-Add-option-to-change-image-offset-a.patch b/package/boot/uboot-rockchip/patches/108-04-rockchip-mkimage-Add-option-to-change-image-offset-a.patch new file mode 100644 index 0000000000..ba0bec841a --- /dev/null +++ b/package/boot/uboot-rockchip/patches/108-04-rockchip-mkimage-Add-option-to-change-image-offset-a.patch @@ -0,0 +1,205 @@ +From a9a5d21d926594a87e8db877d4b9261200c3f8fd Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 29 Jan 2025 22:36:30 +0000 +Subject: [PATCH 4/7] 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 +--- + +--- a/tools/rkcommon.c ++++ b/tools/rkcommon.c +@@ -140,6 +140,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[] = { +@@ -199,14 +200,19 @@ static struct spl_info *rkcommon_get_spl + return NULL; + } + +-static int rkcommon_get_aligned_size(struct image_tool_params *params, +- const char *fname) ++static 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 +@@ -215,6 +221,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; +@@ -237,14 +264,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; +@@ -301,13 +328,6 @@ bool rkcommon_need_rc4_spl(struct image_ + return info->spl_rc4; + } + +-static 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; +@@ -320,12 +340,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); + + /* +@@ -353,10 +374,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; + +@@ -382,11 +403,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) */ +@@ -394,12 +416,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); + } +@@ -624,7 +646,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); +@@ -642,7 +664,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, + }; + diff --git a/package/boot/uboot-rockchip/patches/108-05-rockchip-mkimage-Add-support-for-up-to-4-input-files.patch b/package/boot/uboot-rockchip/patches/108-05-rockchip-mkimage-Add-support-for-up-to-4-input-files.patch new file mode 100644 index 0000000000..8f4fab39d9 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/108-05-rockchip-mkimage-Add-support-for-up-to-4-input-files.patch @@ -0,0 +1,200 @@ +From 31255e35146c279696c51cde45facd1ea10eed28 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 29 Jan 2025 22:36:31 +0000 +Subject: [PATCH 5/7] 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 +--- + +--- a/tools/rkcommon.c ++++ b/tools/rkcommon.c +@@ -166,17 +166,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 }; +@@ -256,31 +254,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; + } + +@@ -347,7 +346,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 +@@ -357,10 +356,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); +@@ -370,7 +370,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; + +@@ -378,19 +377,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; + } +@@ -417,13 +414,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); + } + } + } +@@ -661,8 +658,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); +@@ -749,16 +747,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; + } diff --git a/package/boot/uboot-rockchip/patches/108-06-rockchip-mkimage-Add-option-for-image-load-address-a.patch b/package/boot/uboot-rockchip/patches/108-06-rockchip-mkimage-Add-option-for-image-load-address-a.patch new file mode 100644 index 0000000000..7bd8b53121 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/108-06-rockchip-mkimage-Add-option-for-image-load-address-a.patch @@ -0,0 +1,47 @@ +From 3e252cae2b5b95c483104318120338d5a51a6b4d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 29 Jan 2025 22:36:32 +0000 +Subject: [PATCH 6/7] 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 +--- + +--- a/tools/rkcommon.c ++++ b/tools/rkcommon.c +@@ -168,12 +168,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]; + }; + +@@ -384,7 +388,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, diff --git a/package/boot/uboot-rockchip/patches/108-07-WIP-rockchip-mkimage-Add-rk3576-align-and-sd-card-wo.patch b/package/boot/uboot-rockchip/patches/108-07-WIP-rockchip-mkimage-Add-rk3576-align-and-sd-card-wo.patch new file mode 100644 index 0000000000..b1dfe1b4dd --- /dev/null +++ b/package/boot/uboot-rockchip/patches/108-07-WIP-rockchip-mkimage-Add-rk3576-align-and-sd-card-wo.patch @@ -0,0 +1,106 @@ +From f6f1066339a58444d515f1ed72a172610995d090 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 28 Jan 2025 01:30:12 +0000 +Subject: [PATCH 7/7] 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 +--- + +--- /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 ++ ++#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 +@@ -159,7 +159,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 }, + }; + +@@ -287,6 +287,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: