Linux 커널 모듈 프로그래밍: Hello World 프로그램
커널 모듈은 요청 시 커널에 로드 및 언로드할 수 있는 코드 조각입니다. 시스템을 재부팅할 필요 없이 커널 기능을 확장합니다. 두 가지 방법을 통해 사용자 정의 코드를 Linux 커널에 추가할 수 있습니다.
- 기본적인 방법은 커널 소스 트리에 코드를 추가하고 커널을 다시 컴파일하는 것입니다.
- 보다 효율적인 방법은 커널이 실행되는 동안 커널에 코드를 추가하는 것입니다. 이 프로세스를 모듈 로드라고 합니다. 여기서 모듈은 커널에 추가하려는 코드를 나타냅니다.
- 장치 드라이버
- 파일 시스템 드라이버 및
- 시스템 호출.
/** * @file hello.c * @author Akshat Sinha * @date 10 Sept 2016 * @version 0.1 * @brief An introductory 'Hello World!' loadable kernel * module (LKM) that can display a message in the /var/log/kern.log * file when the module is loaded and removed. The module can accept * an argument when it is loaded -- the name which appears in the * kernel log files. */ #include /* Needed by all modules */ #include /* Needed for KERN_INFO */ #include /* Needed for the macros */ /// < The license type -- this affects runtime behavior MODULE_LICENSE ( 'GPL' ); /// < The author -- visible when you use modinfo MODULE_AUTHOR ( 'Akshat Sinha' ); /// < The description -- see modinfo MODULE_DESCRIPTION ( 'A simple Hello world LKM!' ); /// < The version of the module MODULE_VERSION ( '0.1' ); static int __init hello_start ( void ) { printk ( KERN_INFO 'Loading hello module... n ' ); printk ( KERN_INFO 'Hello world n ' ); return 0 ; } static void __exit hello_end ( void ) { printk ( KERN_INFO 'Goodbye Mr. n ' ); } module_init ( hello_start ); module_exit ( hello_end );
위 코드에 대한 설명: 커널 모듈에는 모듈이 커널에 삽입될 때 호출되는 '시작'(초기화) 함수인 init_module()과 모듈이 rmmoded되기 직전에 호출되는 cleanup_module()이라는 '종료'(정리) 함수라는 두 가지 이상의 함수가 있어야 합니다. 실제로 커널 2.3.13부터 상황이 변경되었습니다. 이제 모듈의 시작 및 종료 기능에 원하는 이름을 사용할 수 있습니다. 실제로는 새로운 방법이 선호되는 방법입니다. 그러나 많은 사람들이 여전히 시작 및 종료 기능에 init_module() 및 cleanup_module()을 사용합니다. 이 코드에서는 hello_start()를 초기화 함수로 사용하고 hello_end()를 정리 함수로 사용했습니다. 또 다른 점은 printf() 함수 대신 printk()를 사용했다는 것입니다. 이는 모듈이 콘솔에 아무 것도 인쇄하지 않지만 /var/log/kern.log에 메시지를 기록하기 때문입니다. 따라서 커널 모듈을 디버깅하는 데 사용됩니다. 또한 printk()를 사용하는 동안 필요한 헤더에 정의된 8개의 가능한 로그 수준 문자열이 있습니다. 심각도가 낮은 순서로 나열했습니다. - KERN_EMERG: 일반적으로 충돌 이전의 긴급 메시지에 사용됩니다.
- KERN_ALERT: 즉각적인 조치가 필요한 상황입니다.
- KERN_CRIT: 심각한 하드웨어 또는 소프트웨어 오류와 관련된 심각한 조건입니다.
- KERN_ERR: 오류 조건을 보고하는 데 사용됩니다. 장치 드라이버는 종종 KERN_ERR을 사용하여 하드웨어 문제를 보고합니다.
- KERN_WARNING: 그 자체로는 시스템에 심각한 문제를 일으키지 않는 문제 상황에 대한 경고입니다.
- KERN_NOTICE: 정상이지만 여전히 주목할 만한 상황입니다. 이 수준에서는 다양한 보안 관련 조건이 보고됩니다.
- KERN_INFO: 정보 메시지. 많은 드라이버가 이 수준에서 시작 시 찾은 하드웨어에 대한 정보를 인쇄합니다.
- KERN_DEBUG: 메시지 디버깅에 사용됩니다. KERN_INFO를 사용하여 메시지를 인쇄했습니다. 코드 실행을 위한 시스템 준비: The system must be prepared to build kernel code and to do this you must have the Linux headers installed on your device. On a typical Linux desktop machine you can use your package manager to locate the correct package to install. For example under 64-bit Debian you can use:
akshat@gfg:~$ sudo apt-get install build-essential linux-headers-$(uname -r)소스 코드를 컴파일하기 위한 Makefile:
obj-m = hello.o all: make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean**참고: Makefile의 탭 공백을 잊지 마세요. 모듈 컴파일 및 로드: Run the make command to compile the source code. Then use insmod to load the module.
akshat@gfg:~$ make make -C /lib/modules/4.2.0-42-generic/build/ M=/home/akshat/Documents/hello-module modules make[1]: Entering directory `/usr/src/linux-headers-4.2.0-42-generic' CC [M] /home/akshat/Documents/hello-module/hello.o Building modules stage 2. MODPOST 1 modules CC /home/akshat/Documents/hello-module/hello.mod.o LD [M] /home/akshat/Documents/hello-module/hello.ko make[1]: Leaving directory `/usr/src/linux-headers-4.2.0-42-generic'Now we will use insmod to load the hello.ko object.
akshat@gfg:~$ sudo insmod hello.ko모듈 테스트: You can get information about the module using the modinfo command which will identify the description author and any module parameters that are defined:
akshat@gfg:~$ modinfo hello.ko filename: /home/akshat/Documents/hello-module/hello.ko version: 0.1 description: A simple Hello world LKM author: Akshat Sinha license: GPL srcversion: 2F2B1B95DA1F08AC18B09BC depends: vermagic: 4.2.0-42-generic SMP mod_unload modversionsTo see the message we need to read the kern.log in /var/log directory.
akshat@gfg:~$ tail /var/log/kern.log ... ... Sep 10 17:43:39 akshat-gfg kernel: [26380.327886] Hello world To unload the module we run rmmod: akshat@gfg:~$ sudo rmmod hello Now run the tail command to get the exit message. akshat@gfg:~$ tail /var/log/kern.log ... Sep 10 17:43:39 akshat-gfg kernel: [26380.327886] Hello world Sep 10 17:45:42 akshat-gfg kernel: [26503.773982] Goodbye Mr.