[OS]/Embedded

[펌] ARM 용 최신 크로스 컴파일러 제작(1/2)

하늘을닮은호수M 2005. 6. 16. 13:29
반응형

ARM 용 최신 크로스 컴파일러 제작

글쓴이 : nanuix (2004년 10월 29일 오후 10:26)

========================================================
"ARM 용 최신 크로스 컴파일러 제작"
2004/ 10/ 01
NaNu9 in Null@Root nanuix at null2root.org
========================================================

0. 무한한 도전.

현재 나와있는 가장 최신 소스를 사용하여 크로스 컴파일러를 만들어 보겠습니다.
저는 상당히 삽질을 많이 했지만.. 이문서를 보시는 분은.. 그냥 따라해보면 만들어 질겁니다.

사용한 소스는 다음소스를 사용했으며..
1. binutils-2.15.91.0.1.tar.bz2
2. gcc-3.4.2.tar.bz2
3. glibc-2.3.3.tar.bz2

복잡한 설명보다.. 간단한 명령으로 구성되어 있으므로.. 리눅스와 조금만 친하면 누구나 가능하리라 생각합니다.

보실때 참고사항
1. 라인 첫글자 #은 Bash Script의 주석입니다. 자동으로 크로스 컴파일러를 만드는 스크립트를 만들려고 하다가...
2. 라인의 두번째 또는 세번째에 있는 $ 는 User Prompt 입니다.
3. 라인 끝에있는 ; 는 여러줄 입력할때 사용하는것 아시죠. 크로스 툴 만들때 일일이 한줄씩 입력할려니 귀찮아서..
4. 같은 명령이 중복되어 있을수도 있는데.. 테스트하면서 이것저것 해본 흔적입니다.
5. 다른 여러 문서에는 Tools을 만들때 root 계정으로 작업을 하시는데 여기서는 사용자 계정으로 작업을 하도록 되어 있습니다. root 계정으로 작업을 하면 자칫 라이브러리를 날려먹는다든지.. 상당히 위험하기 때문에 권하지 않습니다.


1. 준비사항

각 파일이 들어갈 곳을 만들고.. 패스를 설정 해준다.

#!/bin/sh
export HOME_DIR=/home/Xels <-- Xels 라는 계정을 만들어서 작업을 할때.
#export HOME_DIR=$HOME ; <-- 일반 계정으로 작업을 할때
export KNL_DIR=$HOME_DIR/knl ;
export PXA_DIR=$HOME_DIR/usr ;
export SRC_DIR=$HOME_DIR/src ;
export WRK_DIR=$HOME_DIR/wrk ;
export TST_DIR=$HOME_DIR/tst
export PATH=$PXA_DIR/bin:$HOME_DIR/bin:$PATH

cd $HOME_DIR
mkdir -p $KNL_DIR <-- 커널소스가 있는곳
mkdir -p $PXA_DIR <-- 컴파일된 바이너리 파일, 라이브러리 파일이 들어가는곳
mkdir -p $SRC_DIR <-- 작업할 소스가 있는곳
mkdir -p $WRK_DIR <-- 개발하는 파일이 있는곳
mkdir -p $TST_DIR <-- 간단히 테스트하는 파일이 있는곳


2. 사용할 커널작업

cd $KNL_DIR
wget
ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.21.tar.gz
wget ftp://ftp.arm.uk.linux.org/pub/linux/arm/kernel/v2.4/patch-2.4.21-rmk1.gz
wget ftp://ftp.arm.uk.linux.org/pub/linux/arm/people/nico/diff-2.4.21-rmk1-pxa1.gz

tar -xzf linux-2.4.21.tar.gz
mv linux-2.4.21 linux-2.4.21-rmk1-pxa1 ;
ln -s linux-2.4.21-rmk1-pxa1 linux
cd linux
gzip -cd ../patch-2.4.21-rmk1.gz | patch -p1
gzip -cd ../diff-2.4.21-rmk1-pxa1.gz | patch -p1

cd include
rm asm; ln -s asm-arm asm
cd asm
rm arch proc; ln -s arch-pxa arch; ln -s proc-armv proc

