본문 바로가기
Research/SystemProg

MIPS linux cross compiler 제작예제

by sunnyan 2005. 6. 15.
728x90
http://kelp.or.kr/korweblog/?story=04/06/04/0386624 KELP - Korea Embedded Linux Project 제목: MIPS linux cross compiler 제작예제

글쓴이: 이영진
글쓴날: 2004년 06월 04일 오후 08:59
URL : http://kelp.or.kr/korweblog/?story=04/06/04/0386624


안녕하세요. (주) 시그마컴 연구 3팀입니다.
ARM에 비해 상대적으로 이용자가 적은 MIPS에 관련된 글을 하나 올리겠습니다.

http://www.gnu.org에서 binutils, gcc, glibc, glibc-linuxthread를 다운 받는다.

작업디렉토리 : $(WORK) 에 다운 받은 파일들이 놓여있다고 가정한다. 굳이 target이란 디렉토리 밑에 작업 환경을 꾸민 이유는 관리하기에 단순무식해서 편하다는 장점때문이다. 작업한 시스템은 Mandrake 1.0 community 인가 하는 버전이고 binutil-2.15, gcc-3.4.0, glibc-2.3.2이며 따로 패치된 것이 아니다.
http://laronde.org/~brad/mips/mips-cross-toolchain/ 이 싸이트의 것을 그대로 따라한다. 또한 http://www.kegel.com/crosstool 에서도 많은 도움을 얻었다.

1 binutils
별로 어려운게 없다. 그냥 설치할 위치를 지정해 주고 target에다가 mipsel-linux 혹은 mips-linux를 적용해 주면 된다. libdir은 뭔지 나도 잘 모르겠다.

$ cd $(WORK)
$ tar xjf binutils-??.bz2
$ mkdir target; cd target; mkdir binutils
$ cd binutils
$ $(WORK)/binutils-??/configure --prefix=/opt/host/mispel-linux
--target=mipsel-linux --libdir='${exec_prefix}'/mipsel-linux/i386-linux/lib
$ make
$ sudo make install


2. static gcc #
완전한 gcc를 만들기 위해서는 glibc가 필요하지만 아직 glibc를 빌드 하기 전이다. 따라서 static버전의 c언어 컴파일러부터 제작한후에 glibc를 빌드하고 다시 gcc를 빌드하는 과정을 거친다. 이 과정에서 static gcc를 빌드 하기 위해서는 커널 헤더 파일과 시스템 헤더 파일이 필요하다. 다른 곳에서 만들어진 크로스 컴파일러의 것을 복사하거나 단순히 호스트의 /usr/include를 임시로 복사해서 사용할 수도 있다. 단 이때에도 커널 헤더파일은 해당 타겟 시스템 것을 복사하는 것이 좋다. 물론 이 방법들은 모두 에러 가능성을 다분히 지니고 있는 단점이 있다. 이 예제에서는 시스템 헤더 파일(/usr/include)을 작업 디렉토리에 복사하고 asm, asm-generic, linux 디렉토리를 커널 것으로 대체했다.
* 저도 이게 어느 수준의 헤더가 필요한지 잘 몰라서요. 보통은 비슷한 버전 대의 기존 도구의 헤더를 슬쩍 빌립니다. ^_^
binutils을 인스톨 한 후에 그 PATH의 바이너리들을 PATH에 걸어둔다. configure시에 enable-language 는 c만 지정하고 disable_shared옵션을 걸고 앞서 설명한 헤더 파일이 존재하는 디렉토리를 with-headers로 지정한다.

$ export PATH=/opt/host/mipsel-linux/bin:$PATH
$ cd $(WORK)
$ tar xjf gcc-??.bz2
$ cd target; mkdir gcc
$ cd gcc
$ sudo $(WORK)/gcc-??/configure --prefix=/opt/host/mipsel-linux
--target=mipsel-linux --enable-languages=c --disable-shared
--with-headers=/home/romntica/CCK/test/include
$ make
$ sudo make install
configure시에 sudo를 하는 것은 지정한 헤더파일($with-headers)과 함께 필요한 파일들을 $prefix/mipsel-linux/sys-include로 복사 하기 때문이다.

