디바이스 드라이버를 커널에 동적으로 올리는 방법
1. 장치파일 생성(mknod)
- mknod: 장치파일 생성 명령어
mknod ([옵션]) [장치명] [타입] [주번호] [부번호]
# example - char 형 장치파일 생성
mknod /dev/gpio c 230 0
# 장치명: /dev/gpio
# 루트파일시스템 포맷
- 장치명
- 생성할 장치파일의 위치와 장치파일명
- 주번호
- 커널에서 디바이스 드라이버를 구분하고 연결하는데 사용된다. 즉, 주번호는 제어하려는 디바이스를 구분하기 위한 디바이스의 ID 정도로 생각하면 된다.
- 부번호
- 디바이스 드라이버 내에서 장치를 구분하기 위해 사용된다. 즉, 같은 종류의 디바이스가 여러 개 있을 때 그 중 하나를 선택하기 위해 사용된다.
2. 작성한 디바이스 드라이버 파일(object)을 리눅스 커널에 삽입(insmod)
- insmod: 모듈을 리눅스 커널에 삽입하는 명령어
insmod [파일명] ([옵션])
# example
insmod gpio.ko
# 파일명: gpio.ko
# 해당 쉘을 실행하는 쉘 스크립트 경로 기준
- 해당 명령어를 실행하면 디바이스 드라이버 파일 내부 module_init() 함수가 실행된다.
3. 커널 내부에 장치 등록
int register_chdev(unsigned int major, const char* name, struct file_operations* fpos);
// example
register_chdev(230, "gpio", )
- 모듈 적재 시 실행되는 module_init() 함수 내부에서 실행되는 함수로 커널 내부에 등록된 문자장치를 관리하는
chrdev[]
배열 구조체에서 하나의 배열을 할당 받고, 그 배열 안의 필드에 문자장치의 이름과 파일 오퍼레이션을 연결하는 역할을 한다. - 1번 작업으로 만들어 둔 장치파일과 연결된다.
ioctl() 디바이스 제어
- 저수준 파일 입출력 함수로써 디바이스 파일에 적용시키면 디바이스 파일에 연결된 디바이스 드라이버의 file_operations 구조체의 ioctl 필드에 선언된 함수가 호출된다.
- read(), write() 함수와 같이 정형화된 형태를 기본적으로 유지하지만, 사용 방법은 디바이스마다 모두 다르다.
- read(), write()로 다루지 않는 특수한 제어를 한다.
- 응용 프로그램에서 목적에 맞는 디바이스 제어를 위한 시스템 함수를 구현하기 위해 사용한다.
4. 응용프로그램에서 장치파일 열기
- 1번 과정에서 만들어 둔 장치파일을 open() 함수로 열어서 file descriptor 를 받는다.
- file_operations 에 등록된 시스템 함수를 호출하여 디바이스를 제어할 수 있다.
Leave a comment