AVR

4 Memory Sections

siwall 2014. 4. 17. 14:54

4.1. The .text Section

.text 영역은 프로그래밍에 의해 작성된 기계어가 위치한다.

이 섹션은 .initN 과 .finiN 영역으로 다시 나뉘게 되는데, 이것은 나중에 설명이 나온다.

Note

The avr-size program (part of binutils), coming from a Unix background, doesn’t account for the .data initialization space added to the .text section, so in order to know how much flash the final program will consume, one needs to add the values for both, .text and .data (but not .bss), while the amount of pre-allocated SRAM is the sum of .data and .bss.


4.2. The .data Section

이 영역에는 프로그램 코드에서 선언된 static data들을 포함한다. 

 char err_str[] = "Your program has died a horrible death!";

 struct point pt = { 1, 1 };


.data 섹션의 램 시작 주소를 링커에게 알려줄 수 있다.

-Wl,-Tdata,addr 명령을 사용

addr은 실제 램 주소에 0x800000을 더한 값이다.  그래야만 링커가 이 주소가 SRAM에 있다는 것을 알 수 있다.

만일 .data섹션이 0x1100에서 시작되기를 바란다면, 0x801100을 링커에게 전달한다.


4.3. The .bss Section

초기화되지 않은 전역변수 또는 static 변수들이 .bss 섹션에 위치한다.


4.4. The .eeprom Section

eeprom 변수들이 위치한다.


4.5. The .noinit Section

이 섹션은 .bss 섹션의 한 부분이다.

  int foo __attribute__ ((section (".noinit")));

초기화되지 않은 변수들만이 .noinit 섹션에 위치할 수 있다. 따라서 다음과 같은 코드는 에러를 발생시킨다.

  int bar __attribute__ ((section (".noinit"))) = 0xaa;

.noinit 섹션이 어디에 위치 할지를 링커에게 명시적으로 알려주는 것이 가능하다.

Wl,--section-start=.noinit=0x802000 과 같은 형태의 명령을 사용

예를 들어, 

SRAM의 0x2000 번지에 .noinit 섹션을 위치시키려고 한다면

$ avr-gcc ... -Wl,--section-start=.noinit=0x802000 ...

이렇게 사용하면 된다.(0x800000 이 옵셋)


4.6. The .initN Sections

스타트업 코드를 정의하기 위해 사용하는 섹션이다.

이것은 .text 섹션의 하위 파트이다.

.initN 섹션은 0에서 9번 순으로 실행된다.


.init0:

Weakly bound to __init(). If user defines __init(), it will be jumped into immediately after a reset.

.init1:

미사용. 사용자가 정의할 수 있다.

.init2:

In C programs, weakly bound to initialize the stack, and to clear __zero_reg__ (r1).

.init3:

미사용. 사용자가 정의할 수 있다.

.init4:

For devices with > 64 KB of ROM, .init4 defines the code which takes care of copying the contents of .data from the flash to SRAM. 

For all other devices, this code as well as the code to zero out the .bss section is loaded from libgcc.a.

.init5:

미사용. 사용자가 정의할 수 있다.

.init6:

C 프로그램에서는 사용하지 않지만, C++ 프로그램에서 생성자에 의해 사용된다.

.init7:

미사용. 사용자가 정의할 수 있다.

.init8:

미사용. 사용자가 정의할 수 있다.

.init9:

Jumps into main().


4.7. The .finiN Sections

이 섹션은 main() 함수에서 리턴된 이후 또는 exit() 함수 호출에 의해 실행될 exit code를 정의하는데 사용된다.

.text 섹션의 하위 파트이다.

.finiN 섹션은 9에서 0번 순으로 실행된다.


.finit9:

미사용. 사용자가 정의할 수 있다. This is effectively where _exit() starts.

.fini8:

미사용. 사용자가 정의할 수 있다.

.fini7:

미사용. 사용자가 정의할 수 있다.

.fini6:

C프로그램에서는 사용하지 않지만, C++ 프로그램의 소멸자에 의해 사용된다.

.fini5:

미사용. 사용자가 정의할 수 있다.

.fini4:

미사용. 사용자가 정의할 수 있다.

.fini3:

미사용. 사용자가 정의할 수 있다.

.fini2:

미사용. 사용자가 정의할 수 있다.

.fini1:

미사용. 사용자가 정의할 수 있다.

.fini0:

Goes into an infinite loop after program termination and completion of any _exit() code (execution of code in the .fini9 -> .fini1 sections).


4.8. 어셈블러 코드에서 섹션사용하기

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",@progbits tells the assembler that the section is allocatable ("a"), executable ("x") and contains data ("@progbits"). For more detailed information on the .section directive, see the gas user manual.


4.9. C 코드에서 섹션 사용하기

Example:

#include <avr/io.h>

void my_init_portb (void) __attribute__ ((naked)) \

__attribute__ ((section (".init3")));

void my_init_portb (void)

{

PORTB = 0xff;

DDRB = 0xff;

}


Note

Section .init3 is 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 really 0.




'AVR' 카테고리의 다른 글

8 How to Build a Library  (0) 2014.04.17
7 Inline Assembler Cookbook  (0) 2014.04.17
6 avr-libc and assembler programs  (0) 2014.04.17
5 Data in Program Space  (0) 2014.04.17
3 Memory Areas and Using malloc()  (0) 2014.04.17