|
@@ -0,0 +1,147 @@
|
|
|
+/* -*- 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 = .;
|
|
|
+}
|