본문 바로가기

old drawer/Embedded

[Embedded] 크로스 컴파일 툴 체인

출처 : http://cafe.naver.com/devctrl.cafe

글쓴이 : 별빛 byeolbich@naver.com

 

크로스 컴파일러 툴 체인

 


1.
크로스 컴파일러란?

대부분의 프로그래머들은 PC라는 동일한 환경에서 프로그램을 작성하실 겁니다.

PC
에서 프로그램을 짜고 컴파일 하고, 실행 화일을 PC에서 수행 합니다
.
이렇게 동일한 환경에서 동작 되는 컴파일러와 이 컴파일러에서 생성된 실행 화일을 동일한 환경에서 수행 한다면 이때의 컴파일러를 네이티브( native ) 컴파일러라고 합니다
.
이와 반대로
컴파일러가 동작하는 시스템과 컴파일러에 의해서 생성된 실행 화일이 동작하는 시스템이 다를 때 이 컴파일러를 크로스(cross) 컴파일러라고 합니다
.

여러분이 임베디드 시스템에 동작하는 프로그램을 작성한다면 당연히 크로스 컴파일러 환경을 구축해야 합니다. 개발 환경은 PC일것이고 실행 화일이 동작하는 시스템은 다른 CPU 구성을 갖는 임베디드 시스템일 것이기 때문입니다. 그렇다고 모든 임베디드 시스템에 동작하는 프로그램들이 크로스 컴파일 환경을 필요로 하는 것은 아닙니다. PC와 같은 구조를 갖는 임베디드 리눅스 시스템을 만든다면 PC의 네이티브 컴파일러에서 만들어진 실행 화일이 그대로 수행될 수 있기 때문입니다
.
하지만 임베디드 시스템 대부분이 저렴한 가격대를 요구하거나, 또는 특수한 기능을 수행하는 구조를 가지기 때문에 이런 경우는 조금 드믄 편입니다. 그래도 개발 프로세스를 빠르게 진행하기 위해서 익숙한 PC 구조를 사용하는 경우도 요즘은 많아 지는 추세인 것 같습니다
.

어찌되었든 크로스 컴파일 환경에서의 개발은 윈도우 개발자 입장에서 보면 매우 열악한 개발 환경이 됩니다. 돈이 많은 회사야 좋은 개발 툴을 사서 이런 열악한 환경을 일부 개선하기는 하지만 그래도 열악하기는 마찬가지 입니다. 가장 큰 이유는 컴파일이 끝난 후 실행 화일을 즉시 시험하지 못하기 때문입니다. 그 외에도 개발하기 위해서 손가락이 무척 바빠지는 것도 한 요인입니다. 단순하게 마우스 클릭 한번으로 수행되는 GUI 컴파일러에 익순한 분들이 타자를 치는 것은 무척 힘든 것입니다
.
그래도 리눅스에서 크로스 컴파일러를 사용하는 것에는 이유가 있읍니다
.


2.
리눅스와 gcc


지금은 많은 분들이 임베디드 시스템 개발에 리눅스를 사용되고 있다는 것을 알고 있습니다.
하지만 그 이유가 리눅스 커널을 임베디드 시스템에 탑제하기 때문이라고 알고 계신다면 잘못 알고 계신 겁니다.
임베디드 시스템 개발 환경으로 리눅스를 사용하는 근본적인 이유는 gcc라는 막강한 컴파일러가 있기 때문입니다.


리눅스만 사용하시는 분이라면 리눅스 프로그램 개발을 위해서 당연히 gcc라는 컴파일러를 사용합니다. 그래서 gcc라는 것이 그냥 리눅스용 컴파일러라고 알고 있습니다. 하지만 gcc는 그렇게 단순한 컴파일러가 아닙니다. 또한 gcc는 그냥 i386 프로세서에서 동작하는 실행 화일을 만들어 내는 컴파일러도 아닙니다. 현재 존재 하는 컴파일러 중에서 가장 많은 프로세서를 지원하는 컴파일러가 바로 gcc입니다
.

