Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7514925
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T00:38:22+00:00 2026-05-30T00:38:22+00:00

When building a gcc based bare metal mcu project you need to take care

  • 0

When building a gcc based bare metal mcu project you need to take care of the initialization of the .data and .bss sections during startup.

The .bss section is quite easy since I just fill the entire section to 0.
But variables in the .data section needs to have their initialization data in rom/flash and copied during startup.

How do I know where the data with the initialization values can be found?

Let’s take a example.

Let’s say that I create two global variables in main.c

unsigned int my_global_variable_one  = 1;
unsigned int my_global_variable_two  = 2;

Then I can use objdump on the object file to see in what section they will be in,
but I can’t find anything in the objdump out put where the init data should be placed.

$ arm-none-eabi-objdump --syms main.o | grep my_global_variable
00000000 g     O .data  00000004 my_global_variable_one
00000004 g     O .data  00000004 my_global_variable_two

Then I can look at the resulting elf for the entire system, in this case main.elf.

$ arm-none-eabi-nm -n main.elf | grep my_global_variable
20000000 D my_global_variable_one
20000004 D my_global_variable_two

Where can I find where they are so I can do copy the data?
What do I need to put into my linker script?

It should be in something like .text or .rodata, but how do I know?

How can I check where the init data for my_global_variable_one is?

Can I find where this data is with any of the binutils commands like readelf or objdump?

/Thanks


This is on a stm32 (Cortex M3) mcu, and the CodeBench version of gcc is used.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T00:38:23+00:00Added an answer on May 30, 2026 at 12:38 am

    The compiler puts all code and some read-only data in the .text section. There may also be a .rodata section. You can have your linker script put that in a ROM address something like this:

    . = <rom-base-address>;
    .rodata : { *(.rodata) }
    <other read-only sections go here>
    .text   : { *(.text) }
    

    The compiler puts all the initial values of writable data in the .data section, and all symbols that don’t have an initial value in .bss. The .bss is easy, you just place that in RAM. The .data wants to be in RAM at run time, but in ROM at load-time, and the linker script lets you do that with the AT keyword:

    . = <ram-base-address>;
    .bss  : { *(.bss) }
    .data : AT ( ADDR (.text) + SIZEOF (.text) )
            { *(.data) }
    

    This means that the data section now has a different LMA and VMA (Load Memory Address / Virtual Memory Address). Your program will expect to find the data at the VMA (the run-time address) but the data will actually exist at the LMA (you may have to teach your flasher to do this), which is right after the .text section.

    If you need to figure out where to copy to and from then you can create pointers in the linker script. So, modify the above example like this:

    .data : AT ( ADDR (.text) + SIZEOF (.text) )
            { _data_lma = LOADADDR(.data); _data_vma = .;
              *(.data);
              _data_size = SIZEOF (.data);}
    

    You can then do memcpy (_data_vma, _data_lma, _data_size) in your start-up code (although you might have to hand-code that in assembler?) Those symbols will appear to your program as constant globals that resolve at link time. So, in your assembler code you might have something like:

    _data_lma_k:
       .long _data_lma
    

    Then the number will be hard coded into the .text section. Of course, the assembler syntax might be different on your platform.

    For more information, see the linker manual here

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've been getting this undefined symbol building with this command line: $ gcc test.cpp
I have no trouble building 1.35.0, as well as 1.36.0 on the timesys arm-gcc
Building the same project (without any changes) produces binary different exe-files: some small regions
While building Qt and Qt-based software on windows, it seems important to set MINGWDIR
The following code, compiles fine MSVC, but when building GCC provides a lot of
I'm building a Python script to automate my build process, which invokes GCC using
I'm building a shared library with GCC 4.5.2 and Boost 1.46.1 (compiled with --build-type=complete
So, I'm building a custom backend for GCC for a processor. This processor has
So Im building GCC 4.6.0 in Cygwin, but I've hit a wall. I try
I am building an application based on distributed linear algebra using Trilinos , the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.