컴파일과정을 거쳐 생성되는 오브젝트 코드들은 메모리의 주소에 할당되지 않은 상태입니다. 주소 정보는 링크(Link) 과정을 통해 지정됩니다. 이 때 메모리에 대한 정보, 예를 들면 ROM의 시작 번지와 마지막 번지 그리고 RAM 영역의 번지, 스택 크기 설정 등과 같은 정보가 필요합니다.

이러한 정보를 관리하는 파일이 링커 설정 파일(Linker Configuration file)입니다. 이 파일의 확장자는 .icf 이며, 텍스트 파일 형식으로 되어 있어 GUI 방식으로 설정이 가능하나 텍스트 파일을 직접 편집 창에서 설정하는 것이 편리합니다. 

해당 icf파일은 툴이 설치될 때 디바이스에 따라 하나의 icf파일이 제공됩니다. 
그래서 해당 파일을 복사하여 프로젝트 폴더안에 위치시켜 놓고 이름을 변경하여 사용해야 합니다. 앞서 General Options 설정에서 Device를 지정하면 자동으로 해당 icf파일이 연계 동작합니다. 

이런 경우 사용되는 icf파일은 툴이 설치될 때 생성된 파일이므로 프로젝트에 새로이 생성한 icf 파일을 사용하려면 Override default를 선택하고 해당 icf파일을 지정해야 합니다. 이렇듯 별도로 icf파일을 지정한 경우, 주의 할 점은 파일의 위치가 절대 패스로 설정되는 것입니다. 그러므로 $PROJ_DIR$와 같은 프로젝트 폴더의 환경 변수를 이용해 지정해 주어야 다른 폴더 구조의 PC에서도 동작하게 됩니다.

Configuration file symbol definitions 항목은 링커 설정 파일에서 사용하는 상수 설정 심볼을 정의합니다. 이는 icf파일의 define symbol 지시어와 동일한 효과를 가집니다. Library 탭은 사용되는 라이브러리를 선택하는 옵션입니다.

Automatic runtime library selection을 선택하면 
링커(Linker)가 자동으로 알맞은 라이브러리를 선택하여 사용하게 됩니다. 만약 작성하지 않은 함수에 대해 링크 시 오류가 발생되는 경우에는 이 항목이 선택되어 있는지를 확인 하십시오.
Additional libraries 항목은 추가적으로 라이브러리를 사용할 때 해당 라이브러리를 지정합니다. 

[그림 1] Config
[그림 2] Library

한 줄에 하나씩 명시하여야 하며, $PROJ_DIR$ and $TOOLKIT_DIR$와 같은 환경 변수를 이용할 수 있습니다. 또한, 여기서 지정한 라이브러리는 워크스페이스 윈도우의 프로젝트 안에 직접 소스 파일처럼 라이브러리 파일을 추가하여 사용할 수 있습니다.

Override default program entry 는 프로그램 시작점을 변경할 때 사용합니다. 기본적으로 __iar_program_start 라벨이 사용됩니다. 그러나 사용자가 임의의 프로그램 시작점을 사용하는 경우에 이 항목을 선택하고 사용자 정의의 라벨을 사용합니다.

[그림 3] Input

Override default program entry를 선택하여 사용자가 정하는 프로그램 시작 위치를 설정할 수 있습니다. Entry symbol은 기본 __iar_program_start 라벨 이외의 시작점을 명시합니다. 
Defined by application은 링크된 오브젝트 코드의 정의된 시작점을 사용합니다. 링커는 관련된 모든 프로그램 모듈과 필요한 라이브러리들을 포함시킵니다.

Keep symbols 항목은 한줄에 하나의 심볼을 명시하며, 정의된 심볼을 삭제하지 않고 링크 시에 유지합니다. 링커는 어플리케이션에서 필요한 심볼만을 유지합니다. 

Raw binary image 항목은 링크 시에 바이너리 파일을 지정한 메모리 섹션에 함께 합쳐 하나의 실행 이미지를 생성합니다. 바이너리 파일 형식만을 추가하여 이미지를 생성할 수 있으며 정의한 심볼로 해당 바이너리 데이터를 엑세스 할 수 있습니다.

주어진 심볼이 자동 삭제되는 것을 방지하기 위해서는 Keep symbols 항목에 추가하여야 하며, 링커는 심볼이 사용되지 않더라도 삭제하지 않습니다. 

[그림 4] Extra Options
[그림 5] Optimizations

만약에 2개 이상의 바이너리 파일들을 함께 하나의 실행이미지로 생성하기 위해서는 GUI 상에서는 하나만을 지원하므로 Extra Options탭에서 Use command line options를 선택하고 -image_input 명령을 사용하면 됩니다. 

예를 들면 --image_input bootstrap.abs, Bootstrap, CSTARTUPCODE,4와 같이 GUI에서 표시되는 같은 순서의 항목을 쉼표로 분리하여 바이너리 파일들을 여러 라인으로 명시하면 됩니다.
Merge duplicate sections을 선택하면 동일한 읽기 전용 섹션의 단 하나의 영역만을 유지합니다. 

[그림 6] Advanced

서로 같은 주소를 같는 다른 함수 또는 상수 값에 대해 발생될 수 있으며 이 옵션을 선택한 경우 어플리케이션에서 어드레스 상황에 따라 정상적인 동작이 되지 못할 수 있다는 점을 유의해야 합니다. Perform C++ Virtual Function Elimination(VFE)은 VFE 최적화를 활성화합니다. 