gcc
컴파일러의 패케지는 이미 전세계에 동작되는 대부분의 프로세서를 지원하기 위한 준비를 갖추고 있습니다. 더구나 공짜입니다
. !!!
하지만 여러분은 이런 gcc가 어떻게 다른 CPU를 지원하게 할 수 있는지에 대해서는 모를 겁니다. 그냥 gcc 명령을 치면 i386 코드가 생성되기 때문입니다
.


3.
크로스 컴파일러와 gcc 소스 패키지


gcc
에서 i386 이외의 실행 화일을 만들기 위해서는 리눅스에 이미 설치된 gcc란 컴파일러는 소용이 없습니다. 몇 가지 옵션만 바꾸어서 gcc 수행한다고 i386 이외의 프로세서를 지원하는 코드가 생성되는 것은 아닙니다. 애초에 다른 프로세서에서 동작 될 수 있는 실행 파일을 만들 수 있겠끔 gcc를 만들어야 하는 것입니다. 그렇다고 기존에 i386에서 동작하는 gcc를 아예 다른 프로세서에서 동작하는 실행 파일을 만드는 gcc로 바꾸어 버리면 문제가 됩니다. 그 뒤로는 i386에 동작하는 어떤 프로그램도 만들 수 없기 때문입니다.
그래서 보통은 gcc의 이름을 조금 바꿉니다. 예를 들어 arm 계열의 프로세서에서 동작하는 실행 프로그램을 만들기 위해서 사용하는 gcc arm-linux-gcc라는 이름을 가집니다
.
이름이 다른 이 두 컴파일러는 전혀 다른 컴파일러가 아닌 똑같은 gcc인 것입니다. 단지 gcc i386 프로세서에서 수행되는 코드를 만들어 내는 컴파일러이고 arm-linux-gcc라는 것은 arm 프로세서에서 동작되는 코드를 만들어 내는 컴파일러 일 뿐입니다
.

관행적으로 네이티브용 컴파일러가 보통 gcc가 되고 크로스 컴파일러는 gcc 앞에 접두사를 붙입니다. 만약 알파 프로세서 동작하는 gcc에서 i386 계열의 실행 코드를 만드는 크로스 컴파일러는 i386-linux-gcc가 될 것입니다. (확인하지 않았습니다
. ^^ )
어찌되었든 둘 다 동일하게 gcc란 패키지에서 파생한 컴파일러인 것입니다
.

.... 제가 자꾸 gcc 패키지라는 말을 쓰고 있습니다. gcc 패키지라는 것이 무엇일까요? 윈도우에서 델파이라는 개발 툴을 구매해서 설치하면 단순하게 델파이 컴파일러만 설치되는 것이 아닙니다. 개발하기 위한 이것저것들이 설치 됩니다. 이와 동일한 개념으로
gcc 패키지란 컴파일을 하기 위한 이런 저런 것을 모두 담은 것을 말 하는 것입니다.

윈도우에서와 달리 리눅스에서는 패키지들이 소스로 구성되어 있습니다. 그래서 이런 것을 gcc를 예를 들면 gcc 소스 패키지 라고 말합니다
.

또 여러분이 착각하는 것중 하나가 gcc가 단순하게 c 컴파일러라고 알고 있는데 정확하게 이야기 하면 c 컴파일러가 아닙니다. c++ 소스를 컴파일 할 때 도 역시 gcc 를 사용합니다. 어셈블러를 컴파일 할 때 도 gcc를 사용할 수 있습니다. 그래서 gcc 소스 패키지에는 c 이외의 몇 가지 컴파일러들이 더 들어 있습니다
.
어찌되었든
gcc 소스 패키지란 gcc 컴파일러를 만들 수 있는 소스로 구성된 것을 말 합니다. gcc 소스 패키지를 이용하여 원하는 프로세스 지원 크로스(또는 네이티브) 컴파일러를 만드는 것입니다.


