모듈 프로그래밍(실습1) printk test module

Jin Hur·2021년 11월 17일
0
post-custom-banner

reference:

  • "리눅스 커널 내부구조" / 백승재, 최종무
  • "Operating Systems: Three Easy Pieces" / Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau
  1. 먼저 리눅스 헤더를 설치한다.
# apt-get install build-essential linux-headers-$(uname -r)
  1. 모듈 작성, printk test module

Source

(hello.c)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

static int __init hello_init(void) 
{
	printk(KERN_WARNING "(ver: 0.1.0) Hello world! I'm in Kernel \n");
	return 0;
}

static void __exit hello_exit(void) 
{
	printk(KERN_WARNING "(ver: 0.1.0) Goodbye world~! \n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("JIN HUR");
MODULE_DESCRIPTION("printk test module");
MODULE_VERSION("0.1.0");
  • <linux/init.h>: init, exit 매크로를 include
  • <linux/module.h>: KERN_INFO와 같은 로그 메시지 등급 지정 매크로 include
  • <linux/kernel.h>: 모듈 프로그래밍을 하기 위해 필요한 모든 것이 담겨있음

커널 소스를 가장 간단하게 디버깅하는 방법은 소스 중간 중간에 prink() 함수를 삽입하여 그때마다 궁금한 데이터를 출력할 수 있다.

(사용 형식)
printf()와 동일하며 반드시 메시지 끝에 개행문자(\n)를 붙여야한다. 메시지 출력은 콘솔 창에 바로 출력되는 것이 아니라 원형 큐 형식의 커널 로그 버퍼에 저장된다.

(로그 버퍼 출력 방법)
1) # dmesg : 커널 메시지는 이러한 커널 메시지를 관리하는 2개의 데몬(klogd, syslogd)에 의해 '/var/log 디렉터리에 로그가 기록되는데 이 메시지는 쉘에서 'dmesg' 명령을 통해 콘솔에 출력된다.
2) # cat /proc/kmsg : 커널의 상태 정보를 가지는 /proc 디렉터리의 kmsg를 확인한다.

(로그 레벨 지정)
printf와의 차이는 메시지 기록 관리를 위한 로그레벨을 지정할 수 있다는 것이다.
ex) printk(KERN_ALERT "Hello world! I'm in Kernel \n");


cf) 로그레벨 명령어 의미
"<0>" KERN_EMERG 시스템이 동작하지 않는다.
"<1>" KERN_ALERT 항상 출력
"<2>" KERN_CRIT 치명적인 정보
"<3>" KERN_ERR 오류 정보
"<4>" KERN_WARNING 경고 정보
"<5>" KERN_NOTICE 정상적인 정보
"<6>" KERN_INFO 시스템 정보
"<7>" KERN_DEBUG 디버깅 정보
(레벨에 대한 표시를 하지 않았다면 default 레벨은 "KERN_WARNING"이다.


레벨 번호가 낮을수록 응듭한 메시지(에러, 알림)만 출력된다.
레벨 4는 경고에 해당하는 메시지가 출력되고, 레벨 8은 디버그를 위한 대부분의 메시지가 출려된다. 따라서 레벨을 높이면 높일수록 디버스 메시지가 많이 출력되무로 시스템 성능이 저하된다.
위 매크로는 <linux/kernel.h>에 선언되어 있다.

MODULE_LICENSE("GPL");
내가 만든 코드를 다른 사람에게도 공개한다는 의미라고 한다.
이를 적용하지 않아도 되지만 적용하지 않는다면 linux에서 제공하는 라이브러, 함수들을 사용할 수 없다고 한다.
(source: https://kcoder.tistory.com/entry/s5pc100-%EB%AA%A8%EB%93%88-%EB%A7%8C%EB%93%A4%EA%B8%B0-%EA%B8%B0%EC%B4%88-%EC%8B%AC%EB%B3%BC-%EB%AF%B8%EA%B3%B5%EA%B0%9C-%EC%A0%84%EC%97%AD-%EC%8B%AC%EB%B3%BC-%EA%B3%B5%EA%B0%9C-%EA%B7%B8%EB%A6%BC%EC%84%A4%EB%AA%85)


Makefile, make

obj-m += hello.o

KDIR := /lib/modules/$(shell uname -r)/build
default:
	make -C $(KDIR) M=$(PWD) modules

clean:
	make -C $(KDIR) M=$(PWD) clean
  • $(shell uname -r) 값은 커널의 최신 버전의 문자열로 치환된다.
  • 커널 2.6버전 이후부터는 .ko 파일을 만들기 위해 gcc말고 Makefile로 만들어주어야 한다.
  • obj-m은 목적파일이다. 이때 m은 모듈을 뜻한다. (참고로 obj-y는 built-in 형식의 .ko 파일을 만든다. 이는 추후에 다시 살펴보기)
  • KDIR은 Kernel Source Directory이다. 현재 커널 소스의 디렉터리는 '$(shell uname -r)'를 통해 최신 버전으로 가져올 수 있다.
  • 'make' 명령어로 default: 문들이 실행되고, 'make clean'으로 관련 파일들을 지울 수 있다.

모듈을 커널에 적재

make를 통해 모듈을 만들었다면 커널에 적재해야 한다. insmod 명령어를 사용한다.

#sudo insmod hello.ko

모듈을 올리며 hello_init() 함수가 호출됨.
dmesg 명령어로 커널 로그 확인

rmmod로 모듈 내리기

# sudo rmmod hello

모듈을 내리며 hello_exit() 함수가 호출됨.

  • lsmod: 커널 내 적재된 모듈 확인
  • modinfo: 모듈 정보
post-custom-banner

0개의 댓글