reference:
- "리눅스 커널 내부구조" / 백승재, 최종무
- "Operating Systems: Three Easy Pieces" / Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau
# apt-get install build-essential linux-headers-$(uname -r)
(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");
커널 소스를 가장 간단하게 디버깅하는 방법은 소스 중간 중간에 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)
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
make를 통해 모듈을 만들었다면 커널에 적재해야 한다. insmod 명령어를 사용한다.
#sudo insmod hello.ko
모듈을 올리며 hello_init() 함수가 호출됨.
dmesg 명령어로 커널 로그 확인
rmmod로 모듈 내리기
# sudo rmmod hello
모듈을 내리며 hello_exit() 함수가 호출됨.
- lsmod: 커널 내 적재된 모듈 확인
- modinfo: 모듈 정보