How to initialize the bss section

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to initialize the bss section

3,260 Views
Armageddon
Contributor I

Hello,

I use a MKV56F1M0VLQ24 and I want to understand how the memory is initlialized with the linker script file.

I have 2 projects that have each a linker script file and are each loaded in a separate area of the flash.

My problem is that the bss section (which contains the uninitialized variables) has random values at the start of my program. But it is a RAM so if I turn off and on my card, I should not have any values ?

I even tried to add a FILL(0x00) line in the bss section and I don't feel like it changes.

Can someone explain to me how this file works and the memory initialization?

Thanks for help !

0 Kudos
9 Replies

3,128 Views
eden60
Contributor I

The BSS section is a part of the memory where uninitialized global and static variables are stored. During the program's initialization, the BSS section is set to zero. However, it is up to the program to ensure that the BSS section is initialized correctly.

In the linker script file, the BSS section is typically defined using a statement like this:

 

.bss :
{
   __bss_start__ = .;
   *(.bss)
   *(COMMON)
   __bss_end__ = .;
} > RAM

 

This statement defines the BSS section and places it in the RAM memory region. The *(.bss) directive tells the linker to include all sections with the .bss name in the BSS section. The *(COMMON) directive tells the linker to include any common symbols in the BSS section.

To initialize the BSS section to zero, the program's startup code should set all BSS section memory locations to zero before the program starts executing. This can be achieved by adding code to the startup routine to loop through the BSS section and set each memory location to zero.

If your BSS section is not being initialized to zero, it may be because the startup code is not properly initializing the BSS section. You should check the startup code to ensure that it correctly initializes the BSS section. You may also want to check the linker script to ensure that the BSS section is defined correctly and placed in the correct memory region.

In addition to the above, you should also ensure that your program does not accidentally write to the BSS section before it has been initialized. This can cause unpredictable behavior and should be avoided.

You can also visit : AWS Developer Course

 

0 Kudos

3,175 Views
Armageddon
Contributor I

Thanks for all your feedback!

My Bootloader does its job. My program #1 has its startup and I call the startup of program #2 during the init phase of my variables in program #1.

Once in cyclic operation, my program 1 calls the entry function of my program 2.

Is this the best method? I don't know but it works.

My issue is resolved, thanks again for your answers and suggestion!

0 Kudos

3,245 Views
ErichStyger
Senior Contributor V

Hi @Armageddon ,

see https://mcuoneclipse.com/2013/04/14/text-data-and-bss-code-and-data-size-explained/  and https://mcuoneclipse.com/2012/11/11/optimizing-the-kinetis-gcc-startup/.

And https://mcuoneclipse.com/2014/04/19/gnu-linker-can-you-not-initialize-my-variable/ about not initializing variables.

The .bss variables should be initialized in your startup code, so check what it is doing. The linker does not perform that initialization.

As for RAM values at power-up: this is usually undefined unless stated in a data sheet. My experience is that the values will be initialized with zero unless you are using some special kind of SRAM.

 

I hope this helps,

Erich

0 Kudos

3,233 Views
Armageddon
Contributor I

Thanks @ErichStyger 

 

Thanks for the links, I learned a lot about the different sections of a memory and I didn't know that there was a startup called before the "main".

The bss section is supposed to be initialized to 0 in the startup code but I would like to have your opinion on a situation.

 

I loaded 2 differents codes in the memory. My first code has all the files to run my chip including the crt0 (startup code).

My second program is a code generated on Simulink and has only the objective to be an algorithm and therefore does not have crt0.

This means that my program n°1 will initialize its memory correctly but will call the entry point of my program n°2 which has its own memory section and will have a bss section with random values.

My program can not have two crt0 ? How can I have the memory area of two different programs initialized correctly?

Should I modify the crt0 so that it takes into consideration my second program or should I create my own bss init in the second program?

Really thanks for your help !

0 Kudos

3,228 Views
ErichStyger
Senior Contributor V

I would say that the normal case is that you link with the linker both your application with the code from the Simulink blocks. The linker has the full memory map view, and will allocate things, and is aware of that second simulink block. That way you only need a single startup code which is both efficient and simple.

It is possible to have two (or more) different programs, each with its own startup code. The most prominent example for this is the bootloader+application example.

In that case the bootloader is initialized by its own startup code, and then jumps to the startup code of the main application. But for this you need to carefully defined the memory map, so they do not overlap.

I don't recommend that you go down that path, but if you like, here is some more on that topic:

https://mcuoneclipse.com/tag/bootloader/

I hope this helps,

Erich

0 Kudos

3,226 Views
Armageddon
Contributor I

Sorry if I didn't go into details but I am in the Bootloader + 2 applications scenario.
My Bootloader has the functionality to download a program from the UART link and jump to my program #1 if no program to download.

I only have the bootloader which has the startup code. The program n°1 is in charge of managing the low level functionality of the chip and the program n°2 is Simulink called in a cyclic way from the program n°1.
I hope it's clearer now.

Your first suggestion is interesting but it implies to reprogram each time I want to update one of my applications?

0 Kudos

3,218 Views
ErichStyger
Senior Contributor V

Yes, linking everything means you would need to update both.

Looks like the Bootloader way is the way to go for you.

0 Kudos

3,216 Views
Armageddon
Contributor I
I am not a very fan of this solution, I lose the interest of the bootloader which is to update my firmware.
But since I only need to initialize the memory, do I need the crt0 whose role is also to initialize interrupt, stack pointer and others. I have the impression that in my case it is useless since my system works as follows:
BOOT --> LOOP(PROG n°1 --> PROG n°2 -->)

So why would I repeat the runtime just for the memory init?
Is there any other use or could I just init my SRAM with a function in my "main" ?
0 Kudos

3,203 Views
bobpaddock
Senior Contributor III

"Is there any other use or could I just init my SRAM with a function in my "main" ?"

The C standard says BSS will be zeroed before main() starts.
Not doing that can open you up to some hard to find bugs.

This zeroing usually takes place in crt0.S or startup.c (or the name picked by your toolset), before main() is called.

Other things are also happening besides zeroing BSS such has initializing static variables, ie: moving initialized data from the .data section to RAM.

Trying to skip any of this is just going to cause issues at some point in the future.

A bootloader is usually its own standalone thing using its own resources.
The main application should not make any assumptions about the state of resources and should initialize things as if the bootloader did not exist.

If Flash space is limited it would be possible to have the linker place common code in a known location that can be shared between the application and the bootoader.  This is far from easy, even if it sounds like it should be.


 

 

0 Kudos