;

연암과 다산 사이

블로그 이미지
문패 달고 보니까 넘 커다란 이름이네요 ^^; 행여 고래 등 사이에 끼인 새우가 되지 않기를 ㅎㅎ 연암은 고미숙님의 '열하일기, 웃음과 역설의 유쾌한 시공간'에서, 다산은 '다산연구소' (http://www.edasan.org)에서 삘 받았슴다. 잼난 놀이터가 되었으면... ^^
by 명랑만화
  • Total hit
  • Today hit
  • Yesterday hit
09-19 19:47

http://ya-n-ds.tistory.com/3137 : Embedded with ARM (2) Scatter file, Map file, etc

 

Reference : 'Embedded Recipes'(히언, 코너북)

☞ http://recipes.egloos.com/

 

< Registers >
- General Purpose Register : Address Register, Data Registser(In/Out), Instruction Pipeline Register(Op Code)

- Special Purpose Register :
  a. Program Counter : 현재 실행되고 있는 코드 주소
  b. Stack Pointer : 현재 Stack 영역의 마지막에 데이타가 Push된 곳을 가르키는 주소
    cf. Stack initialization for Abort mode : Change CPU mode to Abort mode -> Link Abort stack to R13
    msr CPSR_C, #PSR_Abort
    lrd r13, =abort_stack+Abort_Stack_Size // Descending 일 때는 'abort_stack+Abort_Stack_Size'부터
      // Ascending 일 때는 'abort_stack'부터

  c. Linked Register : code가 Jump 했을 때 돌아갈 곳의 주소
  d. Status Register : MCU의 상태를 나타내는 Register

 

- IO Register : D Flip-flop ( 필요한 크기만큼 assign -> Read할 때 Masking해서 사용 필요 )
  Type : Read-only, Write-only, Read-Write

 

cf. Macro Instruction(Assembly) - Micro Instruction (Lower level : Logic gate?)

 

 

< ARM 동작 Mode >

- User : Normal
  System : OS Task
  Execption Mode : FIQ, IRQ, Supervisor(Protected OS - SWI), Abort(Memory data access violation), Undef(Undefined instruction)
 cf. Privileged Mode : System + Exception Mode

- Privilegd Modes : 서로간의 mode 변경 가능 ( Priviledged -> Normal )
- Default mode : Supervisor Mode ( SVC )

 

 

< ARM Register >

- General register : R0~R12  /  Special Purpose Register : R13~R15, CPSR, SPSR
- R0~R7, R13~R15 : Thumb mode & ARM mode  /  R8~R12 : ARM mode only

 

- R0~R7, R15(PC) : Common for All - 9ea
- R8~12 : Common for USR, SYS, FIQ, SVC, ABT, IRQ, UND - 5ea
- R9~12_banked : FIQ - 5ea
- R13~14 : Common for User, SYS - 2ea
- R13~14_banked : FIQ, SVC, ABT, IRQ, UND - 2*5=10ea


- CPSR : Common for SYS, FIQ, SVC, ABT, IRQ, UND - 1ea
- SPSR_banked : FIQ, SVC, ABT, IRQ, UND - 1*5=5ea

 

- CPSR : Current Program Status Register
 . [31:28] : N(Negative), Z(zero), C(Carry), V(oVerflow)
 . [7]-IRQ, [6]-FIQ : '1'-Disable, '0'-Enalbe
 . [5] : '1'-Thumb mode / '0'-ARM mode
 . [4:0] : modes
 cf. USER, SYS : Same except for the CPSR mode bits

 

- SPSR : Saved Program Status Register - Mode change할 때 CPSR을 backup -> 이전 mode로 돌아갈 때 사용

 

- R14 ( Linked Register ) : 어디에서 branch 했는지를 알려 줌
- R13 ( Stack Pointer ) : 현재 Stack이 쌓여 있는 위치
- R15 ( Program Counter ) : 현재 Instruction을 Fetch해 온 위치

- Context : Register set의 snap shot

 

 

< ARM Exception & Mode >

- Exception : Initiation of Mode entry ( including Interrupt )
- Reaction : 현재 동작 멈춘다 -> Exception에 해당하는 Mode에 진입 -> Exception 해당 주소로 PC(Program Count)를 Jump -> Exception 처리

 

- PC for Modes ( Exception case )
  . SVC mode : Power-on or Reset or SWI -> PC를 0x0(Low vector인 경우)로 jump
  . IRQ/FIQ mode : Interrupt -> PC를 0x1C/0x18로 jump
  . Abort mode : Data abort/Prefetch abort -> PC를 0x10/0x0C로 jump cf. Memory access fail ( e.g. Abnormal address, Access protection )
  . UNDEF mode : PC를 0x04로 jump cf. Decoded Intruction error ( e.g. Memory corruption )

 

- CPSR for Modes
  . User=0x10, FIQ=0x11, IRQ=0x12, SVC=0x13, Abort=0x17, Undef=0x1B, SYS=0x1F

 

- Exception priority : Reset > Data Abort > FIQ > IRQ > Prefetch Abort > Undefined > SWI
  cf. Undefined : Handler에서 Coprocessor 또는 주변기기 control routine에 사용

 

- Exception Reaction;
 1. Ability to return to the previous state
 . Mode saving : CPSR -> SPSR_xcpt
 . Context를 stack에 저장 - Banked register를 제외한 나머지 Register를 저장 ( R0~R12 )
  R13_xcpt = Stack location
 . Mode change : CPSR 변경(bit[4:0]) -> Stack pointer도 Exception mode 것으로 변경됨,
  ARM mode로 변경(T=0), IRQ Disable(I=1) cf. Exception : 32-bit ARM mode .
 . 돌아갈 주소 저장 : R14_xcpt <= R15(PC)  // Back-up of PC to Linked Register
  보정 : PC보다 2개의 OP code 전 ( Calculated address depends on MCU bit e.g. 16-bit, 32-bit, etc )
 . R15(PC) <= Exception Jump 주소 -> PC 값을 Vector address로 변경
 . R0~R12 : Saved to the stack pointed by R13_xcpt
   cf. CPSR, R15(PC), R0~R12 are shared -> Back-up is required

 

 2. Return to the Previous State
 . CPSR <= SPSR_xcpt
 . Stack에 저장했던 Register 복원 ( R0~R12 : via R13_exct )
 . PC(R15) <= R14_xcpt(Linked Register)

 

 3. Miscellaneous Tips
   - mode : ARM can be secured from Application SW
   - No SPSR for System/User mode -> There is no exception for entry -> CPSR is backed-up using Stack if necessary
   - Exception Vector Table : Exception handling FW is to be implemented from that address
   - High Vector : SRAM for Bootloader -> DRAM Initialization -> FW copy from NAND to SDRAM -> Change to Low vector
  
 
< ARM-Thumb PCS : Register 사용법 >
- APCS : ARM Procedure Call Standard -> Compiler가 기계어를 만들어 낼 때 사용하는 규칙
 cf. AAPCS : Procedure Call Standard for ARM Architecture
 . R12 : The Intra-Procedure-Call scratch register
 . R11(=V8 / FP) : ARM state variable register 8 / Frame Pointer
 . R10(=V7 / SL) : Stack Limit Pointer
 . R9 (=V6 / SB) : ARM state variable 6
 . R[8:4](=V5~V1) : ARM state variable [5:1]
 . R[3:0](=A4~A1) : Argument/Result/Scratch register[4:1]

 

- R0~R3(a1~a4)
 1) Argument
 int function (int a, int b, int c, int d)
 -> (void) function (10,20,30,40);
  R0=10, R1=20, R2=30, R3=40
 2) Result ( Return value )
 f = function(10,20,30,40); // if result is '100'
 -> R0=100 -> f=100

 R1~R3 : Pointer값을 넣어주면 호출한 쪽에서 return 값처럼 R1~R3를 가져다 쓸 수 있음
 -> Return value size : Max= 4byte*4 = 16byte
 3) Scratch : Argument 전달 수단으로 쓰인 후, APCS만 잘 지키면 함수 내부에서 임의로 사용 가능

