본문 바로가기

Embedded/Device Driver

Device Driver] 디바이스 드라이버 만드는 법

디바이스 드라이버를 작성하려는데 감이 오질 않을 것이다.
어떻게 작성하는지 들어가기 전에 우선 작성 단계를 짚어보자.


※ 새로운 디바이스 드라이버 작성 단계
ㅡ.디바이스 드라이버 커널 인터페이스 구현
(entry point functions, file_operations)
ㅡ.디바이스 드라이버 초기화 인터페이스 구현
(주번호 할당 및 디바이스 드라이버 루틴 등록)
ㅡ.디바이스 드라이버 하드웨어 인터페이스 구현
(레지스터 접근)
ㅡ.장치 파일 생성
ex)  # mknod /dev/mydrv [b|c] major_number minor_number
ㅡ.응용 프로그램 작성
ㅡ.커널 컴파일 및 리부팅

위의 디바이스 드라이버 작성단계를 보면 디바이스 드라이버를 만드는데 3계의 단계를 거친다.
그 과정을 좀더 자세히 보자.
 
 
※ 디바이스 드라이버의 3부분
     ㅡ.초기화 인터페이스
init()함수 ( init_module()함수 )
     register_chrdev()
     register_blkdev()
     register_irq()
     ...... 
 
     ㅡ.시스템 인터페이스(커널 인터페이스)
문자/블록 드리이버의 경우 file_operations구조체 를 이용
struct file_operations{
open, release, read, write, ioctl, ...
}
네트워크 드라이버의 경우
open, close, transmit, receive, ioctl 과 같은 함수를 사용한다.( 좀 다른 시스템 함수를 사용함 )

     ㅡ.하드웨어 인터페이스
===> I/O Mapped I/O (혹은 Port Mapped I/O )의 경우 입출력을 위해 특정 포트(Port)를 사용한다.
in(), out()

리눅스를 한번이라도 접해 봤다면 리눅스에서는 모든것이 파일이라는 말을 들은적이 있을 것이다.
디바이스 역시 파일로 관리된다. 그리고 그 파일을 장치파일 (Device File)이라고 부른다.
 
 장치 파일(Device File)
     ㅡ.리눅스에서는 모든 하드웨어를 파일로 추상화 한다.
(/dev/ 디렉토리의 파일들은 실제 하드웨어를 표현한다.)

주번호(Major Number) : 응용 프로그램과 디바이스 드라이버를 연결하는 고리 역할 
부번호(Minor Number) : 실질적인 하드웨어

     ㅡ.Device File 만드는 법 (inode를 지원하는 filesystem에서만 가능)
mknod <장치파일명> <종류> <주번호> <부번호>
    ex> monok /dev/gpio c 240 22

디바이스 드라이버도 그 사용에 따라서 구분을 해놓는다.
(날이갈 수록 문자 드라이버와 블록 드라이버 차이가 점점 없어져 가긴하지만...)
그 구분은 다음과같다..

※ 디바이스 드라이버 종류
     ㅡ.문자 디바이스 드라이버 (character device driver)
임의의 길이를 갖는 문자열을 다루는 디바이스 드라이버.
     ㅡ.블록 디바이스 드라이버 (block  device driver)
일정 크기의 버퍼(커널 내부의 버퍼)를 통해 데이터를 처리하는 디바이스 드라이버.
     ㅡ.네트워크 디바이스 드라이버 (network  device driver)
네트워크층과 연결된 디바이스 드라이버로 응용프로그램에서 직접적인 처리가 불가능하다.
커널 내부에 있는 네트워크 프로토콜 스택과 연동해서 사용한다. 
 
디바이스 드라이버를 만든 다음에 이를 어떻게 사용할 것인가?
우리는 응용프로그램에서 장치를 사용하기 위해서 디바이스 드라이버를 만들었다.
그럼 어떻게
자원의 처리를 요청해야 할까?
그 방법으로는 다음과 같이
2가지 방법을 생각할 수 있을 것이다. 

※ 자원처리 요청 방법 
     ㅡ.시스템 호출(system call)
시스템 콜을 사용할 경우 어떻게 작동할지 알아보자.
     o.각 기능 별로 system call번호를 부여
     o.번호에 해당하는 제어 루틴을 커널 내부에 정의
     o.응용프로그램에서 원하는 기능 번호를 레지스터에 저장 후 원하는 기능을 호출(system call)
     o.system call 발생 하면 제어권은 커널이 같는다.
     o.커널내의 서비스 루틴 기능 번호를 살펴보고, 맞는 서비스 루틴을 호출
     o.서비스 루틴이 모두 초리된 후 제어권을 넘겨받음

이와 같은 순서대로 시스템 호출은 이루어 진다.
이때 기능에 따라서 system call 번호를 부여하는데...
일일이 디바이스 드라이버에 system call 번호를 부여한다면 system call 번호가 너무 많아질 것이다.
그럼 관리해야 하는 system call은 증가하고 필요 없는 기능일지라도 커널소스에 포함되어 있어서
커널의 크기가 커지는 단점이 생긴다.

     ㅡ.파일 입출력 형식을 이용한 디바이스 드라이버 사용
<<과정>>
     o. 일반 파일을 제어하듯이 디바이스 파일에 입출력을 시도하고,
     o. 커널내에 해당 디바이스 파일에 연결된 디바이스 드라이버의 서비스 루틴이 호출되서 처리를 한다.(제어권은 커널로...)
     o. 서비스 루틴에서의 모든 처리가 완료되면 제어권은 다시 응용프로그램으로 넘겨진다.

이와 같은 방식을 사용하면 시스템 호출을 이용해서 구현 할 때의 문제가 해결된다(system call 번호문제, 커널의 크기문제)

이렇게 하기 위해 모듈이라는 형식을 빌려서 만든다!!


'Embedded > Device Driver' 카테고리의 다른 글

Device Driver] Kernel Facilities  (0) 2011.04.30
Device Driver] 커널 메시지 출력  (0) 2011.04.25
Device Driver] Hello World 모듈 컴파일  (0) 2011.04.25
Device Driver] 모듈 프로그래밍  (0) 2011.04.25
Device Driver] 시작.  (0) 2011.04.24