mem_sections(3)
๐ธ mem_sections(3) โ Memory Sections ๐ธ
okay bestie, sit down, hydrate, because today we're talking about the mem_sections(3) page from avr-libc โ that's the manual page, section 3, library functions, and it's literally all about where your bytes go live in memory. ๐ This is the girlies' guide to sections, no cap.
๐ NAME ๐
mem_sections โ Memory Sections โจ
Remarks: Need to list all the sections which are available to the avr.
Weak Bindings: FIXME: need to discuss the .weak directive.
The following describes the various sections available.
๐ฆ The .text Section ๐ฆ
The .text section is where the actual machine instructions that make up your program live. Like, the real ones. The ones that actually run. This section is further subdivided by the .initN and .finiN sections dicussed below.
Note: Theavr-sizeprogram (part ofbinutils), coming from a Unix background, doesn't account for the.datainitialization space added to the.textsection, so in order to know how much flash the final program will consume, one needs to add the values for both,.textand.data(but not.bss), while the amount of pre-allocated SRAM is the sum of.dataand.bss. ๐งฎ so if your flash numbers look sus, that's why.
๐ The .data Section ๐
This section contains static data which was defined in your code. Things like the following would end up in .data:
char err_str[] = "Your program has died a horrible death!";
struct point pt = { 1, 1 };
It is possible to tell the linker the SRAM address of the beginning of the .data section. This is accomplished by adding -Wl,-Tdata,addr to the avr-gcc command used to the link your program. Not that addr must be offset by adding 0x800000 the to real SRAM address so that the linker knows that the address is in the SRAM memory space. Thus, if you want the .data section to start at 0x1100, pass 0x801100 at the address to the linker. [offset explained]
Note: When using malloc() in the application (which could even happen inside library calls), additional adjustments are required. ๐
๐ฆ The .bss Section ๐ฆ
Uninitialized global or static variables end up in the .bss section. that's it. that's the vibe. ๐
๐ง The .eeprom Section ๐ง
This is where eeprom variables are stored.
๐ The .noinit Section ๐
This sections is a part of the .bss section. What makes the .noinit section special is that variables which are defined as such:
int foo __attribute__ ((section (".noinit")));
will not be initialized to zero during startup as would normal .bss data. it just vibes there, untouched. โจ
Only uninitialized variables can be placed in the .noinit section. Thus, the following code will cause avr-gcc to issue an error:
int bar __attribute__ ((section (".noinit"))) = 0xaa;
It is possible to tell the linker explicitly where to place the .noinit section by adding -Wl,--section-start=.noinit=0x802000 to the avr-gcc command line at the linking stage. For example, suppose you wish to place the .noinit section at SRAM address 0x2000:
$ avr-gcc ... -Wl,--section-start=.noinit=0x802000 ...
Note: Because of the Harvard architecture of the AVR devices, you must manually add0x800000to the address you pass to the linker as the start of the section. Otherwise, the linker thinks you want to put the.noinitsection into the.textsection instead of.data/.bssand will complain. ๐ญ like it will genuinely be mad at you.
Alternatively, you can write your own linker script to automate this. [FIXME: need an example or ref to dox for writing linker scripts.]
โจ The .initN Sections โจ
These sections are used to define the startup code from reset up through the start of main(). These all are subparts of the .text section.
The purpose of these sections is to allow for more specific placement of code within your program.
Note: Sometimes, it is convenient to think of the.initNand.finiNsections as functions, but in reality they are just symbolic names which tell the linker where to stick a chunk of code which is not a function. Notice that the examples for asm and C can not be called as functions and should not be jumped into. ๐ซ do not jump in. they are not doors.
The .initN sections are executed in order from 0 to 9.
.init0: Weakly bound to__init(). If user defines__init(), it will be jumped into immediately after a reset..init1: Unused. User definable..init2: In C programs, weakly bound to initialize the stack, and to clear__zero_reg__(r1)..init3: Unused. User definable..init4: For devices with > 64 KB of ROM,.init4defines the code which takes care of copying the contents of.datafrom the flash to SRAM. For all other devices, this code as well as the code to zero out the.bsssection is loaded fromlibgcc.a..init5: Unused. User definable..init6: Unused for C programs, but used for constructors in C++ programs..init7: Unused. User definable..init8: Unused. User definable..init9: Jumps intomain().
๐ The .finiN Sections ๐
These sections are used to define the exit code executed after return from main() or a call to exit(). These all are subparts of the .text section.
The .finiN sections are executed in descending order from 9 to 0.
.finit9: Unused. User definable. This is effectively where_exit()starts..fini8: Unused. User definable..fini7: Unused. User definable..fini6: Unused for C programs, but used for destructors in C++ programs..fini5: Unused. User definable..fini4: Unused. User definable..fini3: Unused. User definable..fini2: Unused. User definable..fini1: Unused. User definable..fini0: Goes into an infinite loop after program termination and completion of any_exit()code (execution of code in the.fini9->.fini1sections).
๐ The .note.gnu.avr.deviceinfo Section ๐
This section contains device specific information picked up from the device header file and compiler builtin macros. The layout conforms to the standard ELF note section layout (http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html).
The section contents are laid out as below.
#define __NOTE_NAME_LEN 4
struct __note_gnu_avr_deviceinfo
{
struct
{
uint32_t namesz; /* = __NOTE_NAME_LEN */
uint32_t descsz; /* = size of avr_desc */
uint32_t type; /* = 1 - no other AVR note types exist */
char note_name[__NOTE_NAME_LEN]; /* = "AVR " */
}
note_header;
struct
{
uint32_t flash_start;
uint32_t flash_size;
uint32_t sram_start;
uint32_t sram_size;
uint32_t eeprom_start;
uint32_t eeprom_size;
uint32_t offset_table_size;
uint32_t offset_table[1]; /* Offset table containing byte offsets into
string table that immediately follows it.
index 0: Device name byte offset
*/
char str_table [2 +
strlen(__AVR_DEVICE_NAME__)]; /* Standard ELF string table.
index 0 : NULL
index 1 : Device name
index 2 : NULL
*/
}
avr_desc;
};
๐ซถ Using Sections in Assembler Code ๐ซถ
Example:
#include <avr/io.h>
.section .init1,"ax",@progbits
ldi r0, 0xff
out _SFR_IO_ADDR(PORTB), r0
out _SFR_IO_ADDR(DDRB), r0
Note: The,'ax',@progbitstells the assembler that the section is allocatable ('a'), executable ('x') and contains data ('@progbits'). For more detailed information on the.sectiondirective, see the gas user manual.
โญ Using Sections in C Code โญ
Example:
#include <avr/io.h>
void my_init_portb (void) __attribute__ ((naked)) __attribute__ ((section (".init3")))
__attribute__ ((used));
void
my_init_portb (void)
{
PORTB = 0xff;
DDRB = 0xff;
}
Note: Section.init3is used in this example, as this ensures the inernal__zero_reg__has already been set up. The code generated by the compiler might blindly rely on__zero_reg__being really0.__attribute__ ((used))tells the compiler that code must be generated for this function even if it appears that the function is not referenced - this is necessary to prevent compiler optimizations (like LTO) from eliminating the function. ๐
and that's the whole page bestie, every single section, every single note, nothing skipped, we ate and left no crumbs ๐
Version 2.1.0 ยท Sat Jan 29 2022 โ mwah, that's the source/version and date, tysm for reading, ily, go link something cute ๐๐โจ
๐ฆ where this page comes from
- fedora 43: avr-libc 2.2.1-3.fc43 ยท BSD-3-Clause
- fedora 44: avr-libc 2.2.1-5.fc44 ยท BSD-3-Clause
- opensuse-leap 16.0: avr-libc 2.1.0-bp160.1.33 ยท BSD-3-Clause
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms