kernel에 system call 추가[ubuntu]

2020. 12. 28. 01:55Computer Science

이 포스팅의 목적은 kernel을 직접 컴파일하고, 기존의 kernel에 새로운 system call을 추가한 후 이를 호출할 수 있는 user program을 구현하는 것이다. system call시 전달 받은 정수형 인자를 printk로 출력하도록 하는 커널과 user program을 간단히 구현해보자.
(가상환경 설정에 대해서는 굳이 다루지 않겠습니다. 다른 포스팅에도 많으니까요..)

우리가 구현해야할 목표는 두가지로 나뉜다.

1. kernel
: system call시 전달받은 정수형 인자를 printk로 출력

2. user process
1) syscall 함수를 이용해서 새로 작성한 system call을 호출하도록 한다.
2) system call의 인자로 정수형 숫자를 넘겨준다.


커널 코드를 수정하기 위한 파일은 다음과 같이 4가지가 있다.

  • syscall_64.tbl (혹은 32비트 가상 머신의 경우 32.tbl)
  • syscalls.h
  • 새로 추가할 시스템 콜의 소스
  • Makefile
(linux)/arch/x86/entry/syscalls/syscall_64.tbl #시스템콜 고유 번호 저장을 위한 파일 경로

위 syscall_64.tbl은 본인이 만들고자 하는 시스템 콜의 숫자와 함수 이름을 설정해주면 된다. 본인의 경우 print_number라는 함수를 선언했다.


다음은 syscalls.h 파일을 수정해야 한다. syscalls.h 파일에는 시스템 콜 함수들의 proto type이 정의되어 있다.

(linux)/include/linux/syscalls.h #syscall.h 경로

본인은 asmlinkage를 사용하여 함수를 선언했다. asmlinkage를 사용할 경우 어셈블리 코드에서도 호출이 가능하다.


다음은 새로 추가할 시스템 콜 소스이다. 본인은 c파일로 구현을 하고자 한다.

/usr/src/linux-5.9.1/kernel/ #kernel 파일 하위에 c 파일 생성할 것

kernel 파일의 경우 단순히 구현을 해서는 user program에서 호출되지 않는다. system call을 호출하는 방법 중에 syscall 매크로를 사용하는 방법이 있다. 전달하고자 하는 인자의 개수에 따라 syscall0~syscall6까지 존재한다.

SYSCALL_DEFINE'전달하고자하는 인자의 개수'('선언한 함수의 이름', '전달하고자 하는 인자의 자료형, 매개변수)

로 사용하면 된다.

#include <linux/linkage.h> 
#include <linux/kernel.h> 
#include <linux/syscalls.h> 
SYSCALL_DEFINE1(print_number, int num){ printk("num = %d \n ", num) }

참고로 kernel 파일의 경우 printf가 아닌 printk로 출력해야 정상적으로 작동한다. 유의 하시길.


Makefile의 경우 아래 경로에 따라 들어가 조금 전에 만든 c파일 이름과 동일하게 오브젝트 파일명을 적어준다.


위 과정을 모두 거쳤다면 축하한다. 이 과제가 절반정도 끝난 것이다!
모두 완료했다면 아래 경로에서 다음과 같은 명령어를 입력해주자. 이 명령어는 우리가 새로 추가한 커널에 대해 빌드해주는 명령어다.

cd /usr/src/linux-5.9.1/ #위 경로로 이동한후 차례대로 수행할 것
sudo make 
sudo make install

자... sudo make를 하는 순간 당신은 돌아올 수 없는 강을 건넌거다. 가서 밥이나 먹고 와라... 빌드하는데 시간이 굉장히 오래 걸린다^^ 그리고 빌드가 끝날 때 쯤 이런 오류를 발견할 거다.

id: arch/x86/entry/syscall_64.o:(.rodata+0xdc0): undefined reference to '__x84_sys_print_number' id: arch/x86/entry/syscall_64.o:(.rodata+0xdc0): undefined reference to '__x84_sys_print_number' make: ***[Makefile:1162:vmlinux] Error 1

안뜨면 주님께 감사하고,,,만약 뜬다면 당신의 kernel 파일이 잘못된 것이다. 혹은 Makefile과 64.tbl에 함수 등록을 잘못했거나.


다음은 user program 생성이다. 기존에 우리가 위에서 정말 거지같은 과정을 통해 만든 kernel 파일을 드디어 호출할 프로그램을 만들 수 있다!

#include <linux/kernel.h> 
#include <sys/syscall.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#define SYS_NUM 440 #좀전에 선언한 함수의 코드를 전역변수화 
int main(){ 
	int num=0; 
    while(num!=-1){ 
    	printf("input an integer number(-1 for exit): " ); 
    	scanf("%d", &num); printf("\n"); 
        syscall(SYS_NUM, num); #좀전에 전역변수화 한 커널 함수의 코드와 매개변수를 전달 
} }

유저 프로그램에 대한 코드 설명은 차치하도록 하겠다. 다들 알겠지 읽어보면..

여하튼, 유저프로그램을 생성한 후 c 파일을 컴파일 해준다.

gcc test.c -o test #유저 프로그램을 test.c 로 만들었기 때문에 test.c를 컴파일함. 

./test # ./시 컴파일한 유저프로그램 c파일을 확인할 수 있음 

dmesg #dmesg시 kernel이 제대로 작동했는지 확인 가능함
./test시 화면(컴파일)
dmesg시 화면(커널 컴파일)

이러한 과정을 거치면 systemcall 추가가 가능하다. 나처럼 헤매는 사람 없이 다들 잘하길...
한국어 소스가 너무 없어서 일조하고자 글을 남긴다.

추가로 system call에 대해 정보를 얻고자 하면 아래 링크를 클릭해보는 것도 좋다.
내가 도움을 얻은 몇개 포스팅에 대해 남겨놓는다!

P.S 글이 도움이 되셨다면 좋아요 부탁드립니다🥺저에게 큰 힘이 죄고 있어요🙆🏻‍♀️

https://dev.to/jasper/adding-a-system-call-to-the-linux-kernel-5-8-1-in-ubuntu-20-04-lts-2ga8

Adding A System Call To The Linux Kernel (5.8.1) In Ubuntu (20.04 LTS)

In this guide, you will learn how to add a simple system call to the Linux kernel. Check the help sec...

dev.to

https://dev.to/omergulen/how-to-add-system-call-syscall-that-prints-elapsed-time-of-a-process-with-given-pid-to-the-kernel-and-test-it-335c

How to add system call (syscall) that prints elapsed time of a process with given PID to the kernel and test it?

In my previous tutorial 👇 How to add system call (syscall) to...

dev.to


https://stackoverflow.com/questions/28126204/simple-system-call-implementation-example

Simple System Call Implementation example?

Interestingly, I couldn't find any simple example on web. Can you share a simple example please? I'm trying to understand following by analyzing an example. ⦁ Typically, ⦁ a number associated...

stackoverflow.com

반응형