3

I am new to embedded systems low-level programming and I am quite confused what happens exactly after the linker generate an output object file and during flashing the .bin file.

1- I see in the linker script that the loadable memory address(LMA) and virtual memory address(VMA) of a .bss section is in RAM, my question is how does it initially go to RAM since I flash my binary image in FLASH memory?

2- The start up codes I saw only zero out the .bss section in RAM, but how did it even get there if the start-up code didn't copy it to RAM as it does with the .data section ?

artless noise
  • 21,212
  • 6
  • 68
  • 105
Keith Ape
  • 1,103
  • 1
  • 12
  • 28
  • You could answer that yourself by checking **which** variables go to `.bss` and which initial value they have. Not clear what your problem is. – too honest for this site Oct 28 '16 at 17:37
  • @Olaf I do understand that the .bss holds the uninitialized variables, but don't we still need a reference for the non-local variables that has zero value ? I mean do we actually flash the .bss section or do we just create a section filled with zeros in runtime ? – Keith Ape Oct 28 '16 at 17:48
  • "I do understand that the .bss holds the uninitialized variables" - No, it does not! You might want to read more about this. Note also this is nothing even mentioned in the standard per se and platform-dependent. – too honest for this site Oct 28 '16 at 18:02
  • @olaf " .bss or bss is used by many compilers and linkers for a part of the data segment containing statically-allocated variables represented solely by zero-valued bits initially (i.e., when execution begins). It is often referred to as the "bss section" or "bss segment". thats what I get online about what the .bss hold what do you mean by "no it does not" ? – Keith Ape Oct 28 '16 at 18:35
  • 1
    The `.bss` **section** is not part of the `.data` *section** in gcc, but a seperate `NOLOAD` section! Check your linker control file, read the ld-documentation. A segment is a different thing. "No it does not" - I cited the wrong assumption, not clear what you don't understand, but maybe you follow my advice and read the standard. Hint: Objects going into `.bss` for implementations which support it **are** initialised! In fact, you stated that yourself already. Well-meant: Sometimes it is a good thing to step back to see the whole picture. If you are too close you only see coloured dots. – too honest for this site Oct 28 '16 at 18:46
  • 1
    I think your question is [answered in the manual under output section LMA](https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html) near the bottom of the page. Usually you need some assembler start up code to copy *init data* to RAM, set up a stack and zero the BSS. Then you can call a minimal 'C' function. – artless noise Oct 31 '16 at 13:45
  • @user2628079 Most platforms contains startup code that zeroes out the bss section at runtime. But how or if at all that is done, is entirely platform specific. Remember also that in C, variables with static storage duration that are not explicitly initialized, is guaranteed to get their 0 value . By "uninitialized variables", perhaps you mean a global variable like `int foo;` , however that is exactly the same as `int foo = 0;` – nos Oct 31 '16 at 14:10

1 Answers1

3

It looks like the commenters largely answered your question, but putting this here for future folks who may come across the question:

What you're seeing here is an optimization. The .bss section by definition* is all 0's. While you could write a large array of zeros to flash and then copy the large array of zeros to ram on boot, why bother? All you really need to know is where the "relocated" array of 0's needs to end up. The linker file will usually define symbols named something like _sbss and _ebss (also commonly seen as _szero and _ezero). Now, the whole .bss section only takes up two words of memory in flash (the _sbss and _ebss symbols). Your startup routine (code that runs before main(), the same thing that copied the other data) can do something like memset(_sbss, 0, _ebss-_sbss) and the .bss section is set up and ready to go.

*in your, and most, modern environments .bss is defined to be all zeroes.

Pat
  • 1,882
  • 2
  • 15
  • 22