☞ http://ya-n-ds.tistory.com/3103 : Embedded with ARM (1) ARM Register, Compile, ELF
< Scatter loading - Linker Description Script >
☞ http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0474m/pge1362065973150.html
- XIP ( eXecution-In-Place ) : Memory에서 직접 code 실행 가능 cf. SW Execution with Word-access
- *.scl ( Scatter Loading File = Linker Descritiom Script @GNU ) : Code와 Data를 Memory의 필요한 위치에 배치하는 script
-> Input section & Region is described in the .scl
- Input sections -> Output sections ( Grouping of the same-type symbols from object files : RO, RW, ZI )
-> Region : The unit of the output sections by which the image is loaded in the memory
cf. Input sections and Region are described in *.scl ( Output section is intermediary for Region )
- Load view : in the storage media before execution - ROM(RO,RW) cf. ZI region(.bss) is not necessary because it is '0'
Execution view : at the point of execution - ROM(RO-XIP) / RAM(RW,ZI)
- Scater Loading function
LOAD_ROM 0x0000 0x8000 ; Name of load region (LOAD_ROM)
{
EXEC_ROM 0x0000 0x8000 ; Name of first exec region (EXEC_ROM)
{
* (+RO) ; Place all code and RO data into this exec region
}
SRAM 0x10000 0x6000 ; Name of second exec region (SRAM),
{
* (+RW, +ZI) ; Place all RW and ZI data into this exec region
}
}
. LOAD_ROM 0x0000 0x8000 ; Name of load region (LOAD_ROM), Start address for load region (0x0000), Maximum size of load region (0x8000)
. EXEC_ROM 0x0000 0x8000 ; Name of first exec region (EXEC_ROM), Start address for exec region (0x0000), Maximum size of first exec region (0x8000)
. SRAM 0x10000 0x6000 ; Name of second exec region (SRAM), Start address of second exec region (0x10000), Maximum size of second exec region (0x6000)
. * : Corresponding Relocatable Object file
cf. 'armlink --ro_base 0x0 --rw_base 0x10000 *.o' // Same result with 'armlink -scatter ScatterFileName.scl *.o'
cf. Root region ( Loading view와 Execution view의 주소가 같은 region ) with 'FIXED' attribute e.g. ER_INIT 0x80000 FIXED { init.o(+R0) }
# Load View
LOAD_ROM 0x0 // Load view, ZI is ignored
{
spaghetti.o (+RO)
spaghetti.o (+RW)
}
# for Execution View
LOAD_ROM 0x0
{
EXEC_ROM 0x0 { spaghetti.o (+RO) } // Input section
EXEC_RAM 0x8000 { spaghetti.o (+RW) }
EXEC_RAM2 0xA000 { spaghetti.o (+ZI) } // ZI is indicated
}
- armlink -scatter FILE_NAME.scl outfile1.o outfile2.o ...
cf. caution : Root region ( Loading view와 Execution view의 주소가 같은 region ) - FIXED attribute
- Default memory map : RO - RW - ZI - HEAP - STACK // Contiguous
RO starts from 0x8000 with '__main' symbol as the Enty point
- BSS : 'Block Started by Symbol' : Load view에서 $$을 이용한 Symbol로 시작과 끝만 알려줌
% Map file 분석 ( Linker output )
☞ https://www.embeddedrelated.com/showarticle/900.php
- Image Symbol Table :
. Linker가 만든 Symbol과 주소 & Region
. User가 만든 Symbol과 주소 size & 속해 있는 object
- Memory Map of the image
. Scatter Loading에 맞춘 region에 따른 place
. 주소와 size, type, section과 object -> Linker output section
- Image component size
. 각 object, library의 RO, RW, ZI가 차지하는 size - Linker input section
- Whole layout
. 전체 memory에서 RO, RW, ZI의 size 정보
cf. Memory Map of the Image
Image Entry point : 0x00000000
Load Region BB_ROM ( base: *, Size: *, Max: *, ABSOLUTE )
Execution Region BOOT ( base: *, Size: *, Max: *, ABSOLUTE )
Execution Region MAIN_APP ( base: *, Size: *, Max: *, ABSOLUTE )
< Memory Map & Linker >
- Example 1
armcc -c embedded.c recipes.c // Linkable object file 만들기
armasm main.s // Assembly에서 object file 만들기
armlink --elf --ro-base 0x0 --rw-base 0x1000 -o target.elf embedded.o recipes.o main.o
// RO start=0x0, RW start=0x1000
- Example 2 : using Scatter Loading
armcc -c embedded.c recipes.c // Linkable object file 만들기
armasm boot.s // Assembly에서 object file 만들기
armlink --elf --scatter Target.scl -o target.elf embedded.o recipes.o boot.o
cf. Map file generation option;
armlink --elf --map --symbols --info sizes, totals, --list Tartet.map --scatter Target.scl -o target.elf embedded.o recipes.o boot.o
// '*.map' file is created by --map option and the file name can be assignend via --list option. Symbol information cab be specified with --info option
cf. Target.scl
LOAD_REGION 0x0 // Load region start : 0x0
{
EXE_REG_1 0x0 { boot.o (+RO, Int_Vect) }
EXE_REG_1 0x4000 {
embedded.o (+RO)
recipes.o (+RO)} }
EXT_REG_2 0x8000 { * (+RW, +RZ) } // boot.o, embededded.o, reipes.o
}
< Makefile >
# Makefile 구조
CC = tcc // macro definition
output_file1 : input_file11 input_file12 ...
command // command 앞에 'tab' 필요
output_file2 : input_file21 input_file22 ...
command
....
# spaghetti.mak - Original
spaghetti.bin : spaghetti.elf
fromelf -o spaghetti.bin spaghetti.elf
spaghetti.elf : spaghetti.o manupulation.o
armlink -elf -o spaghetti.elf spaghetti.o manupulation.o
spaghetti.o : spaghetti.c
tcc -c spaghetti.c
manupulation.o : manupulation.c
tcc -c manupulation.c
- 실행 :
work_dir:> make -f spaghetti.mak
cf. *.c와 *.o의 시간을 비교해서 같으면 skip
- Log 남기기
work_dir:> make -f paghetti.mak 2>&1 | tee recipes.log
cf. '| tee' : screen과 log 파일로 전달
cf. '2>&1' : stderr를 stout(buffer 사용)으로 전달 ( Bourne shell 연산자. csh에서는 사용할 수 없음 )
-> 2:stderr, 1:stdout, 0:stdin
# spaghetti.mak - w/ Macro
TARGET = spaghetti.bin
ELF_TARGET = spaghetti.elf
BINTOOL = fromelf
CC = tcc
OBJECTS = spaghetti.o manupulation.o
$(TARGET) : $(ELF_TARGET)
$(BINTOOL) -o $@ $^
$(ELF_TARGET) : $(OBJECTS)
$(CC) -o $@ $^
// Pre-defined Macro;
$@(=Target), $*(=Target w/o suffix), $^(=Source w/o Suffix rule), $<(=Source later than Target)
# spaghetti.mak - w/ Macro, Suffix rule
TARGET = spaghetti.bin
ELF_TARGET = spaghetti.elf
BINTOOL = fromelf
CC = tcc
OBJECTS = spaghetti.o manupulation.o
$(TARGET) : $(ELF_TARGET)
$(BINTOOL) -o $@ $^
$(ELF_TARGET) : $(OBJECTS)
%o : %c
$(CC) -o $@ $<
// % : SUFFIX rule -> Use the same file names for source and target files, e.g.%.out : %.m
mytool $@ $<
// .SURFIXES : .c .o
# spaghetti.mak - w/ Macro, Suffix rule, : Compile all the files in a directory
TARGET = spaghetti.bin
ELF_TARGET = spaghetti.elf
BINTOOL = fromelf
CC = tcc
SRC = $(wildcard *.c)
OBJECTS = $(SRC:.c=.o)
$(TARGET) : $(ELF_TARGET)
$(BINTOOL) -o $@ $^
$(ELF_TARGET) : $(OBJECTS)
%o : %c
$(CC) -o $@ $<
## linux) vi Makefile
all : main
main: main.o test.o
gcc -o main main.o test.o
%o : %c
gcc -c $@ $<
clean:
rm -f main main.o test.o
// linux) make
// linux) make all
// linux) make clean
< Further Skills for Make >
#01. Compile with multiple directories
DIRS = a b c
OBJECTS = a.o b.o c.o
TARGET = k
all : objs
tcc -o $(TARGET) $(OBJECTS)
objs :
@for dir in $(DIRS); do\
make -C $$dir all;
done
// $: for Makefile varriable, $$: for shell variable in make
#02. 'vpath' for autononously search of sub-directory
CSRC_PATH = c:/project/src
vpath %.c $(CSRC_PATH)
vpath %.h $(CSRC_PATH)
// % : acts like wild card '*'
// vpath : appended characteristic
// 'vpath' without any variables -> Delete paths appended before
// VPATH : search path when there is no source in the current directroy
e.g. VPATH = path_1:path_2:...:path_k
#03. include - usually for macro
#04. Definition of Macro. e.g.
define MACRO_NAME
@echo $(INCLUDE_PATHS) $(IBJS) $(CC)
endef
// helpful for debugging
#05. @Command : Display the result without the current command line
#06. .PHONY : same as BOGUS in C-code // Indicates that it's not the target of build. Usage is;
.PHONY: clean
clean:
rm -f *.o
#07. Flags : for selective execution with #ifdef ... #endif
-----------