[PATCH u-boot-mvebu v2 33/41] SPL: Add support for specifying offset between header and image

Stefan Roese sr at denx.de
Wed Jul 21 12:29:23 CEST 2021


On 19.07.21 14:20, Marek Behún wrote:
> From: Pali Rohár <pali at kernel.org>
> 
> Some image types (e.g. kwbimage v1) store the offset to SPL binary and
> offset to main U-Boot binary in their headers. To avoid reading SPL
> binary when loading main U-Boot, add support for specifying offset in
> struct spl_image_info, which defines the offset from the beginning of
> the header and the beginning of the executable data.
> 
> Initial support is added only for SPI, MMC and SATA code. We can extend
> it later if needed.
> 
> Signed-off-by: Pali Rohár <pali at kernel.org>
> Reviewed-by: Marek Behún <marek.behun at nic.cz>

Reviewed-by: Stefan Roese <sr at denx.de>

Thanks,
Stefan

> ---
>   common/spl/spl_mmc.c  | 16 +++++++++++++++-
>   common/spl/spl_sata.c | 12 +++++++++++-
>   common/spl/spl_spi.c  |  2 +-
>   include/spl.h         |  1 +
>   4 files changed, 28 insertions(+), 3 deletions(-)
> 
> diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
> index add2785b4e..5605f1820d 100644
> --- a/common/spl/spl_mmc.c
> +++ b/common/spl/spl_mmc.c
> @@ -20,26 +20,40 @@
>   static int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
>   			   ulong sector, struct image_header *header)
>   {
> +	u32 image_offset_sectors;
>   	u32 image_size_sectors;
>   	unsigned long count;
> +	u32 image_offset;
>   	int ret;
>   
>   	ret = spl_parse_image_header(spl_image, header);
>   	if (ret)
>   		return ret;
>   
> +	/* convert offset to sectors - round down */
> +	image_offset_sectors = spl_image->offset / mmc->read_bl_len;
> +	/* calculate remaining offset */
> +	image_offset = spl_image->offset % mmc->read_bl_len;
> +
>   	/* convert size to sectors - round up */
>   	image_size_sectors = (spl_image->size + mmc->read_bl_len - 1) /
>   			     mmc->read_bl_len;
>   
>   	/* Read the header too to avoid extra memcpy */
> -	count = blk_dread(mmc_get_blk_desc(mmc), sector, image_size_sectors,
> +	count = blk_dread(mmc_get_blk_desc(mmc),
> +			  sector + image_offset_sectors,
> +			  image_size_sectors,
>   			  (void *)(ulong)spl_image->load_addr);
>   	debug("read %x sectors to %lx\n", image_size_sectors,
>   	      spl_image->load_addr);
>   	if (count != image_size_sectors)
>   		return -EIO;
>   
> +	if (image_offset)
> +		memmove((void *)(ulong)spl_image->load_addr,
> +			(void *)(ulong)spl_image->load_addr + image_offset,
> +			spl_image->size);
> +
>   	return 0;
>   }
>   
> diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c
> index e108af0576..535a9219ef 100644
> --- a/common/spl/spl_sata.c
> +++ b/common/spl/spl_sata.c
> @@ -36,6 +36,8 @@ static int spl_sata_load_image_raw(struct spl_image_info *spl_image,
>   	struct image_header *header;
>   	unsigned long count;
>   	u32 image_size_sectors;
> +	u32 image_offset_sectors;
> +	u32 image_offset;
>   	int ret;
>   
>   	header = spl_get_load_buffer(-sizeof(*header), stor_dev->blksz);
> @@ -48,11 +50,19 @@ static int spl_sata_load_image_raw(struct spl_image_info *spl_image,
>   		return ret;
>   
>   	image_size_sectors = DIV_ROUND_UP(spl_image->size, stor_dev->blksz);
> -	count = blk_dread(stor_dev, sector, image_size_sectors,
> +	image_offset_sectors = spl_image->offset / stor_dev->blksz;
> +	image_offset = spl_image->offset % stor_dev->blksz;
> +	count = blk_dread(stor_dev, sector + image_offset_sectors,
> +			image_size_sectors,
>   			(void *)spl_image->load_addr);
>   	if (count != image_size_sectors)
>   		return -EIO;
>   
> +	if (image_offset)
> +		memmove((void *)spl_image->load_addr,
> +			(void *)spl_image->load_addr + image_offset,
> +			spl_image->size);
> +
>   	return 0;
>   }
>   
> diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c
> index 6a4e033287..9884e7c185 100644
> --- a/common/spl/spl_spi.c
> +++ b/common/spl/spl_spi.c
> @@ -159,7 +159,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
>   			err = spl_parse_image_header(spl_image, header);
>   			if (err)
>   				return err;
> -			err = spi_flash_read(flash, payload_offs,
> +			err = spi_flash_read(flash, payload_offs + spl_image->offset,
>   					     spl_image->size,
>   					     (void *)spl_image->load_addr);
>   		}
> diff --git a/include/spl.h b/include/spl.h
> index cee9a42ddb..3df923a813 100644
> --- a/include/spl.h
> +++ b/include/spl.h
> @@ -198,6 +198,7 @@ struct spl_image_info {
>   	void *fdt_addr;
>   #endif
>   	u32 boot_device;
> +	u32 offset;
>   	u32 size;
>   	u32 flags;
>   	void *arg;
> 


Viele Grüße,
Stefan

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de


More information about the U-Boot mailing list