diff --git a/port/moonlight/bootup.c b/port/moonlight/bootup.c index 88f4a86..d4f15f7 100644 --- a/port/moonlight/bootup.c +++ b/port/moonlight/bootup.c @@ -8,6 +8,7 @@ #include #include +#include #ifdef __cplusplus #define EXTERN_C extern "C" @@ -24,6 +25,12 @@ EXTERN_C uint8_t __bss_end; EXTERN_C const uint8_t __data_source; EXTERN_C uint8_t __data_start; EXTERN_C uint8_t __data_end; +EXTERN_C const uint8_t __data_source; +EXTERN_C uint8_t __tbss_start; +EXTERN_C uintptr_t __tbss_size; +EXTERN_C const uint8_t __tdata_source; +EXTERN_C uint8_t __tls_base; +EXTERN_C uintptr_t __tdata_size; EXTERN_C function_t __init_array_start; EXTERN_C function_t __init_array_end; @@ -32,10 +39,10 @@ EXTERN_C function_t __fini_array_end; // This function will be placed by the linker script according to the section // Raw function 'called' by the CPU with no runtime. -EXTERN_C void _start(void) __attribute__ ((naked,section(".text.init"))); +EXTERN_C void _start(void) __attribute__ ((naked,section(".text.boot"))); // Entry and exit points as C functions. -EXTERN_C void _initialize(void) __attribute__ ((noreturn,section(".init"))); +EXTERN_C void _initialize(void) __attribute__ ((noreturn,section(".text.boot"))); EXTERN_C void _exit(int exit_code) __attribute__ ((noreturn,noinline,weak)); // Standard entry point, no arguments. @@ -68,19 +75,22 @@ void _start(void) { void _initialize(void) { // Init memory regions // Clear the .bss section (global variables with no initial values) - memset((void*) &__bss_start, - 0, - (&__bss_end - &__bss_start)); + memset((void*) &__bss_start, 0, (&__bss_end - &__bss_start)); // Initialize the .data section (global variables with initial values) - memcpy((void*)&__data_start, - (const void*)&__data_source, - (&__data_end - &__data_end)); + memcpy((void*)&__data_start, (const void*)&__data_source, (&__data_end - &__data_start)); + // Clear the .tbss section (thread local variables with no initial values) + memset((void*) &__tbss_start, 0, __tbss_size); + // Initialize the .tls section (thread local variables with initial values) + memcpy((void*) &__tls_base, (const void*)&__tdata_source, __tdata_size); // Call constructors for (const function_t* entry=&__init_array_start; entry < &__init_array_end; ++entry) { (*entry)(); } +#ifdef __THREAD_LOCAL_STORAGE + _set_tls(__tls_base) +#endif int rc = main(); // Call destructors for (const function_t* entry=&__fini_array_start; diff --git a/port/threadx/src/tx_initialize_low_level.S b/port/threadx/src/tx_initialize_low_level.S index 4f8a776..558d705 100644 --- a/port/threadx/src/tx_initialize_low_level.S +++ b/port/threadx/src/tx_initialize_low_level.S @@ -135,12 +135,12 @@ trap_handler: */ .global _tx_initialize_low_level .weak _tx_initialize_low_level - .extern _end + .extern __heap_start .extern board_init _tx_initialize_low_level: STORE sp, _tx_thread_system_stack_ptr, t0 // Save system stack pointer - la t0, _end // Pickup first free address + la t0, __heap_start // Pickup first free address STORE t0, _tx_initialize_unused_memory, t1 // Save unused memory address li t0, MSTATUS_MIE csrrc zero, mstatus, t0 // clear MSTATUS_MIE bit diff --git a/src/flash.lds b/src/flash.lds index ecf3e89..94c5e1f 100644 --- a/src/flash.lds +++ b/src/flash.lds @@ -4,9 +4,9 @@ ENTRY( _start ) INCLUDE memory_map.ld -REGION_ALIAS("REGION_TEXT", flash); -REGION_ALIAS("REGION_RODATA", flash); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("LOCATION_TEXT", flash); +REGION_ALIAS("LOCATION_RODATA", flash); +REGION_ALIAS("LOCATION_DATA", ram); +REGION_ALIAS("LOCATION_STACK", ram); INCLUDE sections.ld \ No newline at end of file diff --git a/src/ram.lds b/src/ram.lds index d8158e5..2cec713 100644 --- a/src/ram.lds +++ b/src/ram.lds @@ -1,12 +1,12 @@ -OUTPUT_ARCH( "riscv" ) +OUTPUT_ARCH(riscv) -ENTRY( _start ) +ENTRY(_start) INCLUDE memory_map.ld -REGION_ALIAS("REGION_TEXT", ram); -REGION_ALIAS("REGION_RODATA", ram); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("LOCATION_TEXT", ram); +REGION_ALIAS("LOCATION_RODATA", ram); +REGION_ALIAS("LOCATION_DATA", ram); +REGION_ALIAS("LOCATION_STACK", ram); INCLUDE sections.ld \ No newline at end of file diff --git a/src/ram_dram.lds b/src/ram_dram.lds new file mode 100644 index 0000000..75842f0 --- /dev/null +++ b/src/ram_dram.lds @@ -0,0 +1,12 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +INCLUDE memory_map.ld + +REGION_ALIAS("LOCATION_TEXT", ram); +REGION_ALIAS("LOCATION_RODATA", ram); +REGION_ALIAS("LOCATION_DATA", dram); +REGION_ALIAS("LOCATION_STACK", dram); + +INCLUDE sections.ld \ No newline at end of file diff --git a/src/rom.lds b/src/rom.lds index b730a16..5e2d578 100644 --- a/src/rom.lds +++ b/src/rom.lds @@ -4,9 +4,9 @@ ENTRY( _start ) INCLUDE memory_map.ld -REGION_ALIAS("REGION_TEXT", rom); -REGION_ALIAS("REGION_RODATA", rom); -REGION_ALIAS("REGION_DATA", ram); -REGION_ALIAS("REGION_BSS", ram); +REGION_ALIAS("LOCATION_TEXT", rom); +REGION_ALIAS("LOCATION_RODATA", rom); +REGION_ALIAS("LOCATION_DATA", ram); +REGION_ALIAS("LOCATION_STACK", ram); INCLUDE sections.ld \ No newline at end of file diff --git a/src/sections.ld b/src/sections.ld index c87cea5..c731c49 100644 --- a/src/sections.ld +++ b/src/sections.ld @@ -1,184 +1,108 @@ PHDRS { - flash PT_LOAD; - ram_init PT_LOAD; - tls PT_TLS; - ram PT_NULL; - dram PT_NULL; + text PT_LOAD; + data PT_LOAD; + tls PT_TLS; + stack PT_NULL; } + SECTIONS { __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; __stack_segment_size = DEFINED(__stack_segment_size) ? __stack_segment_size : __stack_size; - .init ORIGIN(REGION_TEXT) : + + /* Code/Const in LOCATION_TEXT */ + . = ORIGIN(LOCATION_TEXT); + .text : ALIGN(4) { - KEEP (*(.text.init.enter)) - KEEP (*(.text.init.*)) - KEEP (*(.text.init)) - KEEP (*(SORT_NONE(.init))) - KEEP (*(.text.libgloss.start)) - } >REGION_TEXT AT>REGION_TEXT :flash - - .text : - { - *(.text.unlikely .text.unlikely.*) - *(.text.startup .text.startup.*) + KEEP(*(.text.boot)) *(.text .text.*) - *(.gnu.linkonce.t.*) - } >REGION_TEXT AT>REGION_TEXT :flash - - .fini : - { - KEEP (*(SORT_NONE(.fini))) - } >REGION_TEXT AT>REGION_TEXT :flash - - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - - .rodata : - { - *(.rdata) *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - } >REGION_RODATA AT>REGION_RODATA :flash - - .srodata : - { - *(.srodata.cst16) - *(.srodata.cst8) - *(.srodata.cst4) - *(.srodata.cst2) *(.srodata .srodata.*) - } >REGION_RODATA AT>REGION_RODATA :flash - - . = ALIGN(4); - - .preinit_array : + KEEP(*(.init)) + KEEP(*(.fini)) + } > LOCATION_TEXT :text + + /* trap/interrupt vectors */ + .vectors : ALIGN(256) { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >REGION_RODATA AT>REGION_RODATA :flash - - .init_array : + KEEP(*(.vectors .vectors.*)) + } > LOCATION_TEXT + + /* C++ ctors/dtors */ + .init_array : ALIGN(4) { - 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 = .); - } >REGION_RODATA AT>REGION_RODATA :flash + PROVIDE_HIDDEN(__init_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN(__init_array_end = .); + } > LOCATION_TEXT :text - .fini_array : + .fini_array : ALIGN(4) { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >REGION_RODATA AT>REGION_RODATA :flash + PROVIDE_HIDDEN(__fini_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN(__fini_array_end = .); + } > LOCATION_TEXT :text - .ctors : + /* .data in LOCATION_DATA, Load-Image in LOCATION_TEXT, PHDR is data */ + .data : ALIGN(4) { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - /* We don't want to include the .ctor section from - the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } >REGION_RODATA AT>REGION_RODATA :flash - - .dtors : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } >REGION_RODATA AT>REGION_RODATA :flash - - .lalign : - { - . = ALIGN(4); - PROVIDE( _data_lma = . ); - } >REGION_RODATA AT>REGION_RODATA :flash - - .data : ALIGN(4) - { - __DATA_BEGIN__ = .; + __data_start = .; *(.data .data.*) - *(.gnu.linkonce.d.*) - __SDATA_BEGIN__ = .; - *(.sdata .sdata.*) - *(.gnu.linkonce.s.*) - } >REGION_DATA AT>REGION_RODATA :ram_init + __data_end = .; + } > LOCATION_DATA AT> LOCATION_TEXT :data + __data_source = LOADADDR(.data); - .tdata : ALIGN(8) { - PROVIDE( __tls_base = . ); - *(.tdata .tdata.* .gnu.linkonce.td.*) - } >REGION_DATA AT>REGION_RODATA :tls :ram_init - - PROVIDE( __data_source = LOADADDR(.data) ); - PROVIDE( __data_start = ADDR(.data) ); - PROVIDE( __data_end = ADDR(.tdata) + SIZEOF(.tdata) ); - - PROVIDE( __tdata_source = LOADADDR(.tdata) ); - PROVIDE( __tdata_size = SIZEOF(.tdata) ); - - .tbss : ALIGN(8) { - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon .tcommon.*) - PROVIDE( __tls_end = . ); - } >REGION_DATA AT>REGION_DATA :tls :ram - - PROVIDE( __tbss_size = SIZEOF(.tbss) ); - PROVIDE( __tls_size = __tls_end - __tls_base ); - - .tbss_space : ALIGN(8) { - . = . + __tbss_size; - } >REGION_DATA :ram - - .bss : + /* TLS: in LOCATION_DATA, initial values are in LOCATION_TEXT, PHDR is tls */ + .tls : ALIGN(16) { - __BSS_BEGIN__ = .; - *(.sbss*) - *(.gnu.linkonce.sb.*) + /* TLS init data (.tdata) */ + __tls_base = .; + *(.tdata .tdata.* .gnu.linkonce.td.*) + __tdata_end = .; + __tdata_size = __tdata_end - __tls_base; + + /* TLS bss (.tbss) */ + __tbss_start = .; + *(.tbss .tbss.* .gnu.linkonce.tb.*) + __tbss_end = .; + __tbss_size = __tbss_end - __tbss_start; + + __tls_size = __tbss_end - __tls_base; + } > LOCATION_DATA AT> LOCATION_TEXT :tls + __tdata_source = LOADADDR(.tls); + + /* normales BSS (inkl. sbss), PHDR is data */ + .bss (NOLOAD) : ALIGN(16) + { + __bss_start = .; + *(.sbss .sbss.*) *(.bss .bss.*) - *(.gnu.linkonce.b.*) *(COMMON) - . = ALIGN(4); - __BSS_END__ = .; + __bss_end = .; + } > LOCATION_DATA :data - } >REGION_BSS AT>REGION_BSS :ram + __global_pointer$ = .; + + /* Heap/Stack Grenzen */ + . = ALIGN(16); + __heap_start = .; - PROVIDE( __bss_start = ADDR(.tbss) ); - PROVIDE( __bss_end = ADDR(.bss) + SIZEOF(.bss) ); - - __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800)); - PROVIDE( _end = . ); - PROVIDE( end = . ); - - .stack ORIGIN(ram) + LENGTH(ram) - __stack_segment_size : + /* __stack_top = ORIGIN(LOCATION_BSS) + LENGTH(LOCATION_BSS); */ + /* PROVIDE(_sp = __stack_top); */ + /* stack segement, PHDR is stack */ + .stack ORIGIN(LOCATION_STACK) + LENGTH(LOCATION_STACK) - __stack_segment_size : { PROVIDE( _heap_end = . ); . = __stack_segment_size; PROVIDE( _sp = . ); - } >REGION_BSS AT>REGION_BSS :ram + } >LOCATION_STACK AT>LOCATION_STACK :stack - - PROVIDE( tohost = . ); PROVIDE( fromhost = . + 8 ); + + /DISCARD/ : { *(.eh_frame*) *(.comment) *(.note .note.*) } }