3 glibc #
자 이제 말도 많고 탈도 많은 glibc를 만들어보자. 많은 사람들이 이 부분에서 어려움을 호소하거나 포기하는 경우가 있다. 그렇지만 어려울 것 없다. 검색 엔진을 활용하면 된다.
google에서 mips glibc로 검색을 해보았더니 관련 패치에 관한 사이트가 몇 개 나왔다. 내용들을 잘 살펴보고 필요한 것을 적용하기만 하면 된다. 이 예제에서는 다음의 패치를 적용하였다. 물론 여기서 사용된 패치가 꼭 필요하거나 전혀 필요치 않다거나의 여부는 따지지 않는다. 꼭 이것뿐 만이 아니고 개발하려는 장치명으로 검색하시면 gcc나 binutils나 glibc에도 적용할 만한 유용한 패치가 많이 있습니다. 예를 들어 제가 도시바 TX49계열의 칩을 사용했는데 그냥 하면 MULTX인가?? 곱셈연산자를 활용을 못하는 것을 binutils를 패치하고나면 해당 연산자를 사용할 수 있게 해주는 패치가 있었습니다.
우선 linuxthread를 add-on하기 위해 glibc-?? 디렉토리의 서브디렉토리로 압축 해제해준다.
$ cd $(WORK)
$ tar xjf glibc-??.bz2
$ cd glibc-??
$ cd $(WORK)/target; mkdir glibc
$ cd glibc
$ tar xjf ../glibc-linuxthread-??.bz2

그리고 다음의 패치를 적용한다. (죄송합니다. 컴파일 전에 diff를 때렸어야 했는데 clean해도 깨끗이 안되는군요. 파일이 너무 커지다보니 실수로 지워버린 것도 있을 것입니다. 문의하시면 답변해 드리겠습니다.)
diff -urN glibc-2.3.2/Makeconfig glibc-2.3.2-fixed/Makeconfig
--- glibc-2.3.2/Makeconfig 2003-01-06 05:31:36.000000000 +0000
+++ glibc-2.3.2-fixed/Makeconfig 2004-06-04 16:39:10.711288024 +0000
@@ -637,7 +637,7 @@
$(foreach lib,$(libof-$(basename $(@F)))
$(libof-$(<F)) $(libof-$(@F)),$(CPPFLAGS-$(lib)))
$(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F)))
-override CFLAGS = -std=gnu99
+override CFLAGS = -std=gnu9x
$(filter-out %frame-pointer,$(+cflags)) $(sysdep-CFLAGS)
$(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) $(CFLAGS-$(@F))