cd ../../
make menuconfig
cd ../
cp -dpR linux-2.4.21-rmk1-pxa1 linux-2.4.21-rmk1-pxa1-org


# ln -s $HOME_DIR $PXA_DIR/arm-linux

$ cd $PXA_DIR/arm-linux/
# $ mv lib lib.bak
$ ln -s ../lib/ lib


3. Binutils 컴파일

binutils-2.15.91.0.2.tar.bz2 버전도 컴파일에는 문제가 없으나.. glibc 컴파일 할때 내부 오류가 발생하는 문제가 있다.

# Build Binutils
cd $SRC_DIR
wget
ftp://ftp.kernel.org/pub/linux/devel/binutils/binutils-2.15.91.0.1.tar.bz2

tar -xjf binutils-2.15.91.0.1.tar.bz2
cd binutils-2.15.91.0.1
mkdir -p pxa;cd pxa
../configure --target=arm-linux --prefix=$PXA_DIR
# ../configure --target=arm-elf --prefix=$PXA_DIR --with-cpu=xscale
make && make install
cd ../..
rm -rf binutils-2.15.91.0.1


4. Gcc 컴파일

# Gcc 초벌 설치 <-- Newlib를 사용해도 된다.
cd $SRC_DIR
wget
ftp://ftp.gnu.org/gnu/gcc/gcc-3.4.2/gcc-3.4.2.tar.bz2

tar -xjf gcc-3.4.2.tar.bz2
cd gcc-3.4.2
perl -pi -e 's/^(TARGET_LIBGCC2_CFLAGS.*)/$1 -Dinhibit_libc -D__gthr_posix_h/' gcc/config/arm/t-linux
echo 'T_CFLAGS = -Dinhibit_libc -D__gthr_posix_h' >> gcc/config/arm/t-linux
mkdir -p pxa;cd pxa
../configure --target=arm-linux --prefix=$PXA_DIR --with-headers=$KNL_DIR/linux/include
--disable-shared --disable-threads --enable-languages=c
make && make install
# ls -la $PXA_DIR/bin ; arm-linux-gcc -v
cd ../..
rm -rf gcc-3.4.2
# 패치를 하지 않으면.. ~.h 파일을 찾지못하는 error 가 발생한다.


5. Glibc 설치

cd $SRC_DIR
wget
ftp://ftp.gnu.org/gnu/glibc/glibc-2.3.3.tar.bz2
wget ftp://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.3.3.tar.bz2

tar -xjf glibc-2.3.3.tar.bz2; tar -C glibc-2.3.3 -xjf glibc-linuxthreads-2.3.3.tar.bz2
cd glibc-2.3.3

patch -p0 < ../glibc-2.3.3-arm.giih.patch <-- 패치내용은 아래에서 참고.

$ vi Makeconfig

gnulib := -lgcc -lgcc_eh --> gnulib := -lgcc 이렇게 수정.
mkdir -p pxa ; cd pxa

# $ CC=arm-linux-gcc ../configure --host=arm-linux --build=i686-pc-cygwin --prefix=$PXA_DIR --with-cpu=xscale
# --with-headers=$KNL_DIR/linux/include --enable-add-ons=linuxthreads --enable-shared

# $ CC=arm-linux-gcc ../configure --host=arm-linux --build=i686-pc-cygwin --prefix=$PXA_DIR
# --with-headers=$KNL_DIR/linux/include --enable-shared --enable-add-ons=linuxthreads

# $ CC=arm-linux-gcc ../configure --host=arm-linux --build=i686-pc-linux-gnu --prefix=$PXA_DIR --with-cpu=xscale
# --with-headers=$KNL_DIR/linux/include --enable-add-ons=linuxthreads --enable-shared

$ CC=arm-linux-gcc ../configure --host=arm-linux --build=i686-pc-linux-gnu --prefix=$PXA_DIR
--with-headers=$KNL_DIR/linux/include --enable-add-ons=linuxthreads --enable-shared

make && make install
cd ../..
rm -rf glibc-2.3.3


# $ cd $PXA_DIR/arm-linux/ <-- 이부분은 앞에서 처리했슴.
# $ mv lib lib.bak
# $ ln -s ../lib/ lib

