1. 디바이스 드라이버 일반
파일
- 유닉스 계열 시스템에서 모든 것은 파일로 취급
- 정규파일 : 디스크에 저장되어 있는 파일
- 장치파일 : 장치를 가리키는 파일 (키보드, 마우스 등등)
사용자 태스크 관점에서의 디바이스 드라이버
- VFS 가 제공하는 파일 객체 = 사용자 태스크가 접근하는 장치 파일
- 사용자 태스크가 구조체에 정의되어 있는 함수를 통해 장치파일에 접근 할 때 호출할 함수를 정의하고 구현해 주는 것
- 각 디바이스 드라이버에게 주 번호 지정
- 리눅스는 시스템에 존재하는 여러 개의 디바이스 드라이버를 구분하기 위한 고유한 번호
- 4096개의 주 번호 지원
- 각 장치는 자신을 나타내는 장치 파일을 가짐
- 장치 파일을 관리하는 아이노드 객체에 주 번호가 기록됨
- 디바이스 드라이버를 선택하는 것은 주 번호를 통해서만 이뤄짐
- 종류
- 문자 디바이스 드라이버 : read(), write()함수와 1:1로 매칭되어 디바이스 드라이버 함수 호출
- 블록 디바이스 드라이버 : 큐를 통해 ‘페이지캐시’와 통신
- 네트워크 디바이스 드라이버
개발자 입장에서 디바이스 드라이버
- 디바이스 드라이버
- 리눅스 디바이스 드라이버 구성
- 디바이스 드라이버 코어
- 특정 하드웨어를 위한 것
- 하드웨어 매뉴얼을 참조하여 해당 하드웨어의 특성에 맞도록 작성
- 래퍼 (wrapper)
- 코어를 리눅스에서 사용가능한 형태로 만들어주기 위한 것
- 작성된 코어를 커널에 등록시킨 후 사용자 태스크가 호출할 함수들과 코어의 함수를 연결
리눅스 디바이스 드라이버 관리 구조

- 사용자 태스크
- 디바이스 드라이버 개발자
- 파일 오퍼레이션 구조체에 정의되어 있는 함수를 디바이스 드라이버 내에 구현
디바이스 드라이버를 리눅스에 추가하는 과정
- 디바이스 드라이버 코어 함수 구현
- 작성된 코어 함수를 리눅스에 등록시키기 위한 래퍼 작성
- 디바이스 드라이버 커널 등록
- 디바이스 드라이버를 호출하기 위한 진입점에 해당하는 장치 파일 생성
2. 문자 디바이스 드라이버 구조
→ 실습
3. 블록 디바이스 드라이버 구조
블록 디바이스 드라이버
- 파일 시스템에서 논리적인 블록에 대한 읽기/쓰기 요청이 발생했을 때 이 논리적인 블록을 물리적인 주소로 변환하여 실제 데이터를 주 메모리로 읽어옴
- 디스크에서 사건의 발생을 알렸을 때 그 사건을 처리함
- 문자 디바이스 드라이버와 달리 사용자의 read()/write() 함수와 1:1로 연결되지 않음 → 대신 리눅스 페이지캐시와 통신
리눅스 I/O 스케줄러
- CFQ (Completely Fair Queuing) 정책
- 기본적으로 64개의 큐 유지
- 태스크의 PID 해쉬 값을 인덱스로 하여 I/O 요청을 각 큐에 나누어 저장
- 각 큐에서 공평하게 I/O 요청을 꺼내어 디바이스 드라이버의 큐에 넣음
- Deadline 정책
- 읽기 요청과 쓰기 요청이 완료되어야 하는 시간(deadline)을 지정하여 특정 I/O 요청이 병합이나 순서 변경 등의 이유로 장시간 대기하는 것을 방지
- Anticipatory
- deadline + 시스템 성능 향상을 위해 두가지 기법 추가
- NOOP
- 아무 일도 하지 않음
- I/O 스케줄링으로 인한 성능 향싱이 적은 SSD등의 저장장치가 존재하기 때문에 존재
이 글은 아래의 책을 공부 및 정리한 내용입니다.
리눅스 커널 내부구조 - 예스24