/* Specify the memory areas */ MEMORY { rom : ORIGIN = 0xBFC00000, LENGTH = 0x00002000 /* 8K */ ram : ORIGIN = 0x40000000, LENGTH = 0x04000000 /* 64M */ flash : ORIGIN = 0x00000000, LENGTH = 0x00800000 /* 8M */ io : ORIGIN = 0xA0000000, LENGTH = 0x00800000 /* 8M */ } STARTUP(startup.o) INPUT(kernel.o) DEBUGGER_VAR_SIZE = 0x10000; SECTIONS { .start ORIGIN(ram) : { start = .; entry = .; _entry = .; __entry = .; KEEP (*(.start)) } >ram .exc_vect ORIGIN(ram) + 0x80 : { KEEP (*(.exc_vect)) } >ram .init ALIGN(4) : { KEEP (*(.init)) } >ram .text ALIGN(4) : { *(.text) *(.text.*) } >ram .fini ALIGN(4) : { KEEP (*(.fini)) } >ram .rodata : { *(.rodata .rodata.*) } >ram .rodata1 : { *(.rodata1) } >ram .sdata2 : { *(.sdata2 .sdata2.*) } >ram .sbss2 : { *(.sbss2 .sbss2.*) } >ram .data : { *(.data .data.*) } >ram .data1 : { *(.data1) } >ram .got.plt : { *(.got.plt) } >ram . = ALIGN(4); _gp = ALIGN(16) + 0x7ff0; .got : { *(.got) } /* 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 .sdata.*) } >ram __bss_start = ALIGN(4); .sbss : { *(.sbss .sbss.*) *(.scommon) } >ram .bss : { *(.bss .bss.*) *(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 don't pad the .data section. */ . = ALIGN(. != 0 ? 32 / 8 : 1); } >ram . = ALIGN(32 / 8); _end = .; PROVIDE (end = .); . = (ORIGIN(ram) + LENGTH(ram) - DEBUGGER_VAR_SIZE - 0x10); stack_ptr = . | ~(LENGTH(ram)-1) & 0x7fffffff; . = . + 0x10; .dbg_vars . (NOLOAD) : { *(.dbg_vars) } }