$ cd $PXA_DIR/lib --> 라이브러리 패치 (이부분이 생략되면 gcc 컴파일때 Error 발생)
$ strings libc.so
$ cp libc.so libc.so.org
# $ sed -e '/*** BUG/d' libc.so > libc.so.new
$ sed '/BUG/d' libc.so > libc.so.new
# $ vi libc.so
$ mv -f libc.so.new libc.so

$ strings libpthread.so
$ cp libpthread.so libpthread.so.org
# $ vi libpthread.so
$ sed '/BUG/d' libpthread.so > libpthread.so.new
$ mv -f libpthread.so.new libpthread.so

# $ cp $PXA_DIR/lib/libc.so $PXA_DIR/arm-linux/lib/libc.so
# $ cp $PXA_DIR/lib/libpthread.so $PXA_DIR/arm-linux/lib/libpthread.so


6. Gcc 재설치

cd $SRC_DIR
$ tar -xjf gcc-3.4.2.tar.bz2
$ cd gcc-3.4.2
$ mkdir pxa;cd pxa
# $ ../configure --target=arm-linux --prefix=$PXA_DIR
# $ make --> Error 발생... 그냥 넘어갈때가 없구먼...
#../../gcc/gthr-posix.h:46: error: parse error before "__gthread_key_t" <-- 이런 Error

$ ../configure --target=arm-linux --prefix=$PXA_DIR --exec-prefix=$PXA_DIR --with-headers=$PXA_DIR/include --libdir=$PXA_DIR/lib
$ make && make install --> Gcc 설치 성공
$ arm-linux-gcc -v <-- 확인

# $ cp -f ~/usr/arm-linux/lib/* ~/usr/lib/


7. 패치항목

o. patch file 만들기 참고

$ cp csu/Makefile csu/Makefile.org <-- 편집기로 수정하기전 파일을 Original file로 보관한다.
$ vi csu/Makefile

-CFLAGS-initfini.s = -g0 -fPIC -fno-inline-functions
+CFLAGS-initfini.s = -O1 -g0 -fPIC -fno-inline-functions

$ cp linuxthreads/Makefile linuxthreads/Makefile.org
$ vi linuxthreads/Makefile

-CFLAGS-pt-initfini.s = -g0 -fPIC -fno-inline-functions
+CFLAGS-pt-initfini.s = -O1 -g0 -fPIC -fno-inline-functions

$ cp sysdeps/generic/framestate.c sysdeps/generic/framestate.c.org
$ vi sysdeps/generic/framestate.c

#ifndef __USING_SJLJ_EXCEPTIONS__
frame_state_for = fallback_frame_state_for;
#else
frame_state_for = abort;
#endif

$ cp sysdeps/arm/machine-gmon.h sysdeps/arm/machine-gmon.h.org
$ vi sysdeps/arm/machine-gmon.h

-static void mcount_internal (u_long frompc, u_long selfpc);

#define _MCOUNT_DECL(frompc, selfpc)
-static void mcount_internal (u_long frompc, u_long selfpc)
+void mcount_internal (u_long frompc, u_long selfpc)

여기까지 수정을 했으면 패치파일을 만든다.

$ diff -uNr csu/Makefile.org csu/Makefile > ../glibc-2.3.3-arm.giih.patch
$ diff -uNr linuxthreads/Makefile.org linuxthreads/Makefile >> ../glibc-2.3.3-arm.giih.patch
$ diff -uNr sysdeps/generic/framestate.c.org sysdeps/generic/framestate.c >> ../glibc-2.3.3-arm.giih.patch
$ diff -uNr sysdeps/arm/machine-gmon.h.org sysdeps/arm/machine-gmon.h >> ../glibc-2.3.3-arm.giih.patch

이렇게 만들어진 glibc-2.3.3-arm.giih.patch 패치파일을 위에서 사용한다.


8. 마치며..

도움이 될지 모르겠네요..
잘못된 부분이나.. 보다 나은 방법도 있으면 과감히 태클주세요.
곧바로 검토하겠습니다.

반응형