반응형
21. 모듈 프로그래밍
커널 모듈(Kernel Module)
- 시스템 부팅후에 동적으로
loading
할 수 있는 커널 구성요소를 말한다. - 커널을 다시 컴파일하거나 시스템 재부팅 할 필요없이 커널의 일부분을 교체하는 것이 가능하다
- 디바이스 드라이버, 파일 시스템, 네트워크 프로토콜 등이 모듈로 제공된다.
일반 응용프로그램과 뭐가 다른거죠??
커널 모듈은 일반 응용 프로그램과 달리 main함수가 없다.
대신에 커널에 로딩 및 제거될 때 불러지는 함수가 존재하는데, 이는 아래와 같다.
- Loading 시 :
module_init()
로 지정된 함수 호출 - Unloading 시 :
module_exit()
로 지정된 함수 호출
25.1 리눅스 디바이스 드라이버의 특성
- 커널 코드
- 디바이스 드라이버는 커널의 한 부분이므로, 커널의 다른 코드와 마찬가지로 잘못되면 시스템에 치명적인 피해를 줄 수 있다.
- 커널 인터페이스
- 디바이스 드라이버는 리눅스 커널이나 자신이 속한 서브시스템에 표준 인터페이스를 제공해야 한다.
- 커널 매커니즘과 서비스
- 디바이스 드라이버는 메모리 할당, 인터럽트 전달, wait queue와 같은 표준 커널 서비스를 사용할 수 있다.
- Loadable
- 대부분의 리눅스 드라이버는 커널 모듈로서, 필요할 때
Load
하고 더이상 필요하지 않을 때Unload
할 수 있다.
- 대부분의 리눅스 드라이버는 커널 모듈로서, 필요할 때
- 설정 가능(Configurable)
- 리눅스 디바이스 드라이버를 커널에 포함하여 컴파일할 수 있다. 어떤 장치를 넣을 것인지는 커널을 컴파일 할 때 설정할 수 있다.
25.2 간단한 커널모듈 작성해보기
1. hello.c
//hello.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("BUTTER SHOWER");
MODULE_DESCRIPTION("module programming - hello module");
static int __init module_begin(void) {
printk("Hello, linux kernel module. \n");
return 0;
}
static void __exit module_end(void) {
printk("Good Bye!\n");
}
module_init(module_begin);
module_exit(module_end);
- 필요한 include 파일들 include 시켜주기
- module license 지정
- 종류 :
GPL, GPL v2, Dual BSD/GPL, Proprietary
등 - 커널 2.6부터 반드시 지정해야 함
- 종류 :
module_init
함수 작성 및 등록 :module_init(init_func);
module_exit
함수 작성 및 등록 :module_exit(exit_func);
2. 커널 모듈 프로그램을 위한 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
이라는 이름으로 위의 코드를 붙여 만들어 준후, make
명령어를 하면 아래와 같이 실행된다.
컴파일 과정
hello.o
파일 먼저 생성modpost
를 C 소스파일에 적용해.ko
에서 요구되는 추가 정보를 부착하여hello.mod.c
를 생성한 후 컴파일 ->hello.mod.o
생성- 두개의
.o
파일을 링크하여.ko(kernel object)
파일을 생성
3. 모듈 적재(loading) 그리고 제거(unloading)
-
생성된 모듈(hello.ko)을 로딩
insmod hello.ko
-
커널에 적재된 모듈 목록보기
lsmod
-
모듈 제거
rmmod hello # (.ko가 붙지 않는다)
-
hello 모듈 동작 확인
# 모듈 적재와 제거 시에 메시지들이 출력되는지 확인 #dmesg 또는 #tail -f /var/log/kern.log (-f 옵션 : 계속적인 변화 출력)
25.3 디바이스 드라이버 작성 방법
1. 디바이스 드라이버 함수 작성
- struct file_operations 정의
- open, release, read, write, ioctl 함수 구현
- init, exit 함수 구현
2. 커널에 디바이스 드라이버 등록
Init 함수에서 수행
int res;
res = register_chardev(); // char driver
res = register_blkdev(); // block driver
res = register_netdev(); // network driver
(사실 register_xxxdev() 함수 파라미터에 필요한 값들이 있지만 일단 생략.. 추후 포스팅 예시를 보면 알 것이다)
3. 컴파일/로딩
# make ... Makefile 작성 후 실행
# insmod ... 생성된 .ko 파일 load
4. 디바이스 파일 생성
# mknode [디바이스 파일 이름] [드라이버타입] [주번호] [부번호]
(예시)
#mknod /dev/LED c 239 0
필요하면 속성을 변경해주면 된다.
# chmod ug+w /dev/LED
5. 디바이스 파일에 입출력하는 응용프로그램 작성 및 테스트
디바이스 파일에 입출력하는 응용프로그램을 작성하고, 테스트한다.
커널 영역을 침범하는 파일이기 때문에 작성에 유의해야 한다.
25.4 디바이스 드라이버 골격
디바이스 드라이버의 골격은 아래와 같다.
반응형
'임베디드 > [ Linux Kernel ]' 카테고리의 다른 글
[ Linux Kernel ] 23. Platform Device & Driver (4) | 2020.11.05 |
---|---|
[ Linux Kernel ] 22. 커널에 모듈 추가하기 (0) | 2020.10.30 |
[ Linux Kernel ] 20. Linux Device Driver (0) | 2020.10.28 |
[ Linux Kernel ] 19. Ubuntu에서 Wi-Fi 연결하기 (0) | 2020.10.16 |
[ Linux Kernel ] 18. Kernel Module (0) | 2020.10.12 |