提交 5fce2875 编写于 作者: P Pali Rohár 提交者: Stefan Roese

SPL: Add support for specifying offset between header and image

Some image types (e.g. kwbimage v1) store the offset to SPL binary and
offset to U-Boot proper binary in their headers. To avoid reading SPL
binary when loading U-Boot proper, 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: NPali Rohár <pali@kernel.org>
Reviewed-by: NMarek Behún <marek.behun@nic.cz>
Reviewed-by: NStefan Roese <sr@denx.de>
上级 abbf2179
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
}
......
......@@ -219,6 +219,7 @@ struct spl_image_info {
void *fdt_addr;
#endif
u32 boot_device;
u32 offset;
u32 size;
u32 flags;
void *arg;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册