MEMORY { VEC : ORIGIN = 0x00, LENGTH = 0x04 /* 0x00000 - 0x00003 */ IVEC : ORIGIN = 0x04, LENGTH = 0x80 - 0x04 /* 0x00004 - 0x0007F */ CALLT0 : ORIGIN = 0x80, LENGTH = 0x40 /* 0x00080 = 0x000BF */ OPT : ORIGIN = 0xC0, LENGTH = 0x04 /* 0x000C0 - 0x000C3 */ SEC_ID : ORIGIN = 0xC4, LENGTH = 0x0A /* 0x000C4 - 0x000CD */ OCDSTAD : ORIGIN = 0xCE, LENGTH = 0xA0 /* 0x000CE - 0x000D7 CA78K0R on chip debugging */ OCDROM : ORIGIN = 0x3E00, LENGTH = 0x200 /* 0x03E00 - 0x03FFF CA78K0R on chip debugging */ ROM : ORIGIN = 0xD8, LENGTH = 0x3E00 -0xD8 /* 0x000D8 - 0x03DFF */ MIRROR : ORIGIN = 0xF2000, LENGTH = 0x2000 /* 0xF2000 - 0xF3FFF */ SADDR : ORIGIN = 0xFFE20, LENGTH = 0x0100 /* 0xFFE20 - 0xFFF1F */ SELFRAM : ORIGIN = 0xFF900, LENGTH = 136 RAM : ORIGIN = 0xFF988, LENGTH = 0xFFE20 -0xFF988 /* 0xFF988 - 0xFFE1F */ } EXTERN(_Option_Bytes _Security_Id _Debug_Monitor _HardwareVectors _Vectors) SECTIONS { .vec 0x0: AT(0x0) { KEEP(*(.vec)) } > VEC .vects 0x4: AT(0x4) { KEEP(*(.vects)) } > IVEC .callt0 0x80 : AT(0x80) { . = ALIGN(2); KEEP(*(.callt0)) } > CALLT0 .option_byte 0xC0 : AT(0xC0) { KEEP(*(.option_bytes)) } > OPT .security_id 0xC4: AT(0xC4) { KEEP(*(.security_id)) } > SEC_ID .debug_monitor 0xCE : AT(0xCE) { KEEP(*(.debug_monitor)) } > OCDSTAD .lowtext 0xD8: AT(0xD8) { *(.plt) *(.lowtext) } > ROM __mdata = .; .init : { KEEP(*(.init)) } > ROM .fini : { KEEP(*(.fini)) } > ROM PROVIDE(__rodata_limit = CONSTANT(MIRRORAREASTART)+0x2000 + LENGTH(MIRROR)); /* The rodata section is placed in MIRROR area in order to access as near addressing. */ .rodata MAX(., (CONSTANT(MIRRORAREASTART)+0x2000)): { . = ALIGN(2); __rodata = .; *(.rodata) *(.rodata.*) . = ALIGN(2); *(.const) *(.const.*) . = ALIGN(2); PROVIDE(__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE(__init_array_end = .); PROVIDE(__fini_array_start = .); KEEP(*(.fini_array)) KEEP(*(SORT(.fini_array.*))) PROVIDE(__fini_array_end = .); __erodata = .; /*The rodata section is copied into the MIRROR area, that is why we check if the start and end addresses for rodata are less then _rodata_limit*/ ASSERT((SIZEOF (.rodata) == 0) || (__rodata < __rodata_limit), "Error: rodata section start address is too large. Move the text section after the rodata section to ensure that correct data is added to the MIRROR area."); ASSERT((SIZEOF (.rodata) == 0) || (__erodata <= __rodata_limit), "Error: rodata section size exceeds length of the MIRROR area."); }>ROM .text (. + __romdatacopysize) : { . = ALIGN(2); *(mfdl) . = ALIGN(2); *(PFDL_COD) *(PFDL_COD.*) . = ALIGN(2); *(.text) *(.text.*) /*INPUT_SECTION_FLAGS(SHF_EXECINSTR) *(*_n)*/ } >ROM AT>ROM .textf : { *(.textf) *(.textf.*) /*INPUT_SECTION_FLAGS(SHF_EXECINSTR) *(*_f)*/ }>ROM .frodata : { . = ALIGN(2); __frodata = .; *(.frodata) *(.frodata.*) __efrodata = .; . = ALIGN(2); __constf = .; *(.constf) *(.constf.*) __econstf = .; } >ROM .eh_frame_hdr : { KEEP(*(.eh_frame_hdr)) } > ROM .eh_frame : { KEEP(*(.eh_frame)) } > ROM .data 0xFFC8A : AT(__mdata) { . = ALIGN(2); PROVIDE (__datastart = .); __data = .; *(.data) *(.data.*) . = ALIGN(2); /*INPUT_SECTION_FLAGS(!SHF_EXECINSTR, SHF_WRITE, SHF_ALLOC) *(*_n)*/ __edata = .; } >RAM PROVIDE(__romdatastart = LOADADDR(.data)); PROVIDE (__romdatacopysize = SIZEOF(.data)); .dataf : { . = ALIGN(2); PROVIDE (__datafstart = .); . = ALIGN(2); *(.dataf) *(.dataf.*) /*INPUT_SECTION_FLAGS(!SHF_EXECINSTR, SHF_WRITE, SHF_ALLOC) *(*_f)*/ . = ALIGN(2); PROVIDE (__datafend = .); } > RAM AT> ROM PROVIDE(__romdatafstart = LOADADDR(.dataf)); PROVIDE (__romdatafcopysize = SIZEOF(.dataf)); .sdata : { . = ALIGN(2); PROVIDE (__sdatastart = .); *(.sdata) *(.sdata.*) . = ALIGN(2); PROVIDE (__sdataend = .); } > SADDR AT> ROM /* Note that crt0 assumes this is a multiple of two; all the start/stop symbols are also assumed word-aligned. */ PROVIDE(__romsdatastart = LOADADDR(.sdata)); PROVIDE (__romsdatacopysize = SIZEOF(.sdata)); .saddr : { . = ALIGN(2); PROVIDE (__saddrstart = .); *(.saddr) . = ALIGN(2); } >SADDR AT>ROM PROVIDE(__romsaddrstart = LOADADDR(.saddr)); PROVIDE (__romsaddrcopysize = SIZEOF(.saddr)); .sbss : { PROVIDE(__sbssstart = .); . = ALIGN(2); __sbss = .; *(.sbss) *(.sbss.*) /*INPUT_SECTION_FLAGS(!SHF_EXECINSTR, SHF_WRITE, SHF_ALLOC) *(*_s)*/ . = ALIGN(2); *(.sbss_bit) . = ALIGN(2); __esbss = .; } >SADDR AT>SADDR PROVIDE(__sbsssize = SIZEOF(.sbss)); .bss : { PROVIDE(__bssstart = .); . = ALIGN(2); __bss = .; *(.bss) *(.bss.*) . = ALIGN(2); *(.bss_bit) . = ALIGN(2); *(COMMON) . = ALIGN(2); __ebss = .; } >RAM AT>RAM PROVIDE(__bsssize = SIZEOF(.bss)); .bssf (NOLOAD): { PROVIDE(__bssfstart = .); . = ALIGN(2); *(.bssf) *(.bssf.*) /*INPUT_SECTION_FLAGS(!SHF_EXECINSTR, SHF_WRITE, SHF_ALLOC) *(*_f)*/ . = ALIGN(128); __end = .; } >RAM AT>RAM PROVIDE(__bssfsize = SIZEOF(.bssf)); PROVIDE(__stack_size = 0x64); .stack 0xFFE20 (NOLOAD) : AT(0xFFE20) { PROVIDE(__stack = .); ASSERT((__stack > (__end + __stack_size)), "Error: Too much data - no room left for the stack"); } >RAM /DISCARD/ : { *(.note) *(.note.*) *(.gnu.warning*) } }