디바이스 드라이버

디바이스 드라이버 개발 (1)

Hufs.Woong 2024. 12. 28. 13:21

디바이스 드라이버의 종류

● 문자 디바이스 드라이버

- 대부분의 디바이스 드라이버가 이에 해당, 구현이 매우 간편

● 블록 디바이스 드라이버

- 대용량의 데이터를 저장하는 디바이스에 대해 사용

● 네트워크 디바이스 드라이버

- 외부와 통신을 하며 특히 소켓을 사용하여 통신하는 디바이스에 대해 사용

● 버스 디바이스 드라이버

- USB나 PCI등 여러 다른 디바이스가 꽂히는 포트 디바이스에 대해 사용

- 디바이스를 탐색하고 인식하는 것이 주역할

 

디바이스 노드

디바이스 드라이버를 다루기 위한 특수 파일

 

모든 디바이스 노드는 고유의 타입, 주번호, 부번호를 가짐

● 타입 : 문자형 (c), 블록형 (b)

● 주번호 : 디바이스 드라이버를 구분하기 위한 번호 (0~511)

● 부번호 : 디바이스를 구분하기 위한 번호 (0~1048576)

● 동일한 디바이스 드라이버를 사용하는 여러 디바이스가 존재할 수 있음

 

mknod <파일이름> <타입> <주번호> <부번호> : 디바이스 노드 파일을 생성하는 명령어

● 일반적으로 디바이스 노드는 /dev에만 생성하여 관리함

 

 

간단한 문자형 디바이스 드라이버 실습

커널 모듈을 만들 때 처럼 drivers 안에 폴더를 만들고 main.c를 구현하였다.

 

<linux/device.h>의 주요기능

헤더파일은 리눅스 커널에서 장치와 관련된 기능을 제공한다. 

● struct device : 장치의 속성, 상태, 드라이버 등을 관리하는 구조체

● device_create() : 장치 파일을 생성

● device_destroy() : 장치 파일을 삭제

 

<linux/fs.h>의 주요기능

파일 시스템과 관련된 기능들을 제공한다.

● struct file_operations : 장치 드라이버에서 파일에 대한 연산(열기,읽기,쓰기,닫기 등)을 정의하는 함수 포인터들을 포함하고 있다. 이 구조체는 장치 드라이버가 구현해야하는 주요 인터페이스이다.

open() : 장치 파일을 열 때 호출되는 함수

  read() : 장치 파일에서 데이터를 읽을 때 호출되는 함수

  write() : 장치 파일에 데이터를 쓸 때 호출되는 함수

release() : 장치 파일을 닫을 때 호출되는 함수

 

 

장치의 이름과 주번호를 설정해준다.

 

 

 

inode는 파일 시스템 내에서 파일에 대한 정보를 담고 있는 구조체이다.

iminor(inode) 함수는 이 inode 구조체에서 minor번호를 추출한 다음 minor에 넘긴다.

 

file_operations 구조체를 통해 open,read,write,relaese,ioctl,mmap,flush 함수를 호출할 수 있다.

.open을 통해 장치 파일이 열릴 때 호출될 함수를 지정할 수 있다. 위에선 device_open함수를 지정해서 장치 파일에 대한 정보(minor번호)를 제공받아 장치와의 연결을 설정하였다.

 

모듈이 로드될 때 register_chrdev 함수를 통해 문자 장치를 등록한다. 모듈이 언로드될 때 문자 장치를 해제한다.

 

CROSS_COMPILE을 하면 커널 모듈 때와 동일하게 ko파일이 생성된다.

 

 

ko파일이 생성되면 mount를통해 복사를 해준다.

 

그 다음 qemu 가상머신에 들어가서 mknod 명령어를 통해 장치파일을 생성한다. 장치파일의 유형은 c(문자형)이고 문자 장치는 데이터를 바이트 단위로 처리한다. 150은 주 장치 번호로 위에 있는 MAJOR_NUMBER와 일치시켜야 한다. 주 번호는 커널에서 장치 드라이버를 식별하는 데 사용된다. 34는 부 장치 번호로 같은 장치 드라이버에서 서로 다른 인스턴스를 식별하는 데 사용된다.

 

그리고 cat 명령어를 사용해서 확인을 해보면 open을 할 수 없다고 나오는데 이는 드라이버가 로드되었지 않았기 때문에 발생하는 문제이다.

 

insmod를 통해 ko파일을 로드해준 후 다시 cat명령어를 사용하면 open은 되었지만 read를 구현하지 않았기 때문에 읽을 수 없다는 에러메시지가 뜬다.

 

ls -lah 명령어를 통해서 로드된 모듈을 살펴보면 주 번호와 부 번호 모두 설정한 값으로 들어간 것을 확인할 수 있다.