그런데 아주 모순 된 것 중 하나는 gcc를 만들기 위해서는 gcc가 필요하다는 점입니다. 왜냐하면 gcc 소스 패키지이기 때문입니다. 하지만 이점은 여기에서 문제 삼지 않으려 합니다. 여러분의 리눅스에는 당연히 gcc 컴파일러가 이미 설치되어 있기 때문입니다
.


4. gcc
의 짝꿍들


gcc
는 컴파일러입니다. 당연히 소스를 컴파일 할 수 있습니다. 그런데 gcc만 가지고 있어서는 아무런 일도 못합니다.
왜냐구요? 그 이유를 알고 싶으시다면 kelp/임베디드강좌/이규명 holelee 님이 쓰신 gcc 이야기 시리즈를 읽어 보시기 바랍니다
.
그래서
gcc 이외에 필요한 프로그램과 데이터(?)들이 있습니다. 이런 것을 모두 모은 것을 크로스 컴파일러 툴 체인이라고 합니다. 컴파일러 툴이라면 될 텐데 굳이 체인이라고 붙인 이유는 제 개인적인 생각으로는 각 패키지간에 서로 의존적이기 때문일 것으로 추측합니다
.

이 툴 체인의 목록은 다음과 같습니다
.
binutils -
어셈블러, 링커 그리고 라이브러리 관련 실행 화일들 모음
kernel -
리눅스 커널 ( 헤더 파일 때문에 필요함
)
gcc -
컴파일러

glibc -
라이브러리 및 헤더화일

추가적으로

gdb -
디버거 ( 이놈은 그냥 옵션으로 생각하시면 됩니다. ^^ ) 가 있읍니다
.

4.1 gcc
3.0 대의 속설(?)


많은 분들은 gcc 3.0 대에 문제가 있다고 알고 있어서 이 버전을 회피하시면서 예전 버전을 고집하시는 경향이 있습니다. 그런데 이 부분은 오해랍니다. 문제가 되는 버전은 gcc 3.0 입니다. 당연히 문제가 발생했으니 해당 버전을 고쳤겠지요 그래서 3.1 대 이후라면 별 문제는 없습니다
.
크로스 컴파일을 하시는 분이라면 최근 프로세스를 쓰기 위해서는 예전 버전으로는 한계가 있습니다. 최신 버전을 쓰셔야 지원되는 프로세스가 있습니다. 넘 겁먹지 마시고 3.0대를 쓰시기 바랍니다
.

4.2 binutils

바이너리 유틸 이라고 합니다. 포함되는 내용은 다음과 같죠
...

addr2line –
실행 파일의 어드레스에 대한 소스 화일명과 라인 넘버를 표현해주는 프로그램입니다
.
ar -
라이브러리를 관리하는 프로그램입니다
.
as -
어셈블러입니다
.
c++filt -
잘 모르겠습니다
. ^^
gasp -
어셈블러 매크로 해석기입니다
.
ld -
링커입니다
.
nm -
오브젝트안의 심볼릭을 표시해 주는 프로그램입니다
.
objcopy -
오브젝트 화일을 컨버팅 해주는 프로그램입니다
.
objdump -
오브젝트 화일의 정보를 표시해 줍니다
.
ranlib -
라이브러리의 인덱스 화일을 생성합니다
.
readelf - elf
포맷의 화일 헤더 정보를 해석해 줍니다
.
size -
오브젝트 화일의 섹션 크기와 포함된 오브젝트의 총 크기를 표시해 줍니다
.
strings -
프로그램 내부에 사용되는 초기화 문자열들을 골라 표시해 줍니다
.
strip -
오브젝트나 실행화일의 정보를 선택적으로 제거해 줍니다
.

4.3 kernel

