soc/intel_adsp: Minimize bootloader linker script

The memory layout for the boot loader was needlessly complicated, with
separate fixed regions defined at fixed addresses, all in a file that
needs to be contiguous and DMA'd from the host in a single block.  The
end result was a lot of magic numbers and wasted space.

Clean things up so that it links in a single region expressed (for the
benefit of rimage, I think) as a single program header in the ELF
file.

This is in preparation for further changes to unify the bootloader
stage with the main Zephyr image in a single link.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2021-11-28 11:28:30 -08:00 committed by Anas Nashif
parent 1e1830de95
commit a42da8dcdb
2 changed files with 64 additions and 150 deletions

View File

@ -1,65 +1,38 @@
OUTPUT_ARCH(xtensa)
ENTRY(boot_entry)
#include <autoconf.h> /* Not a "zephyr" file, need this explicitly */
#include <cavs-mem.h>
PROVIDE(__memctl_default = 0x00000000);
PROVIDE(_MemErrorHandler = 0x00000000);
MEMORY
{
boot_entry_text :
org = IMR_BOOT_LDR_TEXT_ENTRY_BASE,
len = IMR_BOOT_LDR_TEXT_ENTRY_SIZE
boot_entry_lit :
org = IMR_BOOT_LDR_LIT_BASE,
len = IMR_BOOT_LDR_LIT_SIZE
sof_text :
org = IMR_BOOT_LDR_TEXT_BASE,
len = IMR_BOOT_LDR_TEXT_SIZE,
sof_data :
org = IMR_BOOT_LDR_DATA_BASE,
len = IMR_BOOT_LDR_DATA_SIZE
sof_bss_data :
org = IMR_BOOT_LDR_BSS_BASE,
len = IMR_BOOT_LDR_BSS_SIZE
sof_stack :
org = BOOT_LDR_STACK_BASE,
len = BOOT_LDR_STACK_SIZE
wnd0 :
org = HP_SRAM_WIN0_BASE,
len = HP_SRAM_WIN0_SIZE
/* Offset of the entry point from the manifest start in IMR. Magic
* number must be synchronized with the module and rimage configuration!
*/
#define ENTRY_POINT_OFF 0x6000
/* These are legacy; needed by xtensa arch bootstrap code, but not by the
* bootloader per se which isn't responsible for handling exception
* setup or region protection option configuration.
*/
PROVIDE(_memmap_vecbase_reset = 0xbe010000);
PROVIDE(_memmap_cacheattr_reset = 0xff42fff2);
MEMORY {
imr :
org = CONFIG_IMR_MANIFEST_ADDR + ENTRY_POINT_OFF,
len = 0x100000
}
PHDRS
{
boot_entry_text_phdr PT_LOAD;
boot_entry_lit_phdr PT_LOAD;
sof_text_phdr PT_LOAD;
sof_data_phdr PT_LOAD;
sof_bss_data_phdr PT_LOAD;
sof_stack_phdr PT_LOAD;
wnd0_phdr PT_LOAD;
PHDRS {
imr_phdr PT_LOAD;
}
ENTRY(boot_entry)
EXTERN(reset_vector)
SECTIONS
{
.boot_entry.text : ALIGN(4)
{
_boot_entry_text_start = ABSOLUTE(.);
SECTIONS {
.text : {
/* Entry point MUST be here per external configuration */
KEEP (*(.boot_entry.text))
_boot_entry_text_end = ABSOLUTE(.);
} >boot_entry_text :boot_entry_text_phdr
.boot_entry.literal : ALIGN(4)
{
_boot_entry_literal_start = ABSOLUTE(.);
*(.boot_entry.literal)
*(.literal .literal.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
_boot_entry_literal_end = ABSOLUTE(.);
} >boot_entry_lit :boot_entry_lit_phdr
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
@ -69,12 +42,9 @@ SECTIONS
*(.gnu.version)
KEEP (*(.ResetVector.text))
KEEP (*(.ResetHandler.text))
_text_end = ABSOLUTE(.);
_etext = .;
} >sof_text :sof_text_phdr
.rodata : ALIGN(4)
{
_rodata_start = ABSOLUTE(.);
} >imr :imr_phdr
.rodata : {
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
@ -100,42 +70,13 @@ SECTIONS
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
. = ALIGN(4);
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sof_data :sof_data_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sof_data :sof_data_phdr
.lit4 : ALIGN(4)
{
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
} >sof_data :sof_data_phdr
.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_bss_start = ABSOLUTE(.);
} >imr :imr_phdr
/* Note that bootloader ".bss" goes into the ELF program header as
* real data, that way we can be sure the ROM loader has cleared the
* memory.
*/
.bss : ALIGN(8) {
*(.dynsbss)
*(.sbss)
*(.sbss.*)
@ -149,18 +90,30 @@ SECTIONS
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} >sof_bss_data :sof_bss_data_phdr
_man = 0x1234567;
PROVIDE(_memmap_vecbase_reset = (((((((0xBE000000 + 0x8000) + 0x2000) + 0x800) + 0x800) + 0x1000) + 0x2000) + (0x1000 + 0x1000)));
_memmap_cacheattr_wbna_trapnull = 0xFF42FFF2;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull);
__stack = 0xBE000000 + (1 * 0x1000);
__wnd0 = ((((((0xBE000000 + 0x8000) + 0x2000) + 0x800) + 0x800) + 0x1000) + 0x2000);
__wnd0_size = (0x1000 + 0x1000);
.comment 0 : { *(.comment) }
} >imr :imr_phdr
/* The .data section comes last. This is because rimage seems to
* want this page-aligned or it will throw an error, not sure why
* since all the ROM cares about is a contiguous region.
*/
.data : ALIGN(4096) {
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
} >imr :imr_phdr
.comment 0 : { *(.comment) }
.debug 0 : { *(.debug) }
.debug_ranges 0 : { *(.debug_ranges) }
.line 0 : { *(.line) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
@ -177,38 +130,22 @@ SECTIONS
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.debug_ranges 0 : { *(.debug_ranges) }
.xtensa.info 0 : { *(.xtensa.info) }
.xt.insn 0 :
{
.xtensa.info 0 : { *(.xtensa.info) }
.xt.insn 0 : {
KEEP (*(.xt.insn))
KEEP (*(.gnu.linkonce.x.*))
}
.xt.prop 0 :
{
.xt.prop 0 : {
KEEP (*(.xt.prop))
KEEP (*(.xt.prop.*))
KEEP (*(.gnu.linkonce.prop.*))
}
.xt.lit 0 :
{
.xt.lit 0 : {
KEEP (*(.xt.lit))
KEEP (*(.xt.lit.*))
KEEP (*(.gnu.linkonce.p.*))
}
.xt.profile_range 0 :
{
KEEP (*(.xt.profile_range))
KEEP (*(.gnu.linkonce.profile_range.*))
}
.xt.profile_ranges 0 :
{
KEEP (*(.xt.profile_ranges))
KEEP (*(.gnu.linkonce.xt.profile_ranges.*))
}
.xt.profile_files 0 :
{
KEEP (*(.xt.profile_files))
KEEP (*(.gnu.linkonce.xt.profile_files.*))
.debug.xt.callgraph 0 : {
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
}

View File

@ -23,31 +23,8 @@
#define HP_SRAM_WIN3_BASE (L2_SRAM_BASE + CONFIG_ADSP_WIN3_OFFSET)
#define HP_SRAM_WIN3_SIZE 0x2000
/* IMR memory layout in the bootloader. Sort of needlessly complex to
* put all these sections in specific sized regions, it's all the same
* memory and the bootloader doesn't do any mapping or protection
* management
*/
#define IMR_BOOT_LDR_MANIFEST_BASE CONFIG_IMR_MANIFEST_ADDR
#define IMR_BOOT_LDR_DATA_BASE CONFIG_IMR_DATA_ADDR
#define IMR_BOOT_LDR_BSS_BASE 0xb0100000
#define IMR_BOOT_LDR_TEXT_ENTRY_SIZE 0x0120
#define IMR_BOOT_LDR_LIT_SIZE 0x0100
#define IMR_BOOT_LDR_TEXT_SIZE 0x1c00
#define IMR_BOOT_LDR_DATA_SIZE 0x1000
#define BOOT_LDR_STACK_SIZE 0x4000
#ifdef CONFIG_SOC_SERIES_INTEL_CAVS_V15
# define IMR_BOOT_LDR_BSS_SIZE 0x10000 /* (vestigial typo?) */
#else
# define IMR_BOOT_LDR_BSS_SIZE 0x1000
#endif
#define IMR_BOOT_LDR_TEXT_ENTRY_BASE (IMR_BOOT_LDR_MANIFEST_BASE + 0x6000)
#define IMR_BOOT_LDR_LIT_BASE (IMR_BOOT_LDR_TEXT_ENTRY_BASE + IMR_BOOT_LDR_TEXT_ENTRY_SIZE)
#define IMR_BOOT_LDR_TEXT_BASE (IMR_BOOT_LDR_LIT_BASE + IMR_BOOT_LDR_LIT_SIZE)
#define BOOT_LDR_STACK_BASE (L2_SRAM_BASE + L2_SRAM_SIZE - BOOT_LDR_STACK_SIZE)
/* These are fake section addresses used only in the linker scripts */
#define IDT_BASE (L2_SRAM_BASE + L2_SRAM_SIZE)