반응형

라즈베리파이를 위해 새로 컴파일해 본 커널을 이용하여 시스템 콜 추가하는 작업을 해보았습니다.



최초 작성 2014. 10. 15.

최종 업데이트. 2017.11.11.  

 


현재 사용중인 커널 버전입니다.

pi@raspberrypi:~ $ uname -r
4.9.60-v7+




1.시스템 호출 번호 할당


커널 소스 디렉토리의 arch/arm/include/uapi/asm/unistd.h 파일에 새로 생성할 시스템 호출을 위한 고유번호를 할당합니다.

#define __NR_copy_file_range            (__NR_SYSCALL_BASE+391)
#define __NR_preadv2                    (__NR_SYSCALL_BASE+392)
#define __NR_pwritev2                   (__NR_SYSCALL_BASE+393)
#define __NR_pkey_mprotect              (__NR_SYSCALL_BASE+394)
#define __NR_pkey_alloc                 (__NR_SYSCALL_BASE+395)
#define __NR_pkey_free                  (__NR_SYSCALL_BASE+396)
#define __NR_helloworld                 (__NR_SYSCALL_BASE+397)



arch/arm/include/asm/unistd.h에 정의된 다음 값이 시스템 콜 마지막보다 크므로 변경할 필요는 없어 보입니다.

/*
* This may need to be greater than __NR_last_syscall+1 in order to
* account for the padding in the syscall table
*/
#define __NR_syscalls  (400)



2.시스템 호출 테이블에 시스템 호출 처리 함수를 등록


arch/arm/kernel/calls.S에 정의되어 있는데 unistd.h에서 정의했던 시스템 호출 처리함수의 시작 주소들이 들어있습니다.


/* 390 */       CALL(sys_mlock2)
               CALL(sys_copy_file_range)
               CALL(sys_preadv2)
               CALL(sys_pwritev2)
               CALL(sys_pkey_mprotect)
/* 395 */       CALL(sys_pkey_alloc)
               CALL(sys_pkey_free)
               CALL(sys_helloworld)



3.시스템 호출 처리 함수 구현


kernel/helloworld.c라는 파일을 만들고 아래 내용을 작성한다.


#include <linux/unistd.h>
#include <linux/kernel.h>



asmlinkage long sys_helloworld(void)
{
   printk( "[sys_helloworld] Hello World\n" );

   return 0;
}


 


4.Makefile에 추가


kernel/Makefile파일에 helloworld.o 추가


#
# Makefile for the linux kernel.
#

obj-y     = fork.o exec_domain.o panic.o \
           cpu.o exit.o softirq.o resource.o \
           sysctl.o sysctl_binary.o capability.o ptrace.o user.o \
           signal.o sys.o kmod.o workqueue.o pid.o task_work.o \
           extable.o params.o \
           kthread.o sys_ni.o nsproxy.o \
           notifier.o ksysfs.o cred.o reboot.o \
           async.o range.o smpboot.o ucount.o helloworld.o



5.커널을 컴파일한 후,  라즈베리파이로 복사했습니다.


(자세한 커널 컴파일 방법은 다음 포스팅에서 소개하고 있습니다.

Raspberry Pi 3를 위해 커널 크로스 컴파일하기(http://webnautes.tistory.com/547 ) )


$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage  -j4

$ scp arch/arm/boot/zImage  pi@192.168.43.142:/home/pi



라즈베리파이에서 커널 이미지를 /boot로 복사해줍니다.

pi@raspberrypi:~ $ sudo cp zImage /boot/kernel7.img



6. 리부팅 후 다음 소스코드를 라즈베리파이에서 직접 컴파일 하여 실행합니다.

#include <stdio.h>
#include <linux/unistd.h>
#define __NR_helloworld 397


void main()
{
      syscall( __NR_helloworld );
}


dmesg명령으로 확인하면 아래와 같은 문구가 보이게 됩니다.

[  135.364935] [sys_helloworld] Hello World



반응형

해본 것을 문서화하여 기록합니다.


포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
질문을 남겨주면 가능한 빨리 답변드립니다.


제가 쓴 책도 한번 검토해보세요 ^^

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기

댓글을 달아 주세요

">
  1. thumbnail
    김창대
    2016.03.24 11:39

    안녕하세요? 저도 영문을 몰라 헤매고 있었는데, 이 글을 보고 해결했습니다. 감사합니다.

    4배수 법칙의 근거는 모른다고 하셨는데,
    arch/arm/kernel/calls.S 제일 아랫부분에 있는

    #ifndef syscalls_counted
    .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
    #define syscalls_counted
    #endif
    .rept syscalls_padding
    CALL(sys_ni_syscall)
    .endr

    이 부분 때문인 것 같습니다.
    syscalls_padding = ((NR_syscalls + 3) & ~3) - NR_syscalls = NR_syscalls % 4
    가 되는 것 같고, 그 아래에 syscalls_padding 숫자만큼 sys_ni_syscall을 추가하니까요.

    왜 이런 padding이 들어갔는지까진 모르겠지만...cache라든가 memory에 align 맞추려고 한 건 아닐까 싶습니다.

    (저는 오드로이드 보드에서 작업하던 거라 코드가 약간 다를 수는 있습니다.)

  2. thumbnail
    2017.06.07 23:37

    비밀댓글입니다