cf. Argument : 4개까지는 R0~R3에 저장, 나머지는 Stack에 저장
    함수 내부 변수 : 8개까지는 R4~R11에 저장. 나머지는 Stack에 저장

 

- R4~R11(v1~v8) : Variable. 함수 호출 후에 바뀌면 안된다.
 -> 함수 수행 전에 이전 R4~R11을 Stack에 저장한 후 사용
 -> 함수가 끝나면 Stack의 값을 R4~R11로 다시 복원

 

- R12(IP, Intra) : ARM-Thumb interworking / Long branch할 때 Veneer를 통한 주소 할당할 때 임시 보관소로 사용
- R13(SP, Stack Pointer)
- R14(LR, Linked Register) : 함수 호출 또는 Jump할 때 돌아올 주소를 저장
- R15(PC, Program Counter) : Fetch하고 있는 주소

cf. Compiler option : -apcs

 

 

< Compie - Concept >

- Primitive Compiler : Assembly -Assembler-> Native code ( cf. Natvie code : Processor dependent )
  cf. Assembly : 기계어(Native code)와 1:1로 mapping -> a kind of 'mnemonic' ( symbol for easy memorization )
- High level language Compiler : C, C++, etc. -> Assembly -> Native code ( Executable binary image )
  cf. Processor에 맞는 Assembly를 만들어내는 compiler 필요

 

