강좌 & 팁
안녕하세요 판다 이우영입니다.
오늘은 저번 시간에 이어서 디바이스 드라이버 공부를 해보겠습니다.
먼저 복습 부터!!
1. 복습!!!
저번 시간에는 블로킹 I/O의 단점을 설명해 드렸죠?
여러 디바이스 장치를 사용할 때 에로 사항이 있다고 했습니다.
그래서 나온 방법이 입출력 다중화 기법 입니다.
그중 우리는 POLL에 대해서 알아 보겠습니다.
POLL 사용법은 다음과 같다고 했었죠?
응용프로그램
- 사용하는 디바이스 정보를 구조체를 통해 등록
- 디바이스에 따른 poll 처리
디바이스 드라이버
- poll 함수를 등록하여 기존의 read, write 등의 함수를 수행
그럼 하나씩 자세하게 알아 볼까요?
2. POLL을 사용하는 디바이스 드라이버
우선 디바이스 드라이버의 작성 법 부터 알아 보도록 하겠습니다.
방급 복습에서 poll 함수를 등록한다고 했지만 어디다 등록을 하라는거지??
하신 분들 많았겠죠?
생각해보면 간단한 문제입니다. 우리가 디바이스 드라이버에서 사용하는 open, read, write 등의 함수를
파일 오페레이션 필드에 등록해서 사용했었습니다.
POLL 또한 이 file_operations 구조체에 아래와 같이 등록을 하시면 됩니다.
(어디선가 많이 본거죠? ㅎㅎ)
struct file_operations kerneltimer_fops =
{
.owner = THIS_MODULE,
.read = kerneltimer_read,
.write = kerneltimer_write,
.poll = kerneltimer_poll,
.open = kerneltimer_open,
.release = kerneltimer_release,
};
그럼 등록을 했습니다. 그럼 함수를 구현해야 합니다.
먼저 함수의 형태를 알아볼까요?
(등록하는거니 정해진 형태가 있겠죠?)
unsigned int XXX_poll(struct file *file, poll_table *wait);
위와 같이 2개의 인자가 넘어 옵니다.
이 POLL 함수가 해주는 일은 두가지 역활이 있다고 합니다.
1. 커널의 poll_table에 감시해야하는 사건을 대기 큐에 등록해준다.
2. 디바이스 파일에 입축력 다중화 처리를 구현하기 위해 마스크 값을 응용프로그램에 넘겨 준다.
음.. 뭔가 어렵죠? 역시 소스를 짜봐야 금방 이해가 되지만 우선 간단히 설명 부터 해보겠습니다.
먼저 대기 큐에 등록한다는 것은 저번에 블로킹 I/O에서 만들었던 대기 큐를 이용합니다.
문론 함수는 다른걸 사용합니다. 바로 poll_wait 함수 입니다.
DECLARE_WAIT_QUEUE_HEAD(WaitQueue_Read);
unsigned int XXX_poll( struct file *file, poll_tablr *wait)
{
int mask = 0;
poll_wait( file, &WaitQueue_Read, wait );
if( 쓰기 가능 ) mask |= (POLLIN | POLLRDNORM );
return mask;
}
poll_wait 함수를 통해 대기 큐를 poll_table에 등록해서 커널이 주기적으로 감시를 합니다.
사용가능하게 되면 mask에 쓰기 가능 마크를 해두고 리턴해서 응용프로그램에 알려줍니다.
그럼 응용 프로그램은 쓰기를 수행하겠죠?
아마 동작이 이해가 잘 안되실 겁니다. 응용 프로그램 작성법과 소스코드 까지 봐야 어느정도 이해가 됩니다.
(저도 이해가 불가능 했습니다...)
초조해 하지 말고 차근차근 진행 해봅시다 ㅎㅎ
다행이도 POLL은 위와 같은 방식 말고는 사용하지 않는다고 합니다.
한번 배워두면 고생할일이 없는거죠 ㅎㅎ
마지막으로 mask에 넘겨주는 조건 중 중요한 것만 소개 하겠습니다.
읽기 가능 상태 : POLLIN | POKKRDNORM
쓰기 가능 상태 : POLLOUT | POKKWRDNORM
에러 상태 : POLLERR
그럼 오늘은 여기까지!!
다음 시간에 만나요~~
- 참고서적 : 리눅스 드바이스 드라이버(유영창 저) -