]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
SPL: Add support for specifying offset between header and image
authorPali Rohár <pali@kernel.org>
Fri, 23 Jul 2021 09:14:27 +0000 (11:14 +0200)
committerStefan Roese <sr@denx.de>
Sat, 31 Jul 2021 07:49:32 +0000 (09:49 +0200)
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: Pali Rohár <pali@kernel.org>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
common/spl/spl_mmc.c
common/spl/spl_sata.c
common/spl/spl_spi.c
include/spl.h

index 4dff9bfd6e871f22fa43df77f19540270181cea8..212a2b0992891521e5494d61995002d9b48211fc 100644 (file)
 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;
 }
 
index e108af0576aa971a1714a9170cc63173ae3d0bdf..535a9219efa548ef4fa8b8a720ccce96a010e00e 100644 (file)
@@ -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;
 }
 
index 6a4e03328709665573402a5983d7cce832b212d8..9884e7c18500ce2024ba0691d9b8e2ef629942c5 100644 (file)
@@ -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);
                }
index 925b6f0cc6461663f20271d3be35950b747e167f..afbf39bef49f8d110927def0ed46d4c4e5374d32 100644 (file)
@@ -219,6 +219,7 @@ struct spl_image_info {
        void *fdt_addr;
 #endif
        u32 boot_device;
+       u32 offset;
        u32 size;
        u32 flags;
        void *arg;