[t:/]$ 지식_

커널 시스템 콜 추가

2011/03/23

0. 빌드 환경

빌드 환경은 우분투 10.10을 기준으로 한다.

1. 커널 빌드 준비

커널 빌드에 필요한 툴을 설치한다.

$ sudo apt-get install fakeroot kernel-wedge build-essential makedumpfile kernel-package
$ sudo apt-get build-dep linux
$ sudo apt-get build-dep --no-install-recommends linux-image-$(uname -r)
$ sudo apt-get source linux-image-$(uname -r)
$ sudo apt-get install libncurses5 libncurses5-devel

2. 시스템 콜 번호를 추가한다.

linux/arch/x86/include/asm/unistd_32.h를 수정한다. (364라인)

…
#define __NR_rt_tgsigqueueinfo  335
#define __NR_perf_event_open    336
#define __NR_recvmmsg           337
#define __NR_dawnsea            338  // 마지막 콜 번호에 +1 한 것이다.
#ifdef __KERNEL__
#define NR_syscalls 339
… 

3.

시스템 콜 심볼을 추가한다.

linux/arch/x86/kernel/syscal_table_32.S의 마지막에 다음과 같이 추가한다.

        .long sys_perf_event_open
        .long sys_recvmmsg
        .long sys_dawnsea_read          // 빌드 할 때 asmlinakge함수의 심볼을 찾을 수 있도록

4. 시스템 콜 코드를 추가한다.

linux/kernel/dawnsea.c 에 다음과 같이 추가했다.

#include <linux/kernel.h>  // 커널 요소를 작성하기 위한 헤더파일.
int dawnseaX = 10;  // 커널 전역변수 한 개에 10을 할당
asmlinkage int sys_dawnsea_read()  // 시스템 콜 함수 선언
{
        printk("dawnsea : Hello!!, I’m in Kernel\n");  // 커널 메시지 출력
        return dawnseaX;  // dawnseaX를 리턴
}
```c
linux/arch/x86/include/asm/syscalls.h 를 열고 함수 선언을 추가한다.

```c
asmlinkage int sys_dawnsea();
```c

### 5. 빌드가 정상적으로 되도록 Makefile 을 수정한다.

linux/kernel/Makefile 의 obj-y 에 dawnsea.o 를 추가했다.

### 6. 커널 빌드, 설치 재부팅

```bash
fakeroot make-kpkg --initrd --append-to-version=dawnseahw1 kernel-image kernel-headers -j 4

생성된 deb 이미지를 dpkg -i 명령어로 설치한 후 재부팅 한다.

7. 새로 만든 시스템 콜을 사용하는 사용자 프로그램을 작성한다.

2.6.18 이후 버전 부터는 _syscallN 매크로가 사라졌으므로 syscall 함수를 사용한다.
/usr/include/bits/syscall.h에 시스템 콜 번호를 추가한다. (#define SYS_dawnsea __NR_dawnsea)

// 시스템 콜 테스트 코드

#include <linux/unistd.h>
#include <sys/syscall.h>
/// _syscall0(int, dawnsea);

main()
{
        int i;
//      i = dawnsea();
        i = syscall(SYS_dawnsea);
        printf("syscall return = %d\n", i);
        return 0;
}

8. 컴파일 및 실행

gcc -o dawnsea_test dawnsea_test.c
./dawnsea_test

9. 결과

시스템 콜이 반환한 값을 정상적으로 확인할 수 있다.

dawnsea@dawnsea-Lenovo-G460:~$ ./dawnsea_test\
syscall return = 10  

printk가 출력한 커널 메시지를 확인 할 수 있다.

dawnsea@dawnsea-Lenovo-G460:~$ tail /var/log/messages  

Mar 23 21:10:38 dawnsea-Lenovo-G460 kernel: [16989.924202] dawnsea : Hello!!, I’m in Kernel








[t:/] is not "technology - root". dawnsea, rss