크로스 컴파일러를 만들 때 사용되는 데이터 타입이나 시스템 콜을 참조하기 위해서 필요한 헤더 파일을 참조하기 때문에 툴 체인에 들어 갑니다. 엄밀히 말하면 kernel의 헤더 파일만 필요합니다
.

4.4 gcc

패키지가 일반적으로 지원하는 것은 각 언어별로 지원합니다. 다음은 크로스 컴파일러로 쓰는 대표적인 것 들입니다
.
gcc, cpp, g++, c++, gccbug, gcov
설명을 굳이 달지 않는 이유는 저는 gcc 이외에는 거의 쓰지 않기 때문에 뭐 하는 놈들인지 잘 몰라서 입니다. 이해해 주세요
...

4.5 glibc

커널을 컴파일 하거나 부트 로더를 컴파일 할 때는 필요 없습니다. 하지만 응용프로그램을 사용한다면 당연히 이것이 있어야 합니다. 여러분들 중에서 glibc newlib 를 혼동하시는 분들이 있습니다
.
glibc
GNU 라이브러리 입니다. 크기가 매우 커집니다
.
newlib
glibc가 매우 크기 때문에 꼭 필요한 놈들만 골라서 추려놓은 것이죠 그래서 크기가 매우 작습니다
.
특별한 경우가 아니라면 저는 newlib를 별로 추천하지 않습니다. 가끔 리눅스용 프로그램을 임베디드 제품에 포팅 하다보면 없는 함수가 있어서 곤란을 겪기 때문입니다
.
램이나 플래쉬 시스템이 16M 이상이고 여유가 있다면 가급적 glibc를 쓰시기를 권유합니다
.

4.6 gdb

이놈은 디버거죠.. 즉 프로그램을 디버깅 할때 유용한 도구 입니다. 하지만 윈도우 디버거를 사용하시던 분이라면 매우 불편함을 느끼실 겁니다. 하지만 없는 것 보다는 있는 것이 좋습니다. printf 만 가지고 디버깅 하시면 매우 힘들기 때문입니다. 더구나 익숙해지면 의외로 막강한 기능에 놀라시게 됩니다. 이 놈을 굳이 툴 체인에 포함시키지 않는 것은 상호 연관관계가 별로 없어서 입니다.

 

 

 


출처 : http://cafe.naver.com/devctrl.cafe

글쓴이 : 별빛 byeolbich@naver.com

 

 

ARM 용 크로스 컴파일 환경을 구축하기

 

 

 

1 개요
2
무엇을 구하는가
?
3
어디서 구하는가
?
4
설치 전 작업

5
설치 전 주의 사항

6 Binutils
패키지 설치

7
커널 소스 설치

8 gcc
패키지 설치

9 glibc
패키지 설치

10
잘되었나 시험을 해보자

11
결론

 

 

1 개요
이 문서는 이지보드를 위한 ARM 용 크로스 컴파일 환경을 구축하기 위한 방법중 RPM을 이용하는 방식이 아닌 GNU에서 제공하는 소스 패키지를 이용하여 구성하는 방식에 대하여 기술한 문서입니다.

 

2 무엇을 구하는가?
리눅스를 이용한 개발환경으로 선택했다면 크로스 컴파일 환경을 구축하여야 합니다.
이 크로스 컴파일 환경에 포함되는 것은 다음과 같은 패키지가 필요로 하고 이 패키지들의 모음을 일반적으로 크로스 컴파일 툴 체인이라고도 합니다.

 

1) binutils : 어셈블러 및 로더 기타 툴 ( GNU )
2) glibc :
크로스 컴파일 구축을 위한 라이브러리 및 일반 라이브러리

3) gcc :
컴파일러 ( 시그너스
)
4)
커널 : 커널 소스

 

소스 패키지로 구성하기 위해서는 목록에 해당하는 모든 패키지가 있어야 합니다.

