====== 시스템 콜 이해하기 - 1.무작정 따라하기 ====== 리눅스에서 사용되는 시스템 콜(system call) 에 대한 이해와 이를 바탕으로 한 간단한 실습을 정리하고 있다. 교학사에서 나온 '커널 프로그래밍' 이라는 책을 기본으로 하고 있다. 참고로 이 책이 출간된지 4년이 흘렀다. 그래서 이 책에서 다루고 있는 내용들이 많이 달라졌을지 모르지만, 기본적인 큰 틀은 변함이 없다고 본다. 와우(wow) 리눅스 6.2(linux-2.2.14) 를 기준으로 하고 있다. 현재는 구할 길이 없는 관계로 여기서는 레드햇(redhat) 9(linux-2.4.20) 를 기준으로 한다. ====== 들어가기 전에 ====== 여기서는 간단하게 콘솔상에서 'hello world' 라는 문자를 출력하는 함수를 커널안에 넣어볼 것이다. 그후에 상위 어플리케이션에서 호출하여 확인하는 것까지 해볼 것이다. 레드햇 9 에는 기본적으로 2.4.20 커널이 있지만, 여기서는 바닐라 커널을 사용하지 않고 따로 2.4.22 커널을 받아서 사용할 것이다. 참고로 이 문서에서는 기본적인 작업들(압축해제와 컴파일 옵션, 커널 설치등)의 설명은 하지 않을 것이다. 이에 대한 사항은 다른 문서를 참고하기 바란다. 기본 커널 디렉토리는 /usr/src/linux 이다. ====== 시스템 콜 추가하기 ====== include/asm-i386/unistd.h 파일에 다음을 추가한다. #define __NR_alloc_hugepages 250 #define __NR_free_hugepages 251 #define __NR_exit_group 252 #define __NR_newsyscall 259 // 추가 /* user-visible error numbers are in the range -1 - -124: see */ arch/i386/kernel/entry.S 파일에 다음을 추가한다. .long SYMBOL_NAME(sys_ni_syscall) /* sys_remap_file_pages */ .long SYMBOL_NAME(sys_ni_syscall) /* sys_set_tid_address */ .long SYMBOL_NAME(sys_newsyscall) /* sys_set_tid_address */ // 추가 .rept NR_syscalls-(.-sys_call_table)/4 .long SYMBOL_NAME(sys_ni_syscall) .endr kernel 디렉토리 아래에 newfile.c 라는 파일을 만들고, 다음을 입력한다. #include #include #include #include asmlinkage int sys_newsyscall() { printk("hello world!!\n"); return(0); } 앞에서 만든 파일을 커널에 적재하기위해 kernel 디렉토리 아래의 Makefile 에 다음과 같이 추가한다. obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \ module.o exit.o itimer.o info.o time.o softirq.o resource.o \ sysctl.o acct.o capability.o ptrace.o timer.o user.o \ signal.o sys.o kmod.o context.o newfile.o // 추가 커널컴파일 후에 새로 만든 커널이미지로 부팅한다. 이제 어플리케이션 쪽 프로그램을 만들 차례다. 파일이름은 test.c 로 한다. 내용은 아래와 같다. #include #include _syscall0(int, newsyscall); main() { int i; i = newsyscall(); } 에러없이 컴파일 되어다면, a.out 파일이 생성되었을 것이다. 실행해보면 hello, world!! 가 출력될 것이다. ---- {{indexmenu>:#1|skipns=/^(wiki|etc|diary|playground)$/ skipfile=/^(todays|about|guestbook)$/ nsort rsort}} ----