툴체인이란 여러 다른 컴포넌트로 이루어져 있다. 가장 중요한 것은 gcc 컴파일러 자체다. 또 gcc를 사 하기 위해 필요한 binutils도 포함된다. binutils는 바이너리를 다루는데 사용된다. 이 둘로 C 라이브러리 를 사용하는 것을 제외한 나머지 대부분과 커널을 컴파일 할 수 있다. 보통은 컴파일러를 컴파일하는 경우 부트스트랩에 관계된 문제 때문에 툴체인을 만드는 것이 간단치 않다.
이 장에서는 툴체인을 어떻게 만드는지 알아본다. 툴체인 만들기로 시간을 낭비하기 싫거나 시도 하기 싫다면 이미 만들어진 것을 사용해도 좋다.
경험에 의하면 혼자 만드는 툴체인의 경우 조심하지 않으면 나중에 사용할 때 어떤 형태의 이상한 결과 를 만들어낼지 모르기 때문에 검증된 이미 만들어진 툴체인을 사용하는 것이 좋다고 감히 말할 수 있다. 또 만들어보면 알겠지만 상당한 노력과 주의를 기울여야하기 때문에 이미 만들어진 것을 사용하는게 좋을 것이다.
그러나 한번 쯤은 경험으로라도 컴파일러를 만들고 이 것으로 프로그램을 만들어 사용해보기 바란다.
ARM 프로세서에 관한 툴체인은 http://www.arm.linux. org.uk 혹은 http://www.armlinux.org에서 찾기 바란다.
ARM 상에서 도는 Native 컴파일러의 안정화 버전 바이너리는 아래 사이에서 얻을 수 있다.
공식 ARM 리눅스 사이트에서 배포하는 것이다.
Embedian 버전은 gcc 2.95.2, binutils 2.9.5.0.37과 glibc 2.1.3을 포함한다. 인스톨은 간단해 데비안 시스템을 사용하면 apt를 사용해 쉽게 설치할 수 있다. 그러나 /usr/bin에 설치되므로 이미 시스템에 깔린 것에 엎어 쓰지 않도록 주의를 요한다.
LART 타르볼은 아래와 같은 것을 포함한다.
gcc 2.95.2
binutils 2.9.5.0.22
glibc 2.1.2
설치는 아래와 같이 한다.
mkdir /data mkdir /data/lart cd /data/lart bzip2 -dc somewhere/arm-linux-cross.tar.bz2 | tar xvf - |
그리고 /data/lart/cross/bin을 path에 추가해준다. C와 C++ 컴파일러는 arm-linux-gcc와 arm-linux-g++와 같이 명령을 사용해 실행할 수 있다.
컴팩 크로스 툴체인은 다음과 같은 것을 포함한다.
gcc 2.95.2
binutils 2.9.5.0.22
glibc 2.1.2 with international crypt library
설치는 아래와 같이 한다. 이 툴체인은 반드시 /skiff/local에 설치되야한다. 그리고 아래와 같이 심볼릭 링크를 만들어줘야한다.
ln -s /usr/src/linux/include/asm /skiff/local/arm-linux/include/asm ln -s /usr/src/linux/include/linux /skiff/local/arm-linux/include/linux |
우선 크로스 컴파일러를 만들어보자. root로 시작하는 것이 좋겠다. 혹은 적어도 설치할 땐 root로 할 필요가 있다. binutils와 gcc를 다음 사이트에서 다운 받는다.
인텔 SA1100 Assabet 보드에 관한 리눅스 개발 사이트를 참조하면 보다 자세한 사항을 알 수 있다. 인텔 사이트.
받은 파일이 /devel/arm/assabet에 들었다고 가정하고 그 디렉토리에서 다음과 같은 절차를 사용해 컴파일러를 만든다.
binutils
%cd /devel/arm/assabet %tar xzf binutils-2.11.2.tar.gz %cd binutils-2.11.2 %./configure --target=arm-linux --prefix=/usr/local/arm %make %make install |
configure할 때의 --target은 만들어질 binutils가 arm-linux용이란 것을 나타내고, --prefix는 만들어진 binutils가 설치될 디렉토리를 나타낸다.
설치된 디렉토리의 리스트는 다음과 같이 될 것이다.
drwxr-xr-x 4 root root 16 2월 26 09:58 arm-linux drwxr-xr-x 2 root root 4096 2월 26 09:58 bin drwxr-xr-x 2 root root 48 2월 26 09:58 include drwxr-xr-x 2 root root 4096 2월 26 09:58 lib drwxr-xr-x 3 root root 8 2월 26 09:58 man drwxr-xr-x 2 root root 1 2월 26 09:58 share |
정상적으로 만들어 졌으면 다음 절차에서 사용되게 하기 위해 path에 임시로 추가해 준다. bash를 사용한다고 가정했다.
export PATH=/usr/local/arm/bin:$PATH |
gcc
gcc를 만들기 위해선 리눅스 커널의 헤더 파일이 필요하다. 우선 커널 소스를 풀고 2개의 디렉토리를 링크해 준다. 사용된 커널은 원하는 버전을 받아 사용하기 바란다. 여기선 2.4.17을 사용했다.
%cd /devel/arm/assabet %tar xvjf linux-2.4.17.tar.bz2 %mv linux linux-2.4.17 %cd /usr/local/arm/arm-linux %mkdir include %cd include %ln -s /devel/arm/assabet/linux-2.4.17/include/asm-arm asm %ln -s /devel/arm/assabet/linux-2.4.17/include/linux linux %ls asm %ls linux %cd /devel/arm/assabet %tar xzf gcc-2.95.3.tar.gz %cd gcc-2.95.3 %./configure --target=arm-linux --prefix=/usr/local/arm %make LANGUAGES="c" |
make를 진행하는 중에 stdlib.h, unistd.h와 같은 몇 개의 파일이 없다고 에러가 날 것이다. ARM 리눅스 사이트에서 얻은 정보에 의하면, gcc/config/arm/t-linux란 파일을 수정하라고 되어있다.아래와 같이 수정한다.
%cd gcc/config/arm %vi t-linux |
제일 위에 있는 줄을 찾아보면 'TARGET_LIBGCC2_CFLAGS='란 줄이 있을 것이다. 이 줄의 끝에 '-Dinhibit_libc -D__gthr_posix_h'를 추가해 준다. 그리고 configure를 실행할 때 --disable-threads를 추가해 주고 다시 configure과 make를 실행한다.
%./configure --target=arm-linux --prefix=/usr/local/arm --disable-threads %make LANGUAGES="c" |
컴파일 후 에러가 나는 것 처럼 보이지만 에러 나도 필요한 파일은 만들어졌으므로 아래 명령으로 확인 한다. 만약 gcc/xgcc가 없다면 make가 제대로 되지 않은 것이다. 아래 명령의 출력은 'arm-linux'가된다.
%./gcc/xgcc -dumpmachine arm-linux |
위와 같이 출력된다면 제대로 된 것이므로 인스톨한다.
%make LANGUAGES="c" install |
glibc를 만드는 절차에선 커널의 version.h가 필요하다. version.h는 make dep를 하면 생성된다.
%cd /devel/arm/assabet %cd linux-2.4.17 %zcat ../patch-2.4.17-rmk5.gz | patch -p1 |
patch까지 적용하고 나서 Makefile을 수정한다. /devel/arm/assabet/linux-2.4.17/Makefile을 열어 'ARCH := arm'으로 수정하고 'CROSS_COMPILE =/usr/local/arm/bin/arm-linux-'으로 수정한다.
%make assabet_config %make config |
그냥 enter만 쳐서 일단 default setting으로 저장한다.
%make dep %find -name "version.h" |
version.h가 include/linux에 없다면 에러!
glibc가 설치될 디렉토리를 만들어 준다.
%mkdir /usr/local/arm/glibc %mkdir /usr/local/arm/glibc/arm-linux-glibc %cd /devel/arm/assabet %tar xzf glibc-2.1.3.tar.gz %cd glibc-2.1.3 %tar xzf ../glibc-linuxthreads-2.1.3.tar.gz %tar xzf ../glibc-crypt-2.1.tar.gz %CC=arm-linux-gcc ./configure arm-linux --build=i686-pc-linux-gnu \ --prefix=/usr/local/arm/glibc/arm-linux-glibc --enable-add-ons \ --with-headers=/devel/arm/assabet/linux-2.4.17/include %make %make install |
속도가 느린 호스트를 사용한다면 아마도 집에 퇴근하기 전에 make 실행해 놓고 집에 갔다 오면 에러가 나 있던지 제대로 컴파일이 되어 있던지 할 것이다. 전에 P-II 400MHz에서 약 1시간 걸린 기억이 있다. 현재 Athlon 1GHz에서 약 10분 걸린것 같다.
c++
c++ 컴파일러도 만들어보자.
%cd /devel/arm/assabet %cd gcc-2.95.3 %./configure --host=i686-pc-linux-gnu --target=arm-linux \ --prefix=/usr/local/arm \ --with-headers=/usr/local/arm/glibc/arm-linux-glibc/include \ --with-libs=/usr/local/arm/glibc/arm-linux-glibc/lib %make LANGUAGES="c c++" %make LANGUAGES="c c++" install |
테스트
다 만들어진 컴파일러, 라이브러리를 테스트 해본다. 테스트 전에 /usr/local/arm/bin이 패스에 설정됐는지 확인. 없다면 넣어 주거나 아래 compiler 명령에서 적당히 path를 삽입해 줄것.
%cat > hello.c /* * hello.c */ #include <stdio.h> int main() { printf("hello.\n"); return 0; } %arm-linux-gcc -o hello hello.c |
에러 없이 컴파일되고 hello가 만들어졌는지 확인할 것. 그리고 file 명령으로 만들어진 hello가 어떤 내용인지 확인해 본다. 아래 처럼 ELF이고 ARM용이면 OK.
%file hello hello: ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), not stripped |
여기까지 툴체인을 만들어 봤다. 커널이 잘 돌아간다면 만든 툴체인은 잘 동작한다고 봐도 될것이다.