반응형
안녕하세요.

커널 컴파일 포스팅 (http://harryp.tistory.com/9) 에 커널에 시스템 콜 추가 하는 방법에 대해 작성해 달라는 분들이 많으셔서 관련 내용을 포스팅하겠습니다.


작성하는 내용은 제가 실습했던 내용이고,


단순히 시스템 콜을 추가하는 방법 만 먼저 기술하도록 하겠습니다.


(즉, 추가하는 시스템콜이 매우 단순하다는 뜻 입니다.)



우선 해당 내용을 진행하시기 전에 커널 컴파일을 한 번씩 해보시기 바랍니다.


시스템 콜 이라는 것이 커널을 수정하는 것 이기 때문에,


커널컴파일 환경이 구성 되어야 하고,


커널 컴파일을 성공하셔야 시스템 콜을 추가하실 수 있기 때문입니다.


아직 커널컴파일 경험이 없으신 분들은 저의 이전 포스팅 (http://harryp.tistory.com/9) 을 참고해 주시기 바랍니다.



그럼 설명 들어갑니다.



* 유의사항


시스템 콜은 커널에 추가가 됩니다. 따라서 커널 버전에 따라 디렉토리 명이 다르게 됩니다.


본 포스팅 에서는 커널 소스의 경로 (예 - /usr/src/kernel-3.xxx/) 의 경로를 [커널]로 표시하도록 하겠습니다.


저는 해당 실습을 3.2.38 커널에서 진행했기 때문에,


[커널]의 경로가 '/usr/src/linux-3.2.38/'이 됩니다.



1. 시스템 콜 구현


추가할 시스템 콜을 '[커널]/kernel/' 에 구현을 해주셔야 합니다.


저는 'HELLOWORLD'를 printk 해주는 sys_helloworld 라는 아주 간단한 시스템 콜을 구현하였습니다.


파일 명은 helloworld.c 로 지적하였습니다. (즉 [커널]/kernel/helloworld.c)



함수에 대한 설명을 간단히 드리면...



함수 앞 부분의 'asmlinkage'는 함수가 어셈블리 언어로 구현된 함수에서 호출될 때 사용하는 키워드 입니다.



함수 내부에서 사용한 printk()함수의 경우 커널에서 사용하는 출력 함수 입니다.


터미널이 아닌 커널 버퍼에 해당 내용을 출력하면 됩니다.


dmesg 명령어를 통해서 확인할 수 있습니다.



2. 시스템 콜 number 등록


[커널]/arch/x86/include/asm/unistd_32.h


----------------------------------------------------
* 2014.05.21 추가 내용


최신 커널의 경우 경로와 파일이 바뀌었더군요.


다음의 경로의 파일을 수정해주시면 됩니다.


32비트 - [커널]/arch/x86/syscalls/syscall_32.tbl


64비트 - [커널]/arch/x86/syscalls/syscall_64.tbl

----------------------------------------------------


파일을 수정하여 구현한 시스템콜의 번호를 등록해야 합니다.


(아키텍쳐가 x86 아키텍쳐가 아닐경우 해당 아키텍쳐에 맞추어 경로 변경을 해주셔야 합니다.)




우선 밑의 노란 네모인 'NR_syscalls'의 경우 총 시스템 콜의 개수를 나타납니다.


시스템 콜 번호가 0번 부터 시작되기 때문에,


가장 마지막 시스템 콜 번호에 +1 하시면 됩니다.


기존에는 '349'로 입력이 되어 있었습니다. (이 숫자는 커널의 버전에 따라 바뀌게 됩니다.)


시스템 콜을 추가로 하나 더 추가하기 떄문에 1을 더하여 350으로 바꾸어 줍니다.



그리고 위의 노란 네모를 참고하시면,


가장 마지막 부분에 아까 구현한 시스템 콜 함수를 추가해 줍니다.


형식은


#define __NR_함수명    시스템콜번호


가 됩니다. (함수명과 시스템콜 번호 사이는 tab으로 띄우시면 됩니다.)


위의 예시로 든 내용은


#define __NR_helloworld    349


입니다.


즉, 위에 구현한 helloworld 라는 시스템 콜 함수는 349번 시스템 콜 함수 인 것이고,


총 350개의 시스템 콜이 구현되어 있습니다.



3. 시스템 콜 table에 등록


시스템 콜 table의 경로는


[커널]/arch/x86/kernel/syscall_table_32.S


에 명시되어 있습니다.


(마찬가지로 아키텍쳐가 x86이 아닐경우 해당 아키텍쳐에 해당하는 경로로 이동해주셔야 합니다.)




가장 마지막 부분에 구현한 시스템 콜 함수를 작성해 주시면 됩니다.


양식은


.long 시스템콜함수명


입니다.


저는 마지막줄에


.long sys_helloworld


를 추가하였습니다.



4. 시스템 콜 함수 선언


[커널]/include/linux/syscalls.h


파일에 등록 할 시스템 콜 함수를 선언해 주어야 합니다.




마찬가지로 가장 마지막 부분에 추가할 함수의 원형을 작성해 주시면 됩니다.


helloworld 함수의 경우 long 형을 return 하고, 입력되는 인자는 없으므로 void로 작성하였습니다.


노란색 네모가 추가한 부분 입니다.



5. Makefile 수정


이제 커널 컴파일 시 구현한 함수가 컴파일 되도록 Makefile에 추가를 해주셔야 합니다.


Makefile의 경로는


[커널]/kernel/Makefile


입니다.




시스템 콜의 오브젝트 파일들이 나열된 곳에 추가 할 시스템 콜을 추가해 주시면 됩니다.


구현한 시스템 콜의 파일 명이 'helloworld.c' 이기 때문에,


이 파일을 컴파일 하였을 떄의 오브젝트 파일 명인 'helloworld.o'를 작성해 주시면 됩니다.



6. 커널 컴파일


이제 추가, 수정된 내용을 포함하여 커널 컴파일을 하면 됩니다.


1~5번 까지의 과정이 새로운 함수 추가, 등록 등의 과정을 전부 하였기 때문에


기존의 방식대로 커널컴파일을 해주시면 됩니다.


이전 포스팅 (http://harryp.tistory.com/9) 의 내용을 그대로 따라하시면 됩니다.



7. 추가한 시스템 콜 테스트




추가한 시스템 콜을 사용해보기 위한 테스트 프로그램 소스 입니다.


syscall() 함수를 사용하여 구현한 시스템 콜을 동작해보는 간단한 프로그램 입니다.


위에서 구현한 시스템 콜은 printk() 함수로 'HELLOWORLD'를 출력해주는 함수 입니다.


위의 프로그램을 2번 실행 후, dmesg 를 통해 확인해 보면...




위와 같이 가장 마지막 부분에 HELLOWORLD가 2번 찍혀있는 것을 확인하실 수 있습니다.




이번 포스팅에서는 단순히 시스템 콜을 커널에 추가하는 것을 다루었습니다.


수업 혹은 업무에서 요구하는 시스템 콜은 단순히 printk()가 아닌 더 어려운 것을 요구할 수 있습니다.


해당 내용에 따라 시스템 콜 구현하는 난이도가 높아질 것 입니다.


하지만 추가는 위와 같은 방법으로 진행하시면 됩니다.



궁금하신 점은 댓글로 문의 부탁드립니다~



반응형
Posted by 해리팍
BLOG main image

Chanhyun Park (해리팍)
Software Engineer @ SK hynix

Contact Info.
parkch0708@hanmail.net
chanhyun0708@gmail.com
chanhyun.park@sk.com

카테고리

All (1502)
Profile (2)
Park's Life (600)
Computer System (165)
Computer Programming (39)
Computer Study (54)
Computer Etc. (189)
Scuba Diving (137)
Golf (8)
Traveling (245)
생활 정보 (12)
Pokemon GO (50)