5

I successfully wrote a bare metal C program which is running on my STM32F4. It's nothing fancy, just the usual led-blinky-program. In this project I have written the initialization routines which is clearing the .bss section and initializing the .data section myself.

This wasn't really complicated. In the linker script, I just instructed the linker to create some symbols which are marking the start and the end of the .data and .bss section.

.data 0x20001000 :
    ALIGN(4)
    {
        __etext = LOADADDR(.data);
        __data_start__ = ADDR(.data) ;
        *(.data*) ;
        __data_end__ = ADDR(.data) + SIZEOF(.data) ;
    } >RAM AT>ROM


.bss :
    ALIGN(4)
    {
        __bss_start__ = ADDR(.bss) ;
        *(.bss*) ;
        __bss_end__ = ADDR(.bss) + SIZEOF(.bss) ;
    } >RAM

Then I was using these symbols in my code:

extern unsigned int __etext;
extern unsigned int __data_start__;
extern unsigned int __data_end__;
extern unsigned int __bss_start__;
extern unsigned int __bss_end__;


void Reset_Handler()
{
    unsigned int * src;
    unsigned int * dest;

    src = &__etext;
    dest = &__data_start__;

    /* copy .data */
    while (dest < &__data_end__)
        *(dest++) = *(src++);

    /* Zero bss.  */
    for (dest = &__bss_start__; dest < &__bss_end__; dest++)
        *dest = 0;
}

Now I would like to use the crt0 for the purpose of setting-up .bss and .data. (I heard setting up things is the main purpose of crt0.)

How can I do that? Is the basic principle of defining symbols in the linker script and using the in the code the same?


TL;DR

How can I use crt0 to setup my .bss and .data section?

Brian McFarland
  • 9,052
  • 6
  • 38
  • 56
Multisync
  • 767
  • 6
  • 25
  • 1
    Where did you get `crt0` from? – zwol Apr 09 '15 at 19:53
  • This question is highly hardware and compiler dependent. Fortunately your linker will probably tell you any symbols that should have been defined but were not. It's really unclear what problem you're having though - you need to expand your question with details. – mah Apr 09 '15 at 19:56
  • zwol: There are a couple of `crt0.o`s in my `gcc-arm-none-eabi` compiler: https://launchpad.net/gcc-arm-embedded – Multisync Apr 09 '15 at 19:56
  • It's still not clear what you're asking, but yes, those externs you show are defined by the linker, based on the linker configuration it's using and the objects it's linking. Your best bet here is probably to read that linker configuration and read the source to your crt0 (search for a crt0.s). Your recent edit shows the variables being defined in your linker script. What's not clear from your paste but probably is from the rest of the script is that the linked objects have data and text sections that the sizes come from. – mah Apr 09 '15 at 20:13
  • mah: What exactly is still unclear? All the tutorials I have read so far are mentioning, that some of the things `crt0` is resposible for is, besides other things, setting up `.bss` and `.data`. Now I finally want to take use of this. Until now I have set up those sections myself. This is futile, as crt0 could supposedly take care of this anyway. Hene, theres no sense in doing this myself. I just don't know how to utilize crt0. How does crt0 know the size/position of those sections? – Multisync Apr 09 '15 at 20:17
  • Are you familiar with the STM32 Standard Peripheral Library? It contains a significant amount of hardware-specific initialization code which you probably want to use here instead of the newlib crt0. –  Apr 09 '15 at 20:24
  • 1
    duskwuff: Yes, I know the STM32 Standard Peripheral Library. For educational purposes I was replacing the provided `startup.s` with my own code. Now, again for educational purposes, I would like to utilize `crt0` for the same purpose. – Multisync Apr 09 '15 at 20:27
  • From what you've explained so far, I think all you have to do is NOT specify `-nostartfiles` on your GCC command line. I.e. I think you'll get a crt0.o linked in by default unless you specify otherwise. – Brian McFarland Apr 09 '15 at 20:32
  • @BrianMcFarland: But how does `crt0` know where my sections start and end? – Multisync Apr 10 '15 at 06:09
  • 1
    @Multisync I think crt0 is merely the same for the routines doing what your code already does. I don't think it is implemented in some standard way, crt0 is just a name for all the code that is executed before main is called. In addition to initializing .data and .bss you might also have to set up the stack and MMU registers, which needs to be done the first thing you do after reset. Just look at the pre-made code that comes with your compiler and re-use whatever parts of it that are relevant. – Lundin Apr 10 '15 at 09:03

1 Answers1

1

in general, in a linker command file/script...

The posted script has a few problems.

Suggest something similar to the following. (use the actual origin and length parameters) (note that .text, .data, .bss are not the only sections created. there are many more and they should be listed appropriately )

You should look at http://www.math.utah.edu/docs/info/ld_3.html#SEC18 for the details and examples for linker command files

/* this is a very simple memory layout */
/* usually there are separate memory items */
/* for each memory mapped peripheral */
/* external RAM, etc etc etc */
MEMORY {
    rom : ORIGIN = 0, LENGTH = 256K
    ram : ORIGIN = 0x40000000, LENGTH = 4M
}

SECTIONS {
    rom :0 (NOLOAD) BLOCK(4) {
    }

    ram : {
        .text : BLOCK(4) {
        .textStart = .;
        *(.text)
        .textEnd = .;
        }

        .bss : BLOCK(4) {
        .bssStart = .;
        *(.bss)
        .bssEnd = .;
        }

        .data : BLOCK(4) {
        .dataStart = .;
        *(.data)
        .dataEnd = .;
        }
    }
}
user3629249
  • 16,402
  • 1
  • 16
  • 17