본문 바로가기

테크

[디바이스 드라이버] Chapter7. 디바이스 드라이버의 초기화와 종료

Chapter 7. 디바이스 드라이버의 초기화와 종료

1. 초기화와 종료 처리디바이스
1.1 드라이버가 동작하기 위한 초기화/종료에 필요한 처리 항목(대표적)
  • 디바이스 드라이버의 등록과 해제
  • 디바이스 드라이버에 내부 구조체의 메모리 할당과 해제
  • 여러 프로세스가 하나의 디바이스에 접근할 때 필요한 사전 처리 및 종료 시 처리
  • 주 번호에 종속된 부 번호를 관리하기 위한 사전 처리 및 종료 시 처리
  • 하드웨어 검출 처리 및 에러 처리
  • 하드웨어 초기화와 제거 가능한 하드웨어의 제거 처리
  • 응용 프로그램에서 디바이스 드라이버를 사용하는 경우의 초기 처리 및 사용 종료 처리
  • 부 번호에 관련된 프로세스별 처리
  • 프로세스별 메모리 할당과 해제
  • 사용하는 모듈 수의 관리

1.2 디바이스 드라이버의 초기화/종료 처리 시점
  • 모듈 적재와 커널 부팅 처리 과징 / 제거 과정
    - insmod 명령 : module_init : 모듈 적재과정
    - rmmod 명령 : module_exit : 모듈 제거 과정
  • 응용프로그램이 디바이스 파일을 여는 과정과 닫는 과정
    - open() 함수 : file_operations.open : 디바이스 파일을 여는 과정
    - close() 함수 : file_operations.release : 디바이스 파일을 닫는 과정

1.3 모듈 초기화와 종료
1.3.1 module_init의 초기화 처리
  • 디바이스 드라이버의 등록
  • 디바이스 드라이버에 내부 구조체의 메모리 할당
  • 여러 프로세스가 하나의 디바이스에 접근하는 경우에 필요한 사전 처리
  • 주 번호에 종속된 부 번호를 관리하기 위한 사전 처리
  • 하드웨어 검출 처리 및 에러 처리
  • 하드웨어 초기화

1.3.2 module_exit의 종료 처리
  • 디바이스 드라이버의 해제
  • 디바이스 드라이버에 할당된 모든 메모리의 해제

※ 실제로 디바이스 드라비어가 사용되는 시점 : 응용프로그램에서 open()함수로 열었을때 부터

1.3.3 open()함수 호출시 초기화 처리
  • 디바이스 드라이버가 처음 열렸을 때 하드웨어 초기화
  • 디바이스 드라이버의 동작에 필요한 에러 체크
  • 부 번호에 대한 처리가 필요한 경우 파일 오퍼레이션 구조체를 갱신
  • 프로세스별 메모리 할당과 초기화
  • 모듈의 사용 횟수 증가(kernel 2.4)

1.3.4 release()함수 호출시 종료 처리
  • 프로세스별 할당 메모리 해제
  • 모듈 사용 횟수 감소(kernel 2.4)


2. 모듈 사용 횟수 관리
디바이스 드라이버가 모듈 형태라면 커널에 추가하거나 삭제하는 행위가 발생.
프로세스가 드라이버를 사용하는 도중에 디바이스 드라이버 모듈을 커널에서 제거하면 커널 자체에 문제가 생기므로 커널을 디바이스 드라이버의 사용 횟수를 감시하고, 사용하지 않을 때만 삭제할 수 있게 해야한다.

커널 2.4 : 디바이스 드라이버에서 사용 횟수 관리
/linux/modules.h
  • MOD_INC_USE_COUNT : 모듈 사용 횟수를 증가시킨다.
  • MOD_DEC_USE_COUNT : 모듈 사용 횟수를 감소시킨다.
  • MOD_IN_USE : 모듈 사용 횟수가 0이 아니면 참값을 반환한다.
open()함수 : MOD_INC_COUNT 매크로를 이용하여 모듈 사용횟수 증가

release()함수 : MOD_DEC_USE_COUNT 매크로를 이용하여 모듈 사용횟수 감소


커널 2.6 : 커널에서 사용 횟수 관리
핫 플러그인 처리가 필요한 경우처럼 디바이스 드라이버의 사용횟수를 직접 관리해야할 경우에
사용하는 함수
  • try_module_get(THIS_MODULE);: 모듈의 사용 횟수를 증가시킨다.
  • module_put(THIS_MODULE);: 모듈의 사용 횟수를 감소시킨다.
open()함수 : try_module_get() 함수를 이용하여 모듈 사용횟수 증가

release()함수 :     module)put() 함수를 이용하여 모듈 사용횟수 감소

3. I/O 영역의 경쟁 처리 함수

3.1 I/O 포트 영역의 경쟁 처리 함수
#include <linux/ioport.h>
  • check_region : 등록할수 있는 I/O 영역인지 확인한다.
    int check_region(unsigned long from, unsigned long extent);
  • request_region : I/O 영역을 등록한다.
    void request_region(unsigned long from, unsigned long extend, const char * name);
    ※ request_region 등록시 지정하는 문자열은 디바이스 드라이버의 이름을 사용
        cat /proc/ioports
  • release_region : 등록된 I/O 영역을 해제한다.
    void release_region(unsigned long from, unsigned long extent);

자원의 충돌을 해결하기 위해 함수 사용 순서
  1. 디바이스 드라이버 초기화 루틴에서 check_region() 함수를 사용해 해당 I/O영역의 사용 여부를 확인
  2. 해당 영역을 사용하지 않고 있다면 request_region() 함수를 사용해 점유 영역을 새로 등록
  3. 디바이스 드라이버를 제거 할 때는 release_region() 함수를 사용해 등록된 영역을 제거

3.2 I/O 메모리 영역의 경쟁 처리 함수
 #include <linux/ioport.h>
  • check_mem_region : 등록된 자원인가를 확인한다.
    int check_mem_region(unsigned long from, unsigned long extent);
  • request_mem_region() : 자원을 등록한다.
    void request_mem_region(unsigned long from, unsigned long extent, const char * name);
  • release_mem_region() : 등록된 자원을 제거한다.
    void release_mem_reion(unsigned long from, unsinged long extent);

* 디바이스 드라이버 초기화와 종료 함수 정리




※ 이 자료를 공부한 것을 정리하기 위하여 한빛미디어 리눅스 디바이스 드라이버란 책을 기반으로 
   작성되어 졌습니다.