/* -*- ld-script -*- * * Linker script for MAX80 firmware */ #include "sys.h" OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") OUTPUT_ARCH(riscv) ENTRY(_start) MEMORY { SRAM : org = SRAM_ADDR, len = SRAM_SIZE DRAM : org = SDRAM_ADDR, len = SDRAM_SIZE } SECTIONS { /* * Sections we do not need. This program cannot exit, so * fini/destructors are never needed. Exception handling * is not supported. */ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.discard) *(.discard.*) *(.dtors.*) *(.dtors) *(.fini_array) *(.fini_array.*) *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) *(.eh_frame) *(.eh_frame.*) *(.gcc_except_table .gcc_except_table.*) *(.gnu_extab*) *(.exception_ranges*) *crtbegin.o(*) } PROVIDE (__executable_start = _PC_RESET); .init.reset _PC_RESET : ALIGN(4) { PROVIDE (___reset = .); KEEP (*(SORT_NONE(.init.reset))) } >SRAM .init.irq _PC_IRQ : ALIGN(4) { PROVIDE (___irq = .); KEEP (*(SORT_NONE(.init.irq))) } .text : ALIGN(4) { KEEP (*(SORT_NONE(.init))) *(.text.unlikely .text.*_unlikely .text.unlikely.*) *(.text.exit .text.exit.*) *(.text.startup .text.startup.*) *(.text.hot .text.hot.*) *(SORT(.text.sorted.*)) *(.text .stub .text.* .gnu.linkonce.t.*) /* .gnu.warning sections are handled specially by elf.em. */ *(.gnu.warning) } PROVIDE (__etext = .); PROVIDE (_etext = .); . = ALIGN(4); .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } /* Thread Local Storage sections */ .tdata : { PROVIDE_HIDDEN (__tdata_start = .); *(.tdata .tdata.* .gnu.linkonce.td.*) } .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); } .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); } /* Are these necessary/supportable? */ .jcr : { KEEP (*(.jcr)) } .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } .data : { __DATA_BEGIN__ = .; *(.data .data.* .gnu.linkonce.d.*) SORT(CONSTRUCTORS) } .data1 : { *(.data1) } /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ .sdata : { __SDATA_BEGIN__ = .; *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) *(.sdata .sdata.* .gnu.linkonce.s.*) } _edata = .; . = ALIGN(16); __bss_start = .; .sbss : { *(.dynsbss) *(.sbss .sbss.* .gnu.linkonce.sb.*) *(.scommon) } .bss : { *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) /* Align here to ensure that the .bss section occupies space up to _end. Align after .bss to ensure correct alignment even if the .bss section disappears because there are no input sections. FIXME: Why do we need it? When there is no .bss section, we do not pad the .data section. */ . = ALIGN(16); } . = SEGMENT_START("ldata-segment", .); . = ALIGN(16); __BSS_END__ = .; .stack STACK_BOTTOM : { KEEP (*(.stack)) } __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800)); _end = .; }