I have imx7d-pico with Carrier board.
...
I have issue: Reading file would overwrite reserved memory ** Failed to load 'hello_world.bin,
Your use of an SoC that has both a microprocessor and an auxiliary microcontroller with shared memory is a salient point. Refer to the NXP Appnote (esp. Table 5) for details. The use of multiple memory address ranges probably makes your problem a boundary case that U-Boot developers may have overlooked.
Apparently U-Boot has evolved to become more strict on where files can be loaded in address space (probably to help detect mistakes). The dumps of the LMB structure clearly indicate that only main memory, 0x80000000 to 0xbfffffff, is accessible to certain U-Boot commands. Since the address space to access the auxiliary processor memory (0x7f8000 to 0x7fffff) is outside this range of main memory, this auxiliary memory region is unwritable by various load-a-file commands.
The root cause of the error message is in the Logical Memory Block "library" of U-Boot, lib/lmb.c. The procedure lmb_init_and_reserve() only allocates the available (and hence loadable) memory space(s) based on U-Boot's legacy method for memory definition.
The legacy method relies on macro definitions, such as CFG_SYS_SDRAM_BASE, and are typically defined in a board-specific header file. For example the following definitions are extracted from include/configs/imx7-cm.h:
#define CFG_SYS_SDRAM_BASE PHYS_SDRAM
#define CFG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR
#define CFG_SYS_INIT_RAM_SIZE IRAM_SIZE
Then in common/board_f.c, the base address for SDRAM is assigned to a global_data variable for the base address of RAM used by U-Boot:
static int setup_dest_addr(void)
{
...
gd->ram_base = CFG_SYS_SDRAM_BASE;
Later the first memory bank of the board info structure is filled with this global_data memory info in common/board_f.c:
__weak int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = gd->ram_base;
gd->bd->bi_dram[0].size = get_effective_memsize();
return 0;
}
That is the board memory info that is later used to fill-in the LMB structure in lib/lmb.c:
/* Initialize the struct, add memory and call arch/board reserve functions */
void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd, void *fdt_blob)
{
int i;
lmb_init(lmb);
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
if (bd->bi_dram[i].size) {
lmb_add(lmb, bd->bi_dram[i].start,
bd->bi_dram[i].size);
}
}
lmb_reserve_common(lmb, fdt_blob);
}
So the Logical Memory Block "library" relies on U-Boot's legacy method for defining memory.
That means the memory definitions in the Device Tree are ignored by U-Boot.
When you try to load a file from a storage device to memory, the following procedure is called in fs/fs.c
#ifdef CONFIG_LMB
/* Check if a file may be read to the given address */
static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset,
loff_t len, struct fstype_info *info)
{
...
lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
lmb_dump_all(&lmb);
if (lmb_alloc_addr(&lmb, addr, read_len) == addr)
return 0;
log_err("** Reading file would overwrite reserved memory **\n");
return -ENOSPC;
}
#endif
Note the conditional compilation for this routine that performs the memory check.
I tied to build a version of U-Boot 2022.01 without CONFIG_LMB, but the build failed. So even though CONFIG_LMB appears to be an optional library selection in the menuconfig, there seems to be source code changes needed to de-select CONFIG_LMB.
So you cannot try to bypass this memory check by building an alternate configuration of U-Boot.
A Workaround
Rather than try to define the aux memory as a bank of main memory, there is a simple & easy workaround to use a recent & unmodified U-Boot in your situation.
Instead of loading the file directly to the auxiliary processor memory, simply load the file to main memory at 0x80008000
, and then perform a copy of 32KB to the aux memory at tcm_addr
.
The loadm4image
variable should be changed to:
loadm4image=fatload mmc ${mmcdev}:${mmcpart} 80008000 ${m4image}; \
cp.b 80008000 ${tcm_addr} 8000
This can be accomplished with the following command to the previously posted environment:
setenv loadm4image 'fatload mmc ${mmcdev}:${mmcpart} 80008000 ${m4image}; cp.b 80008000 ${tcm_addr} 8000'