On Mon, Mar 10 2025, Vincent Stehlé <vincent.ste...@arm.com> wrote: > On i.MX8M SoCs, the /firmware/optee Devicetree node is created just before > booting the OS when OP-TEE is found running. If the node already exists, > this results in an error, which prevents the OS to boot: > > Could not create optee node. > ERROR: system-specific fdt fixup failed: FDT_ERR_EXISTS > - must RESET the board to recover. > > failed to process device tree > [...] > > Deal with an existing optee node gracefully at runtime to fix this issue.
We hit that exact problem on our imx8mp-evk trying to boot v2025.04. However, since the .dtb in our kernel FIT image certainly did/does not have a /firmware nor /firmware/optee node, I was wondering how we could possibly hit that FDT_ERR_EXISTS, but we clearly did. Digging, we found this, which is now commit 048fabc21bf. But I'm wondering if this is really the right fix. Because digging further, it seems that it is U-Boot stepping on its own toes: We have the generic optee_copy_fdt_nodes() called from image_setup_libfdt(), which copies various optee-related nodes and properties from U-Boot's control dtb to the blob which is to become the linux kernel's dtb. So that's where the /firmware/optee node is really created in the first place. Later, image_setup_libfdt() calls ft_system_setup() which in turn calls the helper ft_add_optee_node() and then hits that "oh but the node already exists". It seems that the two highlighted functions really try to do the same thing, though in slightly different ways. The former copies from U-Boot's control dtb, while the latter hard-codes the compatible and method strings and (re-)computes the memory areas. So using the "find_or_add" variant does feel like somewhat of a band-aid. Shouldn't we have just one place that updates the kernel dtb, instead of one piece of code silently changing or redoing what another piece of code has already done? Rasmus PS: On a somewhat related note, it seems that the whole CONFIG_OPTEE stuff broke our setup in another way: We used to have loadaddr=0x60000000, but trying to use that address now results in ** Reading file would overwrite reserved memory ** Failed to load 'kernel.itb' because somehow U-Boot ends up with this memory view: lmb_dump_all: memory.count = 0x2 memory[0] [0x40000000-0x55ffffff], 0x16000000 bytes, flags: none memory[1] [0x58000000-0x1bfffffff], 0x168000000 bytes, flags: none reserved.count = 0x2 reserved[0] [0x52f020c0-0x55ffffff], 0x30fdf40 bytes, flags: no-map reserved[1] [0x58000000-0x1bfffffff], 0x168000000 bytes, flags: no-map That 0x56000000-0x58000000 is carved out of memory is fine (that's where op-tee lives), but it's really odd that all memory from 0x58000000 till the end ends up "reserved". The first reserved entry is, I guess, U-Boot having relocated itself to the end of the first chunk of memory.