[U-Boot] [PATCH V2] spl: Weed out CONFIG_SYS_TEXT_BASE usage
Michal Simek
monstr at monstr.eu
Wed Oct 3 13:39:24 UTC 2018
Hi Marek,
Ășt 14. 8. 2018 v 11:27 odesĂlatel Marek Vasut <marex at denx.de> napsal:
> The SPL loaders assume that the CONFIG_SYS_TEXT_BASE memory location
> is available and can be corrupted by loading ie. uImage or fitImage
> headers there. Sometimes it could be beneficial to load the headers
> elsewhere, ie. if CONFIG_SYS_TEXT_BASE is not yet writable while we
> still want to parse the image headers in some local onchip memory to
> ie. extract firmware from that image.
>
> Add the possibility to override the location where the headers get
> loaded by introducing new function, spl_get_load_buffer() which takes
> two arguments -- offset from the CONFIG_SYS_TEXT_BASE and size of the
> data that are to be loaded there -- and returns a valid buffer address
> or hangs the system. The default behavior is the same as before, add
> the offset to CONFIG_SYS_TEXT_BASE and return that address. User can
> override the weak spl_get_load_buffer() function though.
>
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Tom Rini <trini at konsulko.com>
> ---
> V2: Fix build issues on multiple boards due to incorrect pointer casting
> ---
> common/spl/spl.c | 5 +++++
> common/spl/spl_ext.c | 3 +--
> common/spl/spl_fat.c | 3 +--
> common/spl/spl_fit.c | 6 +++---
> common/spl/spl_mmc.c | 6 +++---
> common/spl/spl_nand.c | 4 ++--
> common/spl/spl_onenand.c | 3 +--
> common/spl/spl_ram.c | 5 +++--
> common/spl/spl_spi.c | 3 +--
> common/spl/spl_ubi.c | 3 +--
> include/spl.h | 9 +++++++++
> 11 files changed, 30 insertions(+), 20 deletions(-)
>
> diff --git a/common/spl/spl.c b/common/spl/spl.c
> index eda84d0c74..7c22d0f44d 100644
> --- a/common/spl/spl.c
> +++ b/common/spl/spl.c
> @@ -127,6 +127,11 @@ __weak void spl_board_prepare_for_boot(void)
> /* Nothing to do! */
> }
>
> +__weak struct image_header *spl_get_load_buffer(ssize_t offset, size_t
> size)
> +{
> + return (struct image_header *)(CONFIG_SYS_TEXT_BASE + offset);
> +}
> +
> void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
> {
> ulong u_boot_pos = binman_sym(ulong, u_boot_any, image_pos);
> diff --git a/common/spl/spl_ext.c b/common/spl/spl_ext.c
> index fd30a61f9a..fe05223605 100644
> --- a/common/spl/spl_ext.c
> +++ b/common/spl/spl_ext.c
> @@ -16,8 +16,7 @@ int spl_load_image_ext(struct spl_image_info *spl_image,
> loff_t filelen, actlen;
> disk_partition_t part_info = {};
>
> - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
> - sizeof(struct
> image_header));
> + header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
>
> if (part_get_info(block_dev, partition, &part_info)) {
> printf("spl: no partition table found\n");
> diff --git a/common/spl/spl_fat.c b/common/spl/spl_fat.c
> index 0403016bb4..163e540622 100644
> --- a/common/spl/spl_fat.c
> +++ b/common/spl/spl_fat.c
> @@ -63,8 +63,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image,
> if (err)
> goto end;
>
> - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
> - sizeof(struct
> image_header));
> + header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
>
> err = file_fat_read(filename, header, sizeof(struct image_header));
> if (err <= 0)
> diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
> index 9eabb1c105..f08e5018c3 100644
> --- a/common/spl/spl_fit.c
> +++ b/common/spl/spl_fit.c
> @@ -357,7 +357,7 @@ int spl_load_simple_fit(struct spl_image_info
> *spl_image,
> struct spl_image_info image_info;
> int node = -1;
> int images, ret;
> - int base_offset, align_len = ARCH_DMA_MINALIGN - 1;
> + int base_offset, hsize, align_len = ARCH_DMA_MINALIGN - 1;
> int index = 0;
>
> /*
> @@ -386,8 +386,8 @@ int spl_load_simple_fit(struct spl_image_info
> *spl_image,
> * For FIT with data embedded, data is loaded as part of FIT image.
> * For FIT with external data, data is not loaded in this step.
> */
> - fit = (void *)((CONFIG_SYS_TEXT_BASE - size - info->bl_len -
> - align_len) & ~align_len);
> + hsize = (size + info->bl_len + align_len) & ~align_len;
> + fit = spl_get_load_buffer(-hsize, hsize);
> sectors = get_aligned_image_size(info, size, 0);
> count = info->read(info, sector, sectors, fit);
> debug("fit read sector %lx, sectors=%d, dst=%p, count=%lu\n",
> diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
> index 0b2f059570..75c41598e6 100644
> --- a/common/spl/spl_mmc.c
> +++ b/common/spl/spl_mmc.c
> @@ -55,13 +55,13 @@ int mmc_load_image_raw_sector(struct spl_image_info
> *spl_image,
> {
> unsigned long count;
> struct image_header *header;
> + struct blk_desc *bd = mmc_get_blk_desc(mmc);
> int ret = 0;
>
> - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
> - sizeof(struct image_header));
> + header = spl_get_load_buffer(-sizeof(*header), bd->blksz);
>
> /* read image header to find the image size & load address */
> - count = blk_dread(mmc_get_blk_desc(mmc), sector, 1, header);
> + count = blk_dread(bd, sector, 1, header);
> debug("hdr read sector %lx, count=%lu\n", sector, count);
> if (count == 0) {
> ret = -EIO;
> diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c
> index 2722fd3860..6eb190f1ea 100644
> --- a/common/spl/spl_nand.c
> +++ b/common/spl/spl_nand.c
> @@ -83,8 +83,8 @@ static int spl_nand_load_image(struct spl_image_info
> *spl_image,
> #endif
> nand_init();
>
> - /*use CONFIG_SYS_TEXT_BASE as temporary storage area */
> - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
> + header = spl_get_load_buffer(0, sizeof(*header));
> +
> #ifdef CONFIG_SPL_OS_BOOT
> if (!spl_start_uboot()) {
> /*
> diff --git a/common/spl/spl_onenand.c b/common/spl/spl_onenand.c
> index d32333935a..ee30f328e6 100644
> --- a/common/spl/spl_onenand.c
> +++ b/common/spl/spl_onenand.c
> @@ -21,8 +21,7 @@ static int spl_onenand_load_image(struct spl_image_info
> *spl_image,
>
> debug("spl: onenand\n");
>
> - /*use CONFIG_SYS_TEXT_BASE as temporary storage area */
> - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
> + header = spl_get_load_buffer(0, CONFIG_SYS_ONENAND_PAGE_SIZE);
> /* Load u-boot */
> onenand_spl_load_image(CONFIG_SYS_ONENAND_U_BOOT_OFFS,
> CONFIG_SYS_ONENAND_PAGE_SIZE, (void *)header);
> diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c
> index e594beaeaa..619b39a537 100644
> --- a/common/spl/spl_ram.c
> +++ b/common/spl/spl_ram.c
> @@ -63,8 +63,9 @@ static int spl_ram_load_image(struct spl_image_info
> *spl_image,
> * No binman support or no information. For now,
> fix it
> * to the address pointed to by U-Boot.
> */
> - u_boot_pos = CONFIG_SYS_TEXT_BASE -
> - sizeof(struct image_header);
> + header = spl_get_load_buffer(-sizeof(*header),
> + sizeof(*header));
> +
>
I am curious how you have tested this change.
Because I see on my zc706 that this breaks my SPL boot flow.
This should be assigned to u_boot_pos instead of header (which is done 2
line below)
and also here is additional empty line which shouldn't be there.
> }
> header = (struct image_header *)map_sysmem(u_boot_pos, 0);
>
> diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c
> index ba60a3a3c5..e10cf0124f 100644
> --- a/common/spl/spl_spi.c
> +++ b/common/spl/spl_spi.c
> @@ -88,8 +88,7 @@ static int spl_spi_load_image(struct spl_image_info
> *spl_image,
> return -ENODEV;
> }
>
> - /* use CONFIG_SYS_TEXT_BASE as temporary storage area */
> - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
> + header = spl_get_load_buffer(-sizeof(*header), 0x40);
>
And I am also curious why we have 0x40 here.
Thanks,
Michal
--
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform
More information about the U-Boot
mailing list