먼저, Rebis 보드에 딸려 오는 커널 소스 파일을 작업 디렉토리로 복사한 후 압축을 푼다.

tar zxvf s3c2440_kernel2.4.18.tar.gz

cd s3c2440_kernel2.4.18


간단한 시스템 호출을 추가하기 kernel/sys.c 파일을 연후 제일 마지막에 다음 내용을 추가한다.

asmlinkage int sys_my_hello(int i) {
    printk("Hello %s\n", current->comm);
    return i + 1;
}
EXPORT_SYMBOL(sys_my_hello);


작성한 함수를 시스템 호출로 등록하기 위해 arch/arm/kernel 디렉토리에서 calls.S의 끝 부분쯤에 있는 __syscall_end: 바로 앞줄에 다음과 같이 추가한다.

    .long SYMBOL_NAME(sys_my_hello)

이렇게 하면 일단 시스템 호출이 등록된다. 하지만, 사용자가 이걸 호출할 때 번호를 알 수 있도록 하나를 더 추가해 주는 것이 좋다. 그것은 바로 include/asm/ 디렉토리에 있는 unistd.h 헤더 파일에 다음과 같은 내용을 추가하는 것이다. 이때 심볼 테이블내에서 sys_my_hello가 위치하는 번호를 알고 있어야 한다. 만약 그 번호가 226이라면 다음과 같이 작성하면 된다.

#define __NR_my_hello  (__NR_SYSCALL_BASE + 226)


이렇게 하고 나면 이제 커널 컴파일을 해서 보드에 올리면 된다.

커널 소스 디렉토리에서 다음 명령을 수행한다.

make clean
make dep
make zImage

다음에는 이것을 이용하는 어플리케이션을 작성해야 한다.
간단히 다음과 같이 작성한다.

#include <stdio.h>
#include <asm/unistd.h>

_syscall1(int, my_hello, int, i);

int main() {
    printf("Hello\n");
    my_hello(50);
    return 0;
}


이것을 컴파일 할 때에는 반드시 위에서 작성한 커널의 헤더 파일을 사용하도록 해 주어야 한다. 헤더 파일 경로를 바꾸기 위해서는 -I 옵션을 사용하면 된다.

arm-linux-gcc test.c -I~/Work/s3c2440_kernel2.4.18/include

하지만, 크로스 컴파일 환경에서 헤더 파일을 다시 설정해 주는 것도 번거롭기 때문에 컴파일러 안에 있는 헤더 파일을 수정하는 형태로 하겠다. 즉, asm/unistd.h 파일을 다시 수정하겠다.

vi /usr/local/arm/2.95.3/arm-linux/sys-include/asm/unistd.h


위 파일을 앞에서 unistd.h에 했던 것과 같은 방식으로 작성해 준다.

컴파일 된 코드를 보드에 올려서 테스트해 본다.


크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Daniel Kwon