3 어디서 구하는가?
그다음 간단한 방법은

http://www.linuxfromscratch.org

를 받는 방법입니다.

그러나 여기에는 툴 체인 이외에 매우 방대한 패키지가 포함되어 있습니다 무려 80M 가 넘습니다.
원론적인 방법은 다음에서 구하는 것입니다.


1) binutils :
어셈블러 및 로더 기타 툴 ( GNU )

구할수 있는 곳 과 파일
ftp://ftp.gnu.org/gnu/binutils/binutils-2.12.tar.gz

 

2) glibc : 크로스 컴파일 구축을 위한 라이브러리 및 일반 라이브러리

구할수 있는 곳 과 파일
ftp://ftp.gnu.org/gnu/glibc/glibc-2.2.4.tar.gz
ftp://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.2.4.tar.gz

 

3) gcc : 컴파일러 ( 시그너스 )

구할수 있는 곳 과 파일
ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3.tar.gz

4) 커널 : 커널 소스

 

4 설치 전 작업
다운 받은 화일 목록을 정리하면

1) binutils-2.12.tar.gz

2) linux-2.4.18-rmk7-ez1.tar.gz

3) gcc-2.95.3.tar.gz

4) gcc-2.95.3-2.patch.bz2

5) glibc-2.2.4.tar.gz

6) glibc-linuxthreads-2.2.4.tar.gz

등 총 6개가 됩니다.

 

설치하려고 하는 리눅스 머신에 다음 디렉토리를 만듭니다.

mkdir -p /var/download/

 

/var/download/ 에 다운 받은 화일을 가져다 놓습니다.

 

5 설치 전 주의 사항
이제부터 진행하는 순서는 꼭! 지켜야 합니다. 이유는 각 설치되는 패키지들의 의존 관계가 있기 때문입니다.
편리함을 위해 설치는 root 권한으로 하시기 바랍니다.

 

6 Binutils 패키지 설치
본강사가 하는대로 그냥 따라만 해도 별무리 없이 설치 될 것입니다.

[root@falinux /]# cd /var/download/

[root@falinux download]# tar zxvf binutils-2.12.tar.gz

[root@falinux binutils-2.12]# cd /var/download/

[root@falinux download]# cd binutils-2.12

[root@falinux binutils-2.12]# ./configure --target=arm-linux

[root@falinux binutils-2.12]# make

[root@falinux binutils-2.12]# make install


아마도 별 무리없이 끝났을 것입니다.

이 부분을 수행하고 나면 /usr/local/arm-linux 란 디렉토리가 생성됩니다.

이 부분을 실행환경 패스로 잡아 주어야 합니다.

 

설정할 내용은

PATH=$PATH:/usr/local/arm-linux/bin
입니다.

 

본강사는 대부분 root로 작업을 하지요...( 별로 안좋은 습관이나 편하다 ^^;)
그러므로 /root 밑에

".bash_profile"
화일에 위 내용을 추가 합니다
.
export
시키거나 로그아웃 한후 root로 로긴을 다시하면 됩니다.

 

7 커널 소스 설치
커널 소스를 Binutils 패키지 다음에 설치하는 이유는 헤더 화일 때문입니다.
크로스 컴파일 설치 목적이 ARM용 이라면 커널 소스는 암 패치까지 수행되어야 합니다.

여기서 설명하는 것은 스트롱암용이기 때문에 최소한 스트롱암 패치까지는 수행되어진 소스여야 됩니다.
이 문서에서는 linux-2.4.18-rmk7.ez1.tar.gz 소스를 사용 하는 것에 대하여 설명하겠습니다
.
참고로 커널 소스 위치가 고정될 필요는 없습니다

본 강사 경험에 따르면 수행되는 프로젝별로 커널 소스 관리를 하게 됩니다.
설치는 다음과 같은 순서를 따릅니다.

[root@falinux /]# cd /var/download/

