OpenAMP / open-amp

The main OpenAMP library implementing RPMSG, Virtio, and Remoteproc for RTOS etc
https://www.openampproject.org/
Other
678 stars 278 forks source link

The remote ELF loading problem #552

Closed UmairKhanUET closed 4 months ago

UmairKhanUET commented 4 months ago

The elf loader assumes that the last ELF program segment will always be a LOAD type segment. I deduce this from the fact that the elf_load() function, when loading the remote ELF sections during the RPROC_LOADER_READY_TO_LOAD stage, compares the last load segment num to the total ELF sections to determine if the loading is complete and it can move to the next stage PROC_LOADER_POST_DATA_LOAD. If the last program segment in the ELF is not of type LOAD, the last loaded LOAD segment never equals total ELF sections. This creates an error condition, and the firmware loading fails.

tnmysh commented 4 months ago

If the last program segment in the ELF is not of type LOAD, the last loaded LOAD segment never equals total ELF sections.

Is there a way this issue can be reproduced ? May be linker script exapmle where elf loading is failed with current code.

UmairKhanUET commented 4 months ago

If the last program segment in the ELF is not of type LOAD, the last loaded LOAD segment never equals total ELF sections.

Is there a way this issue can be reproduced ? May be linker script exapmle where elf loading is failed with current code.

@tnmysh Yeah. For an instance, you can build any zephyr sample application. I built hello_world for qemu_cortex_a9 and the readelf shows the below output with the -l flag:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x0050f8 0x00105000 0x00105000 0x00008 0x00008 R   0x4
  LOAD           0x0000f8 0x00100000 0x00100000 0x05008 0x06000 RWE 0x8
  LOAD           0x006000 0x00106000 0x00106000 0x01000 0xca3b4 RW  0x4000
  LOAD           0x007000 0x001d03b4 0x001d03b4 0x00054 0x00c4c RW  0x4
  LOAD           0x007054 0x001d1000 0x001d1000 0x00004 0x00004 R   0x1
  TLS            0x006368 0x00106368 0x00106368 0x00000 0x00004 R   0x4

 Section to Segment mapping:
  Segment Sections...
   00     .ARM.exidx
   01     rom_start text .ARM.exidx rodata_start
   02     initlevel device_area sw_isr_table log_const_area rodata bss noinit
   03     datas device_states .last_ram_section
   04     .last_section
   05     tbss
tnmysh commented 4 months ago

Thanks for this example. Looks like bug is there and wasn't found as It's pretty old code not practiced on platforms supported by upstream library.

Thanks for finding this issue. We can close this issue once related PR is merged.

arnopo commented 4 months ago

@UmairKhanUET Your issue shows that we need to improve our tests on the loader part of the library. Unfortunately, this code is quite old, and we don't have reference code/platform to test it. Do you think that your work could be reused for testing (integrated in https://github.com/OpenAMP/openamp-system-reference)? If yes, could you please describe your environment in more detail (platform used, use case, etc.)

UmairKhanUET commented 4 months ago

@arnopo , I would love to contribute back but there are proprietary reasons to not do so. But overall, the use-case is pretty simple, and I believe this ticket also contains adequate information on it. Mine is a custom remote image but you could also safely use any Zephyr image as a replacement on any platform. I have found that Zephyr's ELFs have a trailing PT_TLS type program header so should be good enough. You can use any supported multicore platform. ZynqMP ZCU102 can also be a good choice (I see that it is supported) with the load_fw example that exercises the remoteproc_load() API.

ZCU102 Cortex-A53 = Master/Driver running OpenAMP (any OS or bare-metal) ZCU102 Cortex-R5 = Zephyr based Remote/Device

Let me know if you need further information on this topic and I will be happy to assist.

wmamills commented 3 months ago

@tnmysh Please talk to @bentheredonethat on how we could test this on Zynqmp with current OS releases