Tips for creating a linker script

In short. I want to learn how to create a good script builder so that I can change platforms / architectures / providers, I again don’t get stuck in the ground zero, not knowing what to do. I am not interested in the complexity of the task, as well as understanding this.

I started a kind of project to create a base or skeleton for programming and development on STM 32-bit Cortex-M3. Using jsiei97 Starting with STM32F103RB (I also have TI Stellaris LM3S828, but this is another problem), without the need for a licensed IDE. Since I am a student, and most students cannot afford such things.

I understand that there are ODev and Eclipse plugins and what not, and have read various blogs, wikis, documents / man pages and most of the projects provided you with a script linker to find out a little why and where things were defined.

I compiled the arm-none-eabi toolchain for STM32, but where I hung up is in the script linker. CodeSourcery also requires it. I have a basic concept of creating and syntax after reading gnu man pages, but I just don’t know where to start by adding various additional sections besides the obvious .text, .bss and .data,

I created a rudimentary version , but I get link errors that require the definition of partitions and where I got stuck. I know how to define them, but knowing what I'm doing is even close to the point - a problem.

+6
source share
2 answers

I have a simple script linker that I regularly use on different platforms, just change some addresses as needed.

http://github.com/dwelch67/

There are many samples with gcc samples, and most of them have linker scripts.

MEMORY { rom : ORIGIN = 0x00000000, LENGTH = 0x40000 ram : ORIGIN = 0x10000000, LENGTH = 30K } SECTIONS { .text : { *(.text*) } > rom .bss : { *(.bss*) } > ram } 
+8
source

Here is the working script builder for STM32F105RB (there are also versions for R8 and RC):

https://github.com/anrope/stm-arp/blob/github/arp.rb.ld (text below)

My elite guesses that you have nothing to change. Perhaps this is the origin of the regions defined in the MEMORY {} statement. We hope you find the comments helpful.

I used this with the GNU / GCC cross-compiler that I was rolling around. After compilation, it is useful to run nm in your code to make sure that the partitions are located at the correct addresses.

Edit: I linked this linker script together using the GNU ld documentation:

http://sourceware.org/binutils/docs/ld/

and having examined the output of cross-compiling GCC with a standard script linker using nm . I basically determined all the sections that are displayed and figured out which ones are really useful, and where in memory they should go to STM32F105.

I took notes in the script builder for each section.

 /* arp.{r8,rb,rc}.ld : These linker scripts (one for each memory density of the stm32f105) are used by the linker to arrange program symbols and sections in memory. This is especially important for sections like the interrupt vector, which must be placed where the processor is hard-coded to look for it. */ /*stm32f105 dev board linker script*/ /* OUTPUT_FORMAT() defines the BFD (binary file descriptor) format OUTPUT_FORMAT(default, big, little) */ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") /* ENTRY() defines the symbol at which to begin executing code */ ENTRY(_start) /* tell ld where to look for archive libraries */ /*SEARCH_DIR("/home/arp/stm/ctc/arm-eabi/lib")*/ /*SEARCH_DIR("/home/arp/stm/ccbuild/method2/install/arm-eabi/lib")*/ SEARCH_DIR("/home/arp/stm32dev-root/usrlol/arm-eabi/lib") /* MEMORY{} defines the memory regions of the target device, and gives them an alias for use later in the linker script. */ /* stm32f105rb */ MEMORY { ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32k flash (rx) : ORIGIN = 0x08000000, LENGTH = 128k option_bytes_rom (rx) : ORIGIN = 0x1FFFF800, LENGTH = 16 } _sheap = _ebss + 4; _sstack = _ebss + 4; /*placed __stack_base__ trying to figure out global variable overwrite issue __stack_base__ = _ebss + 4;*/ _eheap = ORIGIN(ram) + LENGTH(ram) - 1; _estack = ORIGIN(ram) + LENGTH(ram) - 1; /* SECTIONS{} defines all the ELF sections we want to create */ SECTIONS { /* set . to an initial value (0 here). . (dot) is the location counter. New sections are placed at the location pointed to by the location counter, and the location counter is automatically moved ahead the length of the new section. It is important to maintain alignment (not handled automatically by the location counter). */ . = SEGMENT_START("text-segment", 0); /*isr_vector contains the interrupt vector. isr_vector is read only (could be write too?). isr_vector must appear at start of flash (USR), address 0x0800 0000*/ .isr_vector : { . = ALIGN(4); _sisr_vector = .; *(.isr_vector) _eisr_vector = .; } >flash /*text contains executable code. text is read and execute.*/ .text : { . = ALIGN(4); *(.text) . = ALIGN(4); *(.text.*) } >flash /*init contains constructor functions called before entering main. used by crt (?).*/ .init : { . = ALIGN(4); KEEP(*(.init)) } >flash /*fini contains destructor functions called after leaving main. used by crt (?).*/ .fini : { . = ALIGN(4); KEEP(*(.fini)) } >flash /* rodata contains read only data.*/ .rodata : { . = ALIGN(4); *(.rodata) /* sidata contains the initial values for variables in the data section. sidata is read only.*/ . = ALIGN(4); _sidata = .; } >flash /*data contains all initalized variables. data is read and write. .data (NOLOAD) : AT(_sidata)*/ .data : AT(_sidata) { . = ALIGN(4); _sdata = .; *(.data) _edata = .; } >ram /*bss contains unintialized variables. bss is read and write. .bss (NOLOAD) :*/ .bss : { . = ALIGN(4); _sbss = .; __bss_start__ = .; *(.bss) . = ALIGN(4); /*COMMON is a special section containing uninitialized data. Example: (declared globally) int temp; //this will appear in COMMON */ *(COMMON) _ebss = .; __bss_end__ = .; } >ram AT>flash . = ALIGN(4); end = .; /* remove the debugging information from the standard libraries */ DISCARD : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2 */ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } } 
+2
source

Source: https://habr.com/ru/post/906598/


All Articles