diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index ef8583a1a6..94e8a502c6 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -24,11 +24,18 @@ static int mmc_load_legacy(struct mmc *mmc, ulong sector, u32 image_size_sectors; unsigned long count; int ret; + int nm_additional_header_bytes; + int nm_additional_trailer_bytes; ret = spl_parse_image_header(header); if (ret) return ret; + nm_additional_header_bytes = sizeof(struct nm_header) - sizeof(struct image_header); + nm_additional_trailer_bytes = sizeof(__be32); + spl_image.load_addr -= nm_additional_header_bytes; + spl_image.size += nm_additional_header_bytes + nm_additional_trailer_bytes; + /* convert size to sectors - round up */ image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / mmc->read_bl_len; @@ -54,21 +61,32 @@ static ulong h_spl_load_read(struct spl_load_info *load, ulong sector, static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) { + const unsigned int START_MAGIC = 0x424c5354; + const unsigned int END_MAGIC = 0x424c454e; + unsigned long count; + struct nm_header *nm_header; struct image_header *header; int ret = 0; + __be32* end_tag_position; - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - - sizeof(struct image_header)); + nm_header = (struct nm_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct nm_header)); /* read image header to find the image size & load address */ - count = blk_dread(mmc_get_blk_desc(mmc), sector, 1, header); + count = blk_dread(mmc_get_blk_desc(mmc), sector, 1, nm_header); debug("hdr read sector %lx, count=%lu\n", sector, count); if (count == 0) { ret = -EIO; goto end; } + if (be32_to_cpu(nm_header->nm_start_tag) != START_MAGIC) return -1; + if (be32_to_cpu(nm_header->nm_length)>10000000) return -1; + end_tag_position = (__be32*)(((void*)nm_header) + sizeof(struct nm_header) - sizeof(struct image_header) + (be32_to_cpu(nm_header->nm_length))); + + header = &(nm_header->header); + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; @@ -84,6 +102,8 @@ static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) ret = mmc_load_legacy(mmc, sector, header); } + if (be32_to_cpu(*end_tag_position) != END_MAGIC) return -1; + end: if (ret) { #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT @@ -92,6 +112,8 @@ end: return -1; } + printf("Found valid u-boot image at sector %ld\n", sector); + return 0; } @@ -324,6 +346,9 @@ int spl_mmc_load_image(u32 boot_device) #if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR) err = mmc_load_image_raw_sector(mmc, CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); + if (err) + err = mmc_load_image_raw_sector(mmc, + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_ALTERNATE); if (!err) return err; #endif diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h index 7db08813e4..adbc8c8ab3 100644 --- a/include/configs/ti_armv7_common.h +++ b/include/configs/ti_armv7_common.h @@ -220,6 +220,7 @@ /* RAW SD card / eMMC locations. */ #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 /* address 0x60000 */ +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_ALTERNATE 0x1b00 /* address 0x360000 */ #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x200 /* 256 KB */ /* FAT sd card locations. */ diff --git a/include/image.h b/include/image.h index a8f6bd16f6..34b0ea71d2 100644 --- a/include/image.h +++ b/include/image.h @@ -286,6 +286,13 @@ typedef struct image_header { uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t; +typedef struct nm_header { + __be32 nm_start_tag; /* BLST (0x424c5354) */ + __be32 nm_version; /* U-boot version number */ + __be32 nm_length; /* U-boot image length */ + struct image_header header; +} nm_header_t; + typedef struct image_info { ulong start, end; /* start/end of blob */ ulong image_start, image_len; /* start of image within blob, len of image */