- Cross compile 환경 : 실제 Target에서 돌아갈 binary image를 PC에서 compile 할 수 있는 환경 ( Taget 자체는 Compile 하기에는 너무 작은 시스템 )

 

 

< Compile - Basic >

- '*.c, *.h' -(C compiler)-> '*.s' -(Assembler)-> '*.o'(+ELF format) -(Linker)-> '*.elf' image -(fromelf)-> '*.bin'
  cf. Linker inputs : '*.o', '*.lib'(on Window, with wrappers for DLL), '*.a'(archive files on Unix), '*.scl'(SCatter Loading for code allocation in memory)
  cf. Linker outputs : Shared object files(*.o, *.a), Executive image(*.elf), Text file for Memory structure(*.map, *.sym)
- C-compiler (armcc, tcc) / Assembler (armasm)
- ELF : Executable and Linking Format -> Native code + Other information = "linked objects"

 

- C-compiler + Assembler ;
 1. Pre-process : #defien, #include 처리, Syntax error check -> c 형식의 *.i 파일 만듦
 2. *.s 파일 만듦 ( Mnemonic의 Assembly )
 3. Assembler : elf 형식의 *.o 파일 만듦

 

- *.lib : source code를 제공하고 싶지 않을 때 object 형식으로 미리 컴파일하여 제공하고, lib는 다른 컴파일된 object 들과 link되어 같이 물려 들어가는 방식으로 처리
- *.scl : Scatter loading - binary를 만들 때 메모리 주소 구성을 원하는 대로 할 수 있게 해주는 script 파일
- *.map, *.sym : compile된 binary의 메모리 구성을 나타내 주는 text file ( compiler option )

 

