soc/intel_adsp: Unbreak xcc builds

Recent linker changes got ahead of the toolchain and started using
features not available in the binutils 2.23-based Xtensa toolchain.
Specifically:

+ The section arguments to objcopy don't accept wildcards.

+ It's not legal to have an ALLOC section emitted to a region outside
  a declared MEMORY space.  So various non-mapped sections populated
  by C structs have to be put somewhere with an explicit address.

+ The older linker won't automatically create an empty section just
  because you assigned to ".", so the Zephyr tests that lack a
  .fw_metadata section get rejected by rimage.  The fix here is a
  little clumsy: copy the section out of zephyr.elf into a
  (potentially-zero-length) temporary file, then add it back to
  main.mod as a final step.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2021-12-14 09:42:55 -08:00 committed by Maureen Helm
parent bc6abbc18b
commit 66e2ba130f
2 changed files with 38 additions and 11 deletions

View File

@ -22,6 +22,7 @@ target_link_libraries(INTEL_ADSP_COMMON INTERFACE intel_adsp_common)
set(ELF_FIX ${SOC_DIR}/${ARCH}/${SOC_FAMILY}/common/fix_elf_addrs.py)
set(KERNEL_REMAPPED ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_NAME}-remapped.elf)
set(EXTMAN ${CMAKE_BINARY_DIR}/zephyr/extman.bin)
# Generate rimage modules from the base kernel ELF file. Note the
# warning squashing on the objcopy steps. Binutils has a misfeature
@ -40,6 +41,13 @@ add_custom_target(
gen_modules ALL
DEPENDS ${ZEPHYR_FINAL_EXECUTABLE}
# The .fw_metadata section may not be present (xcc's older linker
# will remove it if empty). Extract it here (which will create an
# empty file if not present) and add it back when we generate the
# main.mod file below.
COMMAND ${CMAKE_OBJCOPY} -O binary --only-section=.fw_metadata
${CMAKE_BINARY_DIR}/zephyr/${KERNEL_NAME}.elf ${EXTMAN}
# Remap uncached section addresses so they appear contiguous
COMMAND ${CMAKE_COMMAND} -E
copy ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_NAME}.elf ${KERNEL_REMAPPED}
@ -48,19 +56,29 @@ add_custom_target(
# Extract modules for rimage
COMMAND ${CMAKE_OBJCOPY}
--only-section .imr*
--only-section .imr
--only-section .imrdata
--only-section .module.boot
--set-section-flags .module.boot=noload,readonly
--rename-section .module.boot=.module
${KERNEL_REMAPPED} ${CMAKE_BINARY_DIR}/zephyr/boot.mod 2>/dev/null
# Remove .fw_metadata here...
COMMAND ${CMAKE_OBJCOPY}
--remove-section .imr*
--remove-section .imr
--remove-section .imrdata
--remove-section .module.boot
--remove-section .fw_metadata
--set-section-flags .module.main=noload,readonly
--set-section-flags .static_uuid_entries=noload,readonly
--set-section-flags .static_log_entries=noload,readonly
--set-section-flags .fw_metadata=noload,readonly
--rename-section .module.main=.module
${KERNEL_REMAPPED} ${CMAKE_BINARY_DIR}/zephyr/main.mod 2>/dev/null
${KERNEL_REMAPPED} ${CMAKE_BINARY_DIR}/zephyr/main.mod
# ...and copy it back in
COMMAND ${CMAKE_OBJCOPY}
--add-section .fw_metadata=${EXTMAN}
--set-section-flags .fw_metadata=noload,readonly
${CMAKE_BINARY_DIR}/zephyr/main.mod
${CMAKE_BINARY_DIR}/zephyr/main.mod
)

View File

@ -56,6 +56,13 @@ ENTRY(rom_entry);
#define IDT_BASE 0xe0000000
#define IDT_SIZE 0x2000
/* rimage module sections are C struct data, and thus flagged ALLOC.
* The xcc linker demands they be in a declared memory region even if
* the enclosing output section is (NOLOAD). Put them here.
*/
#define NOLOAD_BASE 0x20000
#define NOLOAD_SIZE 0x100000
MEMORY {
vector_memory_lit :
org = XCHAL_MEMERROR_VECTOR_PADDR + MEM_ERROR_LIT_SIZE,
@ -139,6 +146,9 @@ MEMORY {
lpram :
org = LP_SRAM_BASE,
len = LP_SRAM_SIZE
noload :
org = NOLOAD_BASE,
len = NOLOAD_SIZE
}
SECTIONS {
@ -432,30 +442,29 @@ SECTIONS {
. = SEGSTART_CACHED;
/* rimage module manifest headers */
.module.boot : { KEEP(*(.module.boot)) }
.module.main : { KEEP(*(.module.main)) }
.module.boot : { KEEP(*(.module.boot)) } >noload
.module.main : { KEEP(*(.module.main)) } >noload
.static_uuid_entries : {
*(*.static_uuids)
}
} >noload
.static_log_entries : {
*(*.static_log*)
}
} >noload
/* This is the "extended manifest" data (mostly versioning stuff)
* emitted by SOF and inspected by the kernel driver. It doesn't
* appear directly in the image, but rimage will parse and repack
* this into the output file header, so requires this be present
* even if empty. Assignment to "." forces this section to be
* created. Alignment and padding to 16 bytes is required,
* even if empty. Alignment and padding to 16 bytes is required,
* otherwise rimage will complain about the size being wrong (which
* sounds like a struct should be declared packed somewhere...)
*/
.fw_metadata : ALIGN(16) {
KEEP (*(.fw_metadata))
. = ALIGN(16);
}
} >noload
#include <linker/debug-sections.ld>