diff -urN glibc-2.3.2/elf/dl-conflict.c glibc-2.3.2-fixed/elf/dl-conflict.c
--- glibc-2.3.2/elf/dl-conflict.c 2002-10-17 17:05:51.000000000 +0000
+++ glibc-2.3.2-fixed/elf/dl-conflict.c 2004-06-04 13:48:20.897496568 +0000
@@ -33,6 +33,7 @@
_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
ElfW(Rela) *conflictend)
{
+#ifndef _DL_HAVE_NO_ELF_MACHINE_RELA
if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_RELOC, 0))
_dl_printf ("nconflict processing: %sn",
l->l_name[0] ? l->l_name : rtld_progname);
@@ -64,4 +65,5 @@
for (; conflict < conflictend; ++conflict)
elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset);
}
+#endif
}
--- glibc-2.3.2/resolv/Makefile 2003-02-25 23:40:08.000000000 +0000
+++ glibc-2.3.2-fixed/resolv/Makefile 2004-06-04 18:46:07.402374976 +0000
@@ -93,6 +93,8 @@
tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace
$(objpfx)mtrace-tst-leaks: $(objpfx)tst-leaks.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@
+ifeq (no,$(cross-compiling))
ifneq (no,$(PERL))
tests: $(objpfx)mtrace-tst-leaks
endif
+endif
diff -urN glibc-2.3.2/stdio-common/sscanf.c glibc-2.3.2-fixed/stdio-common/sscanf.c
--- glibc-2.3.2/stdio-common/sscanf.c 2002-08-10 18:09:08.000000000 +0000
+++ glibc-2.3.2-fixed/stdio-common/sscanf.c 2004-06-04 14:15:10.784756504 +0000
@@ -27,9 +27,7 @@
/* Read formatted input from S, according to the format string FORMAT. */
/* VARARGS2 */
int
-sscanf (s, format)
- const char *s;
- const char *format;
+sscanf (const char *s, const char *format, ...)
{
va_list arg;
int done;
diff -urN glibc-2.3.2/string/bits/string2.h glibc-2.3.2-fixed/string/bits/string2.h
--- glibc-2.3.2/string/bits/string2.h 2002-05-25 06:09:18.000000000 +0000
+++ glibc-2.3.2-fixed/string/bits/string2.h 2004-06-04 17:50:57.070621896 +0000
@@ -76,7 +76,7 @@
use unaligned memory accesses. */
# define __STRING2_COPY_TYPE(N)
typedef struct { unsigned char __arr[N]; }
- __STRING2_COPY_ARR##N __attribute__ ((packed))
+ __attribute__ ((__packed__)) __STRING2_COPY_ARR##N
__STRING2_COPY_TYPE (2);
__STRING2_COPY_TYPE (3);
__STRING2_COPY_TYPE (4);
diff -urN glibc-2.3.2/sysdeps/mips/Makefile glibc-2.3.2-fixed/sysdeps/mips/Makefile
--- glibc-2.3.2/sysdeps/mips/Makefile 2000-09-06 20:26:50.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/mips/Makefile 2004-06-04 17:53:16.754386736 +0000
@@ -6,3 +6,11 @@
ifeq ($(subdir),setjmp)
sysdep_routines += setjmp_aux
endif
+
+ifeq ($(subdir),csu)
+ifeq (yes,$(build-shared))
+# Compatibility
+sysdep_routines += divdi3
+shared-only-routines += divdi3
+endif
+endif
diff -urN glibc-2.3.2/sysdeps/mips/dl-machine.h glibc-2.3.2-fixed/sysdeps/mips/dl-machine.h
--- glibc-2.3.2/sysdeps/mips/dl-machine.h 2003-02-12 09:42:22.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/mips/dl-machine.h 2004-06-04 13:49:03.153072744 +0000
@@ -55,7 +55,9 @@
to avoid the asserts in dl-lookup.c from blowing. */
#define ELF_MACHINE_JMP_SLOT R_MIPS_REL32
#define elf_machine_type_class(type) ELF_RTYPE_CLASS_PLT
-
+
+/* MIPS doesn't support RELA */
+#define _DL_HAVE_NO_ELF_MACHINE_RELA
/* Translate a processor specific dynamic tag to the index
in l_info array. */
#define DT_MIPS(x) (DT_MIPS_##x - DT_LOPROC + DT_NUM)
diff -urN glibc-2.3.2/sysdeps/mips/mips64/bsd-_setjmp.S glibc-2.3.2-fixed/sysdeps/mips/mips64/bsd-_setjmp.S
--- glibc-2.3.2/sysdeps/mips/mips64/bsd-_setjmp.S 2002-12-31 19:13:27.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/mips/mips64/bsd-_setjmp.S 2004-06-04 13:55:25.649924384 +0000
@@ -22,6 +22,7 @@
in setjmp doesn't clobber the state restored by longjmp. */

#include <sysdep.h>
+#include <sys/asm.h>

#ifdef __PIC__
.option pic2
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/bits/mman.h glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/bits/mman.h
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/bits/mman.h 2001-07-07 19:21:35.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/bits/mman.h 2004-06-04 14:02:26.079009448 +0000
@@ -59,6 +59,8 @@
# define MAP_DENYWRITE 0x2000 /* ETXTBSY */
# define MAP_EXECUTABLE 0x4000 /* mark it as an executable */
# define MAP_LOCKED 0x8000 /* pages are locked */
+# define MAP_POPULATE 0x10000
+# define MAP_NONBLOCK 0x20000
#endif

/* Flags to `msync'. */
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/bits/siginfo.h glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/bits/siginfo.h
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/bits/siginfo.h 2002-12-05 00:22:19.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/bits/siginfo.h 2004-06-04 13:59:42.053945048 +0000
@@ -119,8 +119,10 @@
signals. */
enum
{
- SI_ASYNCNL = -6, /* Sent by asynch name lookup completion. */
+ SI_ASYNCNL = -60, /* Sent by asynch name lookup completion. */
# define SI_ASYNCNL SI_ASYNCNL
+ SI_TKILL = -6,
+# define SI_TKILL SI_TKILL
SI_SIGIO, /* Sent by queued SIGIO. */
# define SI_SIGIO SI_SIGIO
SI_MESGQ, /* Sent by real time mesq state change. */
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/clone.S glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/clone.S
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/clone.S 2001-07-07 19:21:35.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/clone.S 2004-06-04 13:09:34.246201328 +0000
@@ -63,7 +63,7 @@
syscall

bnez a3,error
- beqz v0,__thread_start
+ beqz v0,.Lthread_start

/* Successful return from the parent */
addiu sp,32
@@ -85,6 +85,7 @@
debug info. */

ENTRY(__thread_start)
+.Lthread_start:
/* cp is already loaded. */
.cprestore 16
/* The stackframe has been created on entry of clone(). */
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/kernel_stat.h glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/kernel_stat.h
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/kernel_stat.h 2000-11-20 08:45:43.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/kernel_stat.h 2004-06-04 15:51:16.873177824 +0000
@@ -1,3 +1,5 @@
+#ifndef _KERNEL_STAT_H
+#define _KERNEL_STAT_H 1
/* Definition of `struct stat' used in the kernel.. */
struct kernel_stat
{
@@ -26,3 +28,4 @@
unsigned int st_flags;
unsigned int st_gen;
};
+#endif
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pread.c glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pread.c
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pread.c 2003-01-27 18:55:20.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pread.c 2004-06-04 14:09:59.519076080 +0000
@@ -34,6 +34,24 @@
# endif
# define __NR_pread __NR_pread64
#endif
+#ifdef __NR_O32_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_O32_pread
+# error "__NR_O32_pread and __NR_O32_pread64 both defined???"
+# endif
+# define __NR_O32_pread __NR_O32_pread64
+#endif
+#ifdef __NR_N32_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N32_pread
+# error "__NR_N32_pread and __NR_N32_pread64 both defined???"
+# endif
+# define __NR_N32_pread __NR_N32_pread64
+#endif
+#ifdef __NR_N64_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N64_pread
+# error "__NR_N64_pread and __NR_N64_pread64 both defined???"
+# endif
+# define __NR_N64_pread __NR_N64_pread64
+#endif

#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0

diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pread64.c glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pread64.c
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pread64.c 2003-01-27 18:55:20.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pread64.c 2004-06-04 14:10:25.987052336 +0000
@@ -33,6 +33,25 @@
# endif
# define __NR_pread __NR_pread64
#endif
+#ifdef __NR_O32_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_O32_pread
+# error "__NR_O32_pread and __NR_O32_pread64 both defined???"
+# endif
+# define __NR_O32_pread __NR_O32_pread64
+#endif
+#ifdef __NR_N32_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N32_pread
+# error "__NR_N32_pread and __NR_N32_pread64 both defined???"
+# endif
+# define __NR_N32_pread __NR_N32_pread64
+#endif
+#ifdef __NR_N64_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N64_pread
+# error "__NR_N64_pread and __NR_N64_pread64 both defined???"
+# endif
+# define __NR_N64_pread __NR_N64_pread64
+#endif
+

#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0

diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pwrite.c glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pwrite.c
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pwrite.c 2003-01-27 18:55:20.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pwrite.c 2004-06-04 14:11:12.383998928 +0000
@@ -34,6 +34,24 @@
# endif
# define __NR_pwrite __NR_pwrite64
#endif
+#ifdef __NR_O32_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_O32_pwrite
+# error "__NR_O32_pwrite and __NR_O32_pwrite64 both defined???"
+# endif
+# define __NR_O32_pwrite __NR_O32_pwrite64
+#endif
+#ifdef __NR_N32_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N32_pwrite
+# error "__NR_N32_pwrite and __NR_N32_pwrite64 both defined???"
+# endif
+# define __NR_N32_pwrite __NR_N32_pwrite64
+#endif
+#ifdef __NR_N64_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N64_pwrite
+# error "__NR_N64_pwrite and __NR_N64_pwrite64 both defined???"
+# endif
+# define __NR_N64_pwrite __NR_N64_pwrite64
+#endif

#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0

diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pwrite64.c glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pwrite64.c
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/pwrite64.c 2003-01-27 18:55:20.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/pwrite64.c 2004-06-04 14:11:34.494637600 +0000
@@ -33,7 +33,24 @@
# endif
# define __NR_pwrite __NR_pwrite64
#endif
-
+#ifdef __NR_O32_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_O32_pwrite
+# error "__NR_O32_pwrite and __NR_O32_pwrite64 both defined???"
+# endif
+# define __NR_O32_pwrite __NR_O32_pwrite64
+#endif
+#ifdef __NR_N32_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N32_pwrite
+# error "__NR_N32_pwrite and __NR_N32_pwrite64 both defined???"
+# endif
+# define __NR_N32_pwrite __NR_N32_pwrite64
+#endif
+#ifdef __NR_N64_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_N64_pwrite
+# error "__NR_N64_pwrite and __NR_N64_pwrite64 both defined???"
+# endif
+# define __NR_N64_pwrite __NR_N64_pwrite64
+#endif
#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0

extern ssize_t __syscall_pwrite (int fd, const void *__unbounded buf, size_t count,
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/syscalls.list glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/syscalls.list
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/syscalls.list 2003-01-31 03:39:32.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/syscalls.list 2004-06-04 17:54:47.274625568 +0000
@@ -32,50 +32,12 @@
socket - socket i:iii __socket socket
socketpair - socketpair i:iiif __socketpair socketpair

-#
-# These are defined locally because the caller is also defined in this dir.
-#
-s_llseek llseek _llseek i:iiipi __syscall__llseek
-s_sigaction sigaction sigaction i:ipp __syscall_sigaction
-s_ustat ustat ustat i:ip __syscall_ustat
-sys_mknod xmknod mknod i:sii __syscall_mknod
-
# System calls with wrappers.
+s_readahead EXTRA readahead i:iipi __syscall_readahead
rt_sigaction - rt_sigaction i:ippi __syscall_rt_sigaction
rt_sigpending - rt_sigpending i:pi __syscall_rt_sigpending
rt_sigprocmask - rt_sigprocmask i:ippi __syscall_rt_sigprocmask
rt_sigqueueinfo - rt_sigqueueinfo i:iip __syscall_rt_sigqueueinfo
rt_sigsuspend - rt_sigsuspend i:pi __syscall_rt_sigsuspend
rt_sigtimedwait - rt_sigtimedwait i:pppi __syscall_rt_sigtimedwait
-s_execve EXTRA execve i:spp __syscall_execve
-s_exit _exit exit i:i __syscall_exit
-s_fcntl fcntl fcntl i:iiF __syscall_fcntl
-s_fcntl64 fcntl64 fcntl64 i:iiF __syscall_fcntl64
-s_fstat64 fxstat64 fstat64 i:ip __syscall_fstat64
-s_ftruncate64 ftruncate64 ftruncate64 i:iiii __syscall_ftruncate64
-s_getcwd getcwd getcwd i:pi __syscall_getcwd
-s_getdents getdents getdents i:ipi __syscall_getdents
-s_getdents64 getdents getdents64 i:ipi __syscall_getdents64
-s_getpriority getpriority getpriority i:ii __syscall_getpriority
-s_ipc msgget ipc i:iiiip __syscall_ipc
-s_lstat64 lxstat64 lstat64 i:sp __syscall_lstat64
-s_mmap2 mmap64 mmap2 b:aniiii __syscall_mmap2
-s_poll poll poll i:pii __syscall_poll
-s_pread64 pread64 pread i:ibniii __syscall_pread
-s_ptrace ptrace ptrace i:iipp __syscall_ptrace
-s_pwrite64 pwrite64 pwrite i:ibniii __syscall_pwrite
-s_readahead EXTRA readahead i:iiii __syscall_readahead
-s_reboot reboot reboot i:iii __syscall_reboot
-s_setrlimit setrlimit setrlimit i:ip __syscall_setrlimit
-s_sigpending sigpending sigpending i:p __syscall_sigpending
-s_sigprocmask sigprocmask sigprocmask i:ipp __syscall_sigprocmask
-s_stat64 xstat64 stat64 i:sp __syscall_stat64
-s_truncate64 truncate64 truncate64 i:siii __syscall_truncate64

-# Todo: we can pass 6 args in registers, no need for the wrapper
-sys_sysctl sysctl _sysctl i:p __syscall__sysctl
-sys_fstat fxstat fstat i:ip __syscall_fstat
-sys_lstat lxstat lstat i:sp __syscall_lstat
-sys_readv readv readv i:ipi __syscall_readv
-sys_stat xstat stat i:sp __syscall_stat
-sys_writev writev writev i:ipi __syscall_writev
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/mips/xstatconv.c glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/xstatconv.c
--- glibc-2.3.2/sysdeps/unix/sysv/linux/mips/xstatconv.c 2001-07-07 19:21:35.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/mips/xstatconv.c 2004-06-04 15:47:51.887340408 +0000
@@ -18,6 +18,11 @@
02111-1307 USA. */

#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <string.h>


static inline int
diff -urN glibc-2.3.2/sysdeps/unix/sysv/linux/sys/epoll.h glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/sys/epoll.h
--- glibc-2.3.2/sysdeps/unix/sysv/linux/sys/epoll.h 2002-12-16 23:24:21.000000000 +0000
+++ glibc-2.3.2-fixed/sysdeps/unix/sysv/linux/sys/epoll.h 2004-06-04 17:59:29.871664288 +0000
@@ -19,6 +19,7 @@
#ifndef _SYS_EPOLL_H
#define _SYS_EPOLL_H 1

+#include <stdint.h>
#include <sys/types.h>


@@ -44,6 +45,8 @@
#define EPOLLERR EPOLLERR
EPOLLHUP = 0x010
#define EPOLLHUP EPOLLHUP
+ EPOLLET = (1<<31)
+#define EPOLLET EPOLLET
};


패치가 끝났으면 이제 glibc를 만들어 보자. 물론 한번에 될 거라곤 생각 않는다. 나도 이 예제를 무려 세 번이나 다시 빌드해서 성공했다. gcc와 glibc의 버전에 따른 문제에 기인했던 것 같다. 문제가 발생하면 찾아보고 모르겠으면 다시 또 인터넷을 뒤져보자! 아 주의할 사항은 prefix를 /usr로 줘야 한다는 것이다. glibc가 /usr인 prefix는 특별하게 다룬다고 한다.

$ CFLAGS="-O2 -g -finline-limit=10000 -fno-unit-at-a-time" ../../glibc-??/configure --prefix=/usr --build=i686-linux --host=mipsel-linux --enable-add-ons
$ make
$ make install install_root=/opt/host/mipsel-linux/glibc
이렇게 하면 glibc에 인스톨이 된다.
glibc/lib/* 과 glibc/usr/lib/*을 /opt/host/mipsel-linux/mipsel-linux/lib에 복사한다. 또한 glibc/usr/include/*를 /opt/host/mipsel-linux/mipsel-linux/include로 복사한다. 나머지 glibc의 기타 등등은 옵션으로 각각에 맞게 /opt/host/mipsel-linux/mipsel-linux에다가 복사해 넣으면 된다. 이때 복사를 하면서 lib/*이하에 소프트링크가 깨진 것들이 있는데 걍 놔둬두 무방한것도 있고 필요에 따라 수정해 주면 된다. glibc이하는 삭제해도 좋다.

4 gcc 다시 만들기
이제 완전한 버전의 GCC를 다시 만들기만 하면 된다. 해당 작업디렉토리로 가서 깔끔하게 이전에 static으로 만들었던 것을 싹 지우고 다시 만든다.
$ cd $(WORK)/target/gcc
$ rm -rf *
$ $(WORK)/gcc-??/configure --prefix=/opt/host/mipsel-linux
--target=mipsel-linux --enable-languages=c,c++
$ make
$ sudo make install

자 이제 모든 것이 끝났다.

그러나 본인이 여러분에게 권하는 것은 이미 만들어져 널리 쓰이는 툴을 이용하라는 겁니다.

이런짓은 반드시 꼬옥~ 해야 할때만 해야 하는 것이고 나처럼 널널한 사람만 재미로 해보는 것일 뿐입니다.

DDK가 온다면 DDK것을 그대로 이용하시면 되고 그렇지 않더라도 가장 비슷한 것을 찾아서 이용하면 됩니다. 이런 것 만들줄 몰라도 남이 만든걸 이용해서 더 멋진 것을 만든다면 그걸로도 굉장히 큰 행운이라고 생각합니다.

요청이 있으면 예제로 만든 CCK를 자료실에 올리겠습니다만..

압축해도 100메가 넘을것 같습니다만 ㅡ,ㅡ;;;;
KELP - Korea Embedded Linux Project

728x90