cf. Cross Compiler : ADS(ARM Developer's Suit), ARM GCC(GNU project)

 

< Compile Execution - Preprocess >

- tcc -E file_name.c > file_name.i

 

- #include "" : *.c가 있는 directory에서부터 시작하여 Search path로 등록된 path를 찾아감
  #include <> : Compiler에게 미리 정의된 path부터 header를 찾아감
 e.g. #include <stdio.h> : ADS 설치된 directory의 include directory가 pre-defined path

 

- tcc -E -Iinclude_path file_name.c > file_name.i  // Inlcude path option : -I
 cf. -J option : Compiler default include path for <>

 

- Header의 중복 include를 막음
 #ifndef __SPAGHETTI_H__
   #define __SPAGETTI_H__
   #include "spaghetti.h"
 #endif

 

 

< Compile Execution - Assembly >

- tcc -S file_name.c

main PROC
 ...
 BX lr ;; Branch exchange to lr(Linked Register) ; Return value is r0
ENDP

 

__asm {...} ; In-line Assembly
cf. Function arguments are separately managed from the registers used in in-line assembly

 

 

< Compile Execution - Library >
- Library ( Archive file ) : 미리 컴파일 해놓은 object 파일 모음 ( 자주쓰는 함수는 compile할 때 Link만 해주면 됨 )  e.g. 'printf'

 

- Make Library from Object files
 armar -r Lib_FileName.lib C_FileName1.o C_FileName1.o C_FileName1.o
cf. tcc -c C_FileName1.c C_FileName1.c C_FileName1.c

 

- command window에서 'armar'   // Option is displayed
 armar -x Lib_FileName.a Target_Name // Extract members corresponding to the target names
 armar -d Lib_FileName.a Target_Name // archive 안에 있는 object 제거
 armar -tv Lib_FileName.a   // Print table of the contents of archive

 

ADS12\Lib\armlib>
 *_a_*.? : ARM standard library
 *_t_*.? : Thumb standard library

ADS12\Lib\armlib> armar -t f_t.b // Print table of the contents of the archive

ADS12\Lib\armlib> armar -zs f_t.b // Show table of the symbols
 cf. Symbol : Names of Global variable, Function, etc.

 

ADS12\Lib\armlib> armar -d f_t.b printf2.o // Delete 'printf2.o' from f_t.b archicve
-> printf2.c에 다른 함수를 구현
-> tcc -c printf2.c  // Generate only Linkable object
-> armar -c f_t.b printf2.o // Suppress warning when a new archive is created

 

 

< 변수의 scope >
- auto : Local 변수 - 함수 안에 정의. 선언된 함수 또는 block 안 -> 함수 수행 후 return과 함께 사라짐
  e.g. void function_name { auto int var1; ... return; }

 

- Global 변수 - 함수 바깥에 정의... 선언된 위치부터 파일 끝까지 영향을 줌
  int durian = 0x10;  // durian : spaghetti, ramen 함수에서 사용 가능
  void spaghetti(void){...}
  char sirsak = 0x20;  // sirsak : ramen 함수에서 사용 가능
  void ramen(void){...}

- extern : 다른 파일에서 선언된 Global 변수를 사용
  e.g. extern int durian : 다른 함수에서 정의되어 있는 durian을 사용 ( Link할 때 연결됨 )

 

- static : 프로그램 시작할 때 생성, 프로그램 끝날 때 없어짐. 접근성을 제약 ( 선언된 파일 안에서만 사용 )
 . local static : 함수가 끝난 후에도 그 값을 유지
 . global static : 다른 함수에서 extern을 선언하여 가져다 쓸 수 없음
  e.g. static int durina = 0x10;

 

- volatile : Optimization 하지 않음
 cf. Memory mapped I/O

 

 

< Memory Map & Symbol >

- Symbol : Linker가 알아볼 수 있는 기본 단위. Link 후에 자신만의 주소를 갖게 됨
 -> Symbol의 이름은 메로리 영역의 시작 주소를 가리키는 pointer 역할
 -> e.g. function, global variable, static variable ( 자기만의 고유 주소 가짐 - 다른 파일의 함수들에서도 access 가능 )

 

- ELF object 파일 내의 Symbol table : Source code에 의해 참조되는 Symbol들의 이름과 위치 정보
 -> Linker가 참조하여 address로 변환하여 binary로 만듦

 

- Symbol Types ( ADS )
 . RO ( Read Only ) - Function(Code - .text), Const Global Variable, Const data (.constdata )
 . RW ( Read Write ) - 초기값 있는 Global variable ( .data )
 . ZI ( Zero-Initialization ) - 초기값이 0인 Global variable ( .bss )
  = initial 되지 않은 global variable + initial 값이 0인 global variable + 전역변수 array로 구현된 stack, heap
 cf. RO->ROM / RW->ROM,RAM / ZI->RAM : Location can be manipulated via 'Scatter loading file'

 

- Non-symbol ( ZI )
 . Local variable : Stack
 . Dynamic Memory Allocation : Heap   e.g. 'malloc-free'

 


< Executable and Linking Format : ELF >
http://recipes.egloos.com/5010841 : ELF format Object 파일에 관한 진실
http://recipes.egloos.com/v/5011946 : ELF와 fromelf까지!

https://www.cs.utexas.edu/users/fussell/courses/cs429h/lectures/Lecture_20-429h.pdf : Linking

 

- Linking view ( Link 하기 전의 object 파일 ) / Execution view ( Link 후 )
 cf. ELF Header / .text(code), .rodata (RO) / .data(RW) / .bss(Block Shared by Symbol:ZI)

 -> readelf -h spaghetti.o ( cf. -h : header option )
 -> fromelf -c spaghetti.o // disassemble


- Linker Placement Rule for Executable Image
 . Input Section (Section) : Collect the same section from the surce files
 . Output Section (Code) : Arrange the input section in alphabetic sequence
 . Region (RO, RW, ZI) : ??
 cf. Linker 역할 : 함수 위치와 전역변수들의 위치를 library 파일과 object 파일에서 조사한 후 Table로 가지고 있다가, 그 주소를 함수와 변수를 사용하는 코드 부분에 적는다. RAM이 많이 필요.

 

- ELF Relocatable object file ( Linker가 사용할 수 있는 정보 포함 )
 ELF header
   // Start of section
 .text  // 컴파일된 OP code
 .rodata  // Const data + switch case의 jump table
 .data  // Global variables with initial values other than zero
 .bss  // Global variables unitialized or zero-initialized
 .symtab  // Symbol table ( Global variable, function )
 

.rel.text // relocatable text, Relocation info for .text section. Addresses of instructions that will need to be modified in the executable object file
   // Linker가 이 object 파일과 다른 object 파일 연결할 때 사용 (e.g. code with extern variable ). Link 후의 executable object file에서는 없어짐.

 .rel.data // ( similar as .rel.text. ) Relocation info for .data. Addresses of pointer data that will need to be modified in the merged executable object file
 .debug  // -g option : debug symbol table ( DWARF type debugging symbol )
 .line  // -g option : op code와 C code의 line을 연결 ( for Trace32 Debugger cf. 'y.sourcepath' )
 .strtab  // .symtab과 .debug setction에 사용되는 const data인 string table
   // End of section
 Section header table // Description of object file sections

cf. Relocatable object file : section = Executable object file : segment(~Sum of sections)

 

- ELF Executable object file
 ELF header  // with entry point address which is the start address of this file
 Segment header table // Maps contiguous file section to runtime memory segments
 .init   // ELF 실행전 OS의 Initializatin code + Program header ( Informatiom for execution )
 .text   // 컴파일된 OP code
 .rodata   // Const data + switch case의 jump table
 .data   // RW
 .bss   // RW
 .symtab   // Symbol table ( Global variable, function )
 .debug   // -g option : debug symbol table
 .line   // -g option : op code와 C code의 line을 연결
 .strtab   // .symtab과 .debug setction에 사용되는 const data인 string table
    // End of section
 Section header table // Description of object file sections

 

=> Segment allocation

 . Read-only Segment : ELF header ~ .rodata ( Code segment ) -> RO : .text + .rodata
 . Read-Write Segment : .data, .bss ( Data segment ) -> RW : .data
      => Binary for Embedded system : 'RO + RW'
   cf. .symtab ~ Section header table are not loaded into memory

   cf. .data : ROM에 초기값을 가지고 있어야
   cf. .bss : 시작주소와 Size만 가고 RAM 영역 확보 -> boot sequence에서 bss 영역을 0으로 초기화

 

- Relocation Rule for the duplicated Global symbols
0. Function & Initialized Global varialbe=Strong  //  Uninitialized Global variable=Weak
1. Duplicated Strong symbol -> Link error
2. Strong symbol + Weak symbols -> Compiled with Strong symbol
3. Weak symbols -> randomly selected and compiled
cf. 'static' : prevention of reference from other files


- Making binary : stored in ROM ( RO, RW )
tcc -c arm.c thumb.c     // for Relocatable object file in ELF format : Output - arm.o thumb.o
armlink -elf -o embedded.elf recipes.lib arm.o thumb.o // for Executable object file in ELF format
fromelf -bin -o embedded.bin embedded.elf  // for Executable binary file

 

- Example including 'armar', 'armasm'
armcc -c arm.c thumb.c   // linkable object 파일 만들기
     // = 'armcc -S' + 'armasm'
armar -r armthumb.lib arm.o thumb.o // library 만들기
armasm boot.s    // Assembly를 linkable object 파일 만들기
armlink -elf -o recipe.elf armthumb.lib boot.o
fromelf -bin -o recipe.bin recipe.elf

 

- DWARF : Executable ELF의 debug section의 형식 -> ICD(In Circuit Debugger)에 사용
- axf : arm executable format ( a variance of elf ) - .debug is based on DWARF2.0

 

-------

AND

ARTICLE CATEGORY

분류 전체보기 (4370)
올드Boy다이어리 (529)
올드Boy@Jeju (83)
올드Boy@Road (130)
올드Boy@Book (57)
숨은길찾기 (14)
스펙트럼 (104)
우물밖엿보기 (32)
교회에말걸기 (225)
이어지는글들 (52)
하하호호히히 (73)
어?...아하! (123)
대한늬우스 (1616)
세계는지금 (260)
차한잔의여유 (64)
La Vita E Bella (230)
좋은나라만들기 (91)
트위터세상 (67)
사람&말 (596)
호모파베르 (20)

RECENT ARTICLE

RECENT COMMENT

RECENT TRACKBACK

CALENDAR

«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

ARCHIVE