리눅스에서 사용되는 시스템 콜(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 <asm-i386/errno.h> */

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 <linux/unistd.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
 
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 <linux/unistd.h>
#include <errno.h>
_syscall0(int, newsyscall);
main()
{
        int i;
        i = newsyscall();
}

에러없이 컴파일 되어다면, a.out 파일이 생성되었을 것이다. 실행해보면

hello, world!!

가 출력될 것이다.

  • computer/embedded/시스템_콜_이해하기_-_1.무작정_따라하기.txt
  • Last modified: 3 years ago
  • by likewind