[Research] Linux Kernel Basic - (7) 디바이스 드라이버(Device Driver) 2편
[Research] Linux Kernel Basic - (7) 디바이스 드라이버(Device Driver) 2편

서론
지난 포스트에서는 커널의 종류인 모놀리식 커널과 마이크로 커널을 알아보았으며 적재 가능 모듈(LKM)이 어떠한 것 인지, 적재 가능 모듈(LKM)으로 사용되는 디바이스 드라이버에 대해 언급하였다. 해당 포스트에서는 캐릭터 디바이스 드라이버(Character Device Driver)를 직접 구현해보며 연구한 것을 토대로 포스트를 작성하겠다.
디바이스 드라이버
디바이스 드라이버의 경우 디바이스 자체에 대한 정보를 세부적으로 알 필요가 없으며 가상파일시스템(VFS)을 이용하여 파일에 대한 접근을 통해 디바이스를 제어할 수 있다. 해당 말을 일반적으로 풀어내면 디바이스 드라이버의 경우 추상화된 장치에 접근하여 정형화 된 인터페이스(open, read, write)과 같은 형태로 접근이 가능하다는 말이다.
User Application 측면
- 하드웨어 장치, 즉 디바이스의 경우 하나의 파일로 인식할 수 있다.
- 정형화된 인터페이스 시스템 호출을 통해 실제 하드웨어 장치에 대한 접근/제어가 가능하다.
Operating System 측면
- 리눅스에서 디바이스는 파일로 취급되며 액세스가 가능하다.
- 파일로 취급되므로 정의된 file operation을 기준으로 접근/제어가 가능하다.
- 각각의 디바이스는 디바이스를 식별하기 위한 Major Number와 Minor Number를 가지고 있다.
Major Number & Minor Number
$ ls -al /dev/*
crw-rw---- 1 root tty 7, 0 Sep 5 17:33 vcs
crw-rw---- 1 root tty 7, 1 Sep 5 17:33 vcs1
crw-rw---- 1 root tty 7, 2 Sep 5 17:33 vcs2
crw-rw---- 1 root tty 7, 3 Sep 5 17:33 vcs3
crw-rw---- 1 root tty 7, 4 Sep 5 17:33 vcs4
crw-rw---- 1 root tty 7, 5 Sep 5 17:33 vcs5
crw-rw---- 1 root tty 7, 6 Sep 5 17:33 vcs6
.
Major Number(주번호)의 경우는 커널에서 디바이스 드라이버를 구분/연결하는 용도로 사용되며 같은 디바이스 종류를 지칭한다. 1byte로 구성된다. Minor Number(부번호)의 경우는 디바이스 드라이버 내에 장치를 구분하기 위해 사용되며 각 디바이스의 부가적인 정보를 나타내며 2byte로 구성된다. 이를 통해 하나의 디바이스 드라이버가 여러 개의 디바이스를 제어 가능하다.
모듈 프로그래밍
chardev.c
1 | |
다음과 같은 디바이스 드라이버 모듈을 작성하였다. module_init의 경우는 해당 모듈이 등록될 경우 실행되는 함수이며, module_exit의 경우는 해당 모듈이 해제될 경우 실행되는 함수이다.
Makefile
1 | |
모듈의 소스코드를 컴파일하기 위해서는 Makefile을 작성해야 한다. 커널 버전과 동일한 형태로 빌드를 진행해야 해당 시스템에서 동적으로 로드할 수 있는 모듈이 된다. 컴파일이 정상적으로 될 경우 chardev.ko 바이너리를 확인할 수 있으며 해당 바이너리가 LKM이다.
커널 모듈의 등록과 해제
$ sudo insmod chardev.ko
$ dmesg
[301222.511894] atkbd serio0: Unknown key released (translated set 2, code 0x72 on isa0060/serio0).
[301222.511896] atkbd serio0: Use 'setkeycodes 72 <keycode>' to make it known.
[301226.623243] atkbd serio0: Unknown key pressed (translated set 2, code 0x72 on isa0060/serio0).
[301226.623250] atkbd serio0: Use 'setkeycodes 72 <keycode>' to make it known.
[301226.623564] atkbd serio0: Unknown key released (translated set 2, code 0x72 on isa0060/serio0).
[301226.623566] atkbd serio0: Use 'setkeycodes 72 <keycode>' to make it known.
[301300.320388] [+] Init Custom Device
.
insmod 명령어를 통해 해당 커널 모듈을 등록할 경우 custom_init 함수가 실행되는 것을 확인할 수 있다.
$ sudo rmmod chardev
$ dmesg
[301222.511894] atkbd serio0: Unknown key released (translated set 2, code 0x72 on isa0060/serio0).
[301222.511896] atkbd serio0: Use 'setkeycodes 72 <keycode>' to make it known.
[301226.623243] atkbd serio0: Unknown key pressed (translated set 2, code 0x72 on isa0060/serio0).
[301226.623250] atkbd serio0: Use 'setkeycodes 72 <keycode>' to make it known.
[301226.623564] atkbd serio0: Unknown key released (translated set 2, code 0x72 on isa0060/serio0).
[301226.623566] atkbd serio0: Use 'setkeycodes 72 <keycode>' to make it known.
[301300.320388] [+] Init Custom Device
[301311.542920] [-] Exit Custom Device
.
rmmod 명령어를 통해 해당 커널 모듈을 해제할 경우 custom_exit 함수가 실행되는 것을 확인할 수 있다.
한줄평
아몬드 넥스트 레벨💁
참고
b30w0lf님의 운영체제(Operating System)
https://butter-shower.tistory.com/29?category=715664
