리눅스/디바이스 드라이버
[디바이스 드라이버] 4. 장치파일과 디바이스 드라이버 연결하기
다락공방
2024. 9. 2. 01:38
목표
이번엔 장치파일과 디바이스 드라이버를 만들어서 연결해볼 것이다.
그렇게해서 애플리케이션(User Level)에서는 디바이스 드라이버로(Kernel Level)에 장치파일을 이용해 접근해본다.
디바이스 드라이버 모듈
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("IH02");
MODULE_DESCRIPTION("user_to_driver");
static int driver_open(struct inode *device_file, struct file *instance){
printk("open was called!\n");
return 0;
}
static int driver_close(struct inode *device_file, struct file *instance){
printk("close was called!\n");
return 0;
}
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = driver_open,
.release = driver_close
};
#define MAJOR_NUM 100
static int __init driver_init(void) {
int retval;
printk("Driver init!\n");
retval = register_chrdev(MAJOR_NUM, "IH_driver2", &fops);
if(retval == 0) {
printk("Device Major Number :%d, Minor : %d\n", MAJOR_NUM,0);
}
else if(retval > 0) {
printk("Registered Device number Major :%d, Minor : %d\n", retval>>20,retval&0xfffff);
} else {
printk("Could not register device number!\n");
return -1;
}
return 0;
}
static void __exit driver_exit(void) {
unregister_chrdev(MAJOR_NUM, "IH_driver2");
printk("Driver exit!\n");
}
module_init(driver_init);
module_exit(driver_exit);
이전 모듈 프로그래밍이랑 좀 달라진 점이 있어 확인해보자.
fops 구조체
- 문자 디바이스의 파일 조작을 처리하는 함수 포인터들의 집합을 의미
- open 필드는 디바이스 파일이 열릴 때 호출되는 함수의 포인터이다.
- release 필드는 디바이스 파일이 닫힐 때 호출되는 함수의 포인터이다.
이번에는 장치 파일을 열고 닫아서, 장치파일과 연결된 디바이스 드라이버에서 함수가 잘 호출되는지 확인할예정이다.
register_chrdev 함수의 역할
- register_chrdev(MAJOR_NUM, "IH_driver2", &fops);
- 이 함수는 커널에 문자 디바이스를 등록한다. 주번호(major number)를 통해 디바이스를 식별하고, 해당 디바이스에 대해 수행할 작업을 정의하는 file_operations 구조체를 연결한다.
- 반환값은 0이면 등록성공, 0보다 작으면 등록실패를 의미한다.
등록 확인
디바이스 파일 만들기
mknod로 만들 수 있다.
dev 폴더 안에 day2라는 문자 장치파일을 만들고, 100번의 주번호로 디바이스 드라이버와 연결해준다.
chmod로 권한을 부여해준다. 666은 장치파일을 읽고 쓸 수 있도록 해주는 것이다.
유저 어플리케이션 생성
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
int dev = open("/dev/day2", O_RDONLY);
if(dev == -1) {
printf("Opening was not possible!\n");
return -1;
}
printf("Opening was successfull!\n");
close(dev);
return 0;
}
유저 실행파일은 위와 같이 만들었으며, 단순히 open, close 함수를 이용하여 /dev/day2 파일을 열고 닫는다.
이 장치 파일을 열고 닫으면 디바이스 드라이버에서의 fops 구조체에서의, 파일 open/release 포인터가 연결된 함수들이 호출될 것이다.
위 c 파일을 실행파일로 컴파일하고 실행한다.
결과 확인
dmesg를 통해 장치파일과 디바이스 드라이버에 정상적으로 접근했는지 확인할 수 있다.
open_moduile을 선언했을때 3번째 줄, 4번째 줄이 순차적으로 디바이스 드라이버를 통해 호출 되었음을 확인할 수 있다.
이로서 유저 프로그램으로 디바이스 드라이버 접근까지 성공하였다.