I have built the CodeSourcery ARM compiler (2008q3). I have a linker script for the STM32 with the following sections: MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K RAM (xrw): ORIGIN = 0x20000000, LENGTH = 20K } SECTIONS { .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) . = ALIGN(4); } >FLASH .text : { . = ALIGN(4); *(.text) *(.text.*) *(.rodata) *(.rodata*) . = ALIGN(4); _etext = .; } >FLASH .data : AT ( _etext ) { . = ALIGN(4); _sdata = .; *(.data) *(.data.*) . = ALIGN(4); _edata = .; } >RAM .bss : { . = ALIGN(4); _sbss = .; *(.bss) *(COMMON) . = ALIGN(4); _ebss = .; } >RAM } When I build my application, I create the binary image with arm-eabi-objcopy -O binary main.elf main.bin That creates a binary that is 400M in size. Presumably because (0x20000000-0x08000000) is about that size. The problem seems to occur when there is nothing in the .data section. Possibly because it is being thrown out by the linker. I found some stuff in the ld manual that suggests that, if I change the .data section to this: .data : AT ( _etext ) { . = ALIGN(4); _sdata = .; KEEP(*(.data)) KEEP(*(.data.*)) . = ALIGN(4); _edata = .; } >RAM all will be OK in the world. or, at least, my tiny part of it. Does that sound right? Is this the 'proper' thing to do? there is also mention of the --gc-sections option for the linker. Would it be simpler not to use this?
strangeness with objcopy and large binaries
Started by ●May 17, 2009
Reply by ●May 17, 20092009-05-17
On May 17, 1:51=A0pm, Peter Harrison <peter.harri...@helicron.net> wrote:> I have built the CodeSourcery ARM compiler (2008q3). I have a linker > script for the STM32 with the following sections: > > MEMORY { > =A0 =A0FLASH (rx) : ORIGIN =3D 0x08000000, LENGTH =3D 128K > =A0 =A0RAM =A0 (xrw): ORIGIN =3D 0x20000000, LENGTH =3D 20K} > > SECTIONS { > =A0 =A0 =A0 =A0 =A0.isr_vector : { > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0. =3D ALIGN(4); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0KEEP(*(.isr_vector)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0. =3D ALIGN(4); > =A0 =A0 =A0 =A0 =A0} >FLASH > =A0 =A0 =A0 =A0 =A0.text : { > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0. =3D ALIGN(4); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*(.text) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*(.text.*) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*(.rodata) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*(.rodata*) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0. =3D ALIGN(4); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0_etext =3D .; > =A0 =A0 =A0 =A0 =A0} >FLASH > =A0 =A0 =A0 =A0 =A0.data : AT ( _etext ) { > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0. =3D ALIGN(4); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0_sdata =3D .; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*(.data) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*(.data.*) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0. =3D ALIGN(4); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0_edata =3D .; > > =A0 =A0 =A0 =A0 =A0} >RAM > =A0 =A0 =A0 =A0 =A0.bss : { > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0. =3D ALIGN(4); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0_sbss =3D .; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*(.bss) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*(COMMON) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0. =3D ALIGN(4); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0_ebss =3D .; > =A0 =A0 =A0 =A0 =A0} >RAM > > } > > When I build my application, I create the binary image with > > arm-eabi-objcopy -O binary main.elf main.bin > > That creates a binary that is 400M in size. Presumably because > (0x20000000-0x08000000) is about that size. > > The problem seems to occur when there is nothing in the .data section. > Possibly because it is being thrown out by the linker. I found some > stuff in the ld manual that suggests that, if I change the .data section > to this: > > .data : AT ( _etext ) { > =A0 =A0. =3D ALIGN(4); > =A0 =A0_sdata =3D .; > =A0 =A0KEEP(*(.data)) > =A0 =A0KEEP(*(.data.*)) > =A0 =A0. =3D ALIGN(4); > =A0 =A0_edata =3D .; > =A0 =A0} >RAM > > all will be OK in the world. or, at least, my tiny part of it. > > Does that sound right? Is this the 'proper' thing to do? there is also > mention of the --gc-sections option for the linker. Would it be simpler > not to use this?Suggest you narrow it down a bit more with a few examples prior messing with the linker script, but... objcopy has at least one bug relating to internal accidental sign- extension converting to 64-bit addresses (which it uses internally), and CodeSourcery just fixed it (ask me how I know... ) When you've narrowed it down a bit perhaps best to submit a trouble ticket ! Hope that helps, Best Regards, Dave
Reply by ●May 18, 20092009-05-18
Peter Harrison wrote:> I have built the CodeSourcery ARM compiler (2008q3). I have a linker > script for the STM32 with the following sections: > > MEMORY { > FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K > RAM (xrw): ORIGIN = 0x20000000, LENGTH = 20K > } > SECTIONS { > .isr_vector : { > . = ALIGN(4); > KEEP(*(.isr_vector)) > . = ALIGN(4); > } >FLASH > .text : { > . = ALIGN(4); > *(.text) > *(.text.*) > *(.rodata) > *(.rodata*) > . = ALIGN(4); > _etext = .; > } >FLASH > .data : AT ( _etext ) { > . = ALIGN(4); > _sdata = .; > *(.data) > *(.data.*) > . = ALIGN(4); > _edata = .; > > } >RAM > .bss : { > . = ALIGN(4); > _sbss = .; > *(.bss) > *(COMMON) > . = ALIGN(4); > _ebss = .; > } >RAM > } > > When I build my application, I create the binary image with > > arm-eabi-objcopy -O binary main.elf main.bin > > That creates a binary that is 400M in size. Presumably because > (0x20000000-0x08000000) is about that size. > > The problem seems to occur when there is nothing in the .data section. > Possibly because it is being thrown out by the linker. I found some > stuff in the ld manual that suggests that, if I change the .data section > to this: > > .data : AT ( _etext ) { > . = ALIGN(4); > _sdata = .; > KEEP(*(.data)) > KEEP(*(.data.*)) > . = ALIGN(4); > _edata = .; > } >RAM > > all will be OK in the world. or, at least, my tiny part of it. > > Does that sound right? Is this the 'proper' thing to do? there is also > mention of the --gc-sections option for the linker. Would it be simpler > not to use this?Have you had a look at your map file to see if there is anything in .data, or .bss? It might also be as simple as objcopy doing exactly what you asked it to do - copying all the sections to a .bin file. When using objcopy, I typically have flags such as "-j .text -j .data" to specify the sections I want copied - other sections, such as .bss, are then dropped during the copy.
Reply by ●May 18, 20092009-05-18
David Brown wrote:> Peter Harrison wrote:>> >> When I build my application, I create the binary image with >> >> arm-eabi-objcopy -O binary main.elf main.bin >> >> That creates a binary that is 400M in size. Presumably because >> (0x20000000-0x08000000) is about that size. >> >> The problem seems to occur when there is nothing in the .data section. >> Possibly because it is being thrown out by the linker. I found some >> stuff in the ld manual that suggests that, if I change the .data >> section to this: >> >> .data : AT ( _etext ) { >> . = ALIGN(4); >> _sdata = .; >> KEEP(*(.data)) >> KEEP(*(.data.*)) >> . = ALIGN(4); >> _edata = .; >> } >RAM >> >> all will be OK in the world. or, at least, my tiny part of it. >> >> Does that sound right? Is this the 'proper' thing to do? there is also >> mention of the --gc-sections option for the linker. Would it be >> simpler not to use this? > > Have you had a look at your map file to see if there is anything in > .data, or .bss? It might also be as simple as objcopy doing exactly > what you asked it to do - copying all the sections to a .bin file. When > using objcopy, I typically have flags such as "-j .text -j .data" to > specify the sections I want copied - other sections, such as .bss, are > then dropped during the copy.I have tried that and asking for specific sections seems to work but I worry that the startup values for initialised data would not be included as they seem not to have an LMA that follows on in the .text section. Without the KEEP() directive, the .data section is otherwise empty. That is when I get trouble. If there is stuff in the .data section, it all works as advertised. Presumably because the garbage collection is not throwing out the empty .data section.
Reply by ●May 18, 20092009-05-18
Peter Harrison wrote:> David Brown wrote: >> Peter Harrison wrote: > >>> >>> When I build my application, I create the binary image with >>> >>> arm-eabi-objcopy -O binary main.elf main.bin >>> >>> That creates a binary that is 400M in size. Presumably because >>> (0x20000000-0x08000000) is about that size. >>> >>> The problem seems to occur when there is nothing in the .data >>> section. Possibly because it is being thrown out by the linker. I >>> found some stuff in the ld manual that suggests that, if I change the >>> .data section to this: >>> >>> .data : AT ( _etext ) { >>> . = ALIGN(4); >>> _sdata = .; >>> KEEP(*(.data)) >>> KEEP(*(.data.*)) >>> . = ALIGN(4); >>> _edata = .; >>> } >RAM >>> >>> all will be OK in the world. or, at least, my tiny part of it. >>> >>> Does that sound right? Is this the 'proper' thing to do? there is >>> also mention of the --gc-sections option for the linker. Would it be >>> simpler not to use this? >> >> Have you had a look at your map file to see if there is anything in >> .data, or .bss? It might also be as simple as objcopy doing exactly >> what you asked it to do - copying all the sections to a .bin file. >> When using objcopy, I typically have flags such as "-j .text -j .data" >> to specify the sections I want copied - other sections, such as .bss, >> are then dropped during the copy. > > I have tried that and asking for specific sections seems to work but I > worry that the startup values for initialised data would not be included > as they seem not to have an LMA that follows on in the .text section. > > Without the KEEP() directive, the .data section is otherwise empty. That > is when I get trouble. If there is stuff in the .data section, it all > works as advertised. Presumably because the garbage collection is not > throwing out the empty .data section.The C startup code has a loop that will read through the flash copy of the initial data and copy it to its address in RAM. If you have no .data section, perhaps the linker ends up using some sort of default addresses for some of the symbols used in the startup code.