[root@falinux download]# tar zxvf linux-2.4.18-rmk7-ez1.tar.gz

[root@falinux download]# cd linux-2.4.18-rmk7-ez1

[root@falinux linux-2.4.18-rmk7-ez1]# mkdir /usr/local/arm-linux/include

[root@falinux linux-2.4.18-rmk7-ez1]# cp -dR include/asm-arm /usr/local/arm-linux/include/asm

[root@falinux linux-2.4.18-rmk7-ez1]# cp -dR include/linux /usr/local/arm-linux/include/linux

[root@falinux linux-2.4.18-rmk7-ez1]# cd /usr/local/arm-linux/

[root@falinux arm-linux]# ln -s include sys-linux

8 gcc 패키지 설치

[root@falinux arm-linux]# cd /var/download/

[root@falinux download]# tar zxvf gcc-2.95.3.tar.gz

[root@falinux download]# bunzip2 gcc-2.95.3-2.patch.bz2

[root@falinux download]# cd gcc-2.95.3

[root@falinux gcc-2.95.3]# patch -Np1 -i ../gcc-2.95.3-2.patch

[root@falinux gcc-2.95.3]# cd gcc/config/arm/


t-linux
화일을 수정합니다.
t-linux
의 선두에 보면


TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC


이란 내용이 있는데 이것을

 TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h
으로 바꿔줍니다.


[root@falinux gcc-2.95.3]# mkdir ../gcc-build

[root@falinux gcc-2.95.3]# cd ../gcc-build #

[root@falinux gcc-build]# ../gcc-2.95.3/configure --target=arm-linux -v --with-gnu-as --with-gnu-ld --with-gnu-newlib [root@falinux gcc-build]# ../gcc-2.95.3/configure --target=arm-linux -v --with-gnu-as --with-gnu-ld

[root@falinux gcc-build]# make -w all-gcc install-gcc LANGUAGE="c c++"


인스톨까지 정상적으로 수정되었습니다.

 

9 glibc 패키지 설치

[root@falinux /]# cd /var/download/

[root@falinux download]# tar zxvf glibc-2.2.4.tar.gz

[root@falinux download]# cd glibc-2.2.4

[root@falinux glibc-2.2.4]# tar zxvf ../glibc-linuxthreads-2.2.4.tar.gz

[root@falinux glibc-2.2.4]# mkdir ../glibc-build

[root@falinux glibc-2.2.4]# cd ../glibc-build

[root@falinux glibc-build]# CC=arm-linux-gcc ../glibc-2.2.4/configure arm-linux --prefix=/usr/local/arm-linux --enable-add-ons --with-headers=/var/download/linux-2.4.18-rmk7-ez1/include --with-cpu=strongarm110 [root@falinux glibc-build]# make [root@falinux glibc-build]# make install

 

== 잘되었나 시험을 해보자 ==

[root@falinux /]# cd /var/download/

[root@falinux download]# vi test.c


#include <stdio.h>

main()

{

  printf( "OK GCC\n" );

}


[root@falinux download]# arm-linux-gcc -o test test.c

[root@falinux download]# file test test: ELF 32-bit LSB executable, Advanced RISC Machines ARM, version 1, dynamically linked (uses shared libs), not stripped

위와 같이 나오면 잘된 것입니다.

 

10 결론
9
항까지의 과정을 거치고 나면
/usr/local/arm-linux/
에 암용 크로스 컴파일 환경이 구축되게 됩니다
.
최근의 포팅 경험을 다시 비추어 보면 이 과정들이 다른 환경에서 100% 된다는 것은 아무도 보장 못합니다
.
만약 본강사와 똑같이 해보고 나서 안되는 문제에 대해서는 본강사도 어렵사리 한 결론이므로

출처는 어딘지 모르겠습니다.@@

'old drawer > Embedded' 카테고리의 다른 글

X86  (0) 2011.05.25