VFE 기능을 강제로 사용하기 위해 Even if some modules are missing VFE information 옵션을 선택합니다. 이때는 필요한 정보가 부족한 모듈에서 가상 함수 호출 또는 다이나믹 런타임 형식 정보를 사용한다면 안정적이지 못할 수 있습니다. 

Advance 옵션은 다양한 링커 기능을 제어합니다. Allow C++ exceptions을 선택하지 않은 경우이면 포함된 코드에서 throw가 있으면 링커는 오류를 발생합니다. 만약 애플리케이션에서 실수로 예외 처리를 하지 않은 것을 링커가 검사하기 위해서는 이 옵션을 선택하지 마십시오.

Always include C++ exceptions 을 선택하면 필요한 예외 처리 루틴이 없는 경우 링커가 예외 처리 코드를 포함합니다. 코드 중에 rethrow가 되지 않는 throw 표현식이 있다면 사용되는 예외 처리를 고려합니다. 

코드에서 throw표현식이 없다면 링커는 실패에 대한 예외처리를 throw하는 대신에 abort를 호출하기 위해 new 연산자, dynamic _cast 그리고 typeid에 대해 정렬합니다. 만약 throw 처리가 미비한 경우에는 이 옵션을 사용하여야 할 수도 있습니다. 만약 애플리케이션에서 실수로 예외 처리를 하지 않은 것을 링커가 검사하기 위해서는 이 옵션을 선택하지 마십시오.

[그림 7] Output

Enable stack usage analysis는 스택 사용 분석 기능을 활성화합니다. Linker map파일이 생성되면, 그 map파일에 스택 사용 정보가 포함됩니다. 각 함수마다 사용하는 스택 사용량에 대한 정보를 취합하여 스택 사용에 대한 크기 설정에 참고할 수 있는 자료를 제공합니다. 

Control file은 스택 사용 분석 기능을 제어하기 위해 사용하는 스택 사용 제어 파일(stack usage control file)을 지정하며 확장자는 .suc입니다. 이 파일은 컴파일러가 인식하지 못하는 함수의 호출 단계에 대한 정보를 사용자가 직접 정의해 주는 기능입니다. Call graph output은 링커에서 생성되는 call graph 파일명을 지정합니다. 확장자는 .cgx입니다.

[그림 8] List

Output filename은 ILINK 출력 파일의 이름을 지정합니다. 기본적으로 링커는 프로젝트명을 사용하며, 확장자는 out입니다. Include debug information in output 을 선택하면 디버깅 정보를 위한 DWARF를 포함하는 ELF형식의 결과 파일을 링커가 생성합니다. 디버깅 정보를 포함하고 있어야 C-SPY 디버거를 사용할 때 정상적으로 동작합니다.

Generate linker map file을 선택하면 링커가 메모리 맵 파일을 생성하며, list 폴더 위치에 프로젝트명.map 파일을 생성합니다. Generate log file 항목에서는 각종 로그 정보들을 프로젝트명.log 파일명으로 로그 파일을 생성합니다. 

[그림 9] Checksum

그림 9의 Checksum 탭에 대해 살펴보겠습니다. 체크섬(Checksum) 기능은 실행이미지의 상태를 검사하는 기능입니다. 실행 코드의 값들을 CRC16과 같은 알고리즘을 이용하여 체크섬 값을 생성하여 ROM의 특정 위치에 기억시킵니다. 

프로그램이 실행되면서 동일한 체크섬 알고리즘으로 체크섬 값을 계산하고 ROM에 저장되어 있는 값과 비교하여 실행 코드의 정상 여부를 확인할 수 있습니다. Fill unused code memory는 사용하지 않는 메모리 영역에 대해 시작과 마지막 번지를 명시하고 Fill pattern 에 지정한 16진수 값으로 채우게 됩니다. Generate checksum 항목에서는 체크섬의 크기 및 정렬(Alignment), 알고리즘 등에 대해 세부적인 설정을 할 수 있습니다.

 

맺음말  
EWARM에 대한 프로젝트 옵션 중 Linker에 대해 살펴보았습니다. 링크 시 사용되는 여러 옵션 설정을 활용한다면 보다 편리하게 코드를 특정 번지에 위치시킬 수 있으며, 효율적인 코딩을 구현 할 수 있습니다. 

그리고 메모리 영역 설정에 필요한 정보는 icf파일을 이용하므로 icf파일을 잘 활용하면 쉽게 코드를 RAM으로 재배치할 수도 있습니다. icf파일에 대한 자세한 내용은 C/C++ Development Guide의 Linker Configuration File 항목을 참조하시기 바랍니다. 
감사합니다.

 

고성용 이사 / IAR 시스템즈
Sung-Yong.Ko@iar.com

회원가입 후 이용바랍니다.
개의 댓글
0 / 400
댓글 정렬
BEST댓글
BEST 댓글 답글과 추천수를 합산하여 자동으로 노출됩니다.
댓글삭제
삭제한 댓글은 다시 복구할 수 없습니다.
그래도 삭제하시겠습니까?
댓글수정
댓글 수정은 작성 후 1분내에만 가능합니다.
/ 400
내 댓글 모음
저작권자 © 테크월드뉴스 무단전재 및 재배포 금지