2024. 6. 8. 13:39ㆍCS/Operating System
device drivers
- 각 디바이스를 제어하기 위한 디바이스 별 코드이다.
- 디바이스 드라이버가 인터럽트 핸들러와도 작용하고 device-independent I/O 소프트웨어와도 작용한다.
- 디바이스 드라이버는 OS와 상호작용하기 위한 잘 정의된 모델과 standard interface가 필요하다.
- 디바이스 드라이버는 세 가지 방식으로 구현된다.
- static 하게 커널과 linked 되는 방식
- 부팅할 때 전부 로드되는 방식
- 필요할 때 dynamic 하게 로드되는 방식
문제가 되는건 device driver 코드가 운영체제 내부에 있는 코드와 같이 동작할 텐데, 이 코드가 조금만 잘못되어도 운영체제가 고장 난다. 따라서 드라이버의 가장 중요한 점은 reliablility : 안정성이다.
특히 unmanaged system에서 고장나면 고치는데 오랜 시간이 걸린다. 이러한 문제는 운영체제를 만드는 사람과 디바이스를 만드는 사람이 다르기에 쉽게 해결할 수 있는 문제가 아니다.
또, 디바이스 드라이버는 굉장히 많다.
대략적으로 12만개의 드라이버 버전이 존재하는데, 중요한 점은 뭔가 드라이버에 문제가 생기면 운영체제 전체를 날려야 한다. 또, 여러 회사의 디바이스를 사용할 텐데, 한 디바이스만 썼을 때 괜찮았는데 여러 회사를 섞어서 사용하면 뭔가 서로 꼬이면서 망가지는 현상이 생긴다.
Device-Independent I/O SW
device driver 상위의 레이어는 Device-Independent I/O SW이다. 대부분의 운영체제는 IO 장치를 특별한 파일로 본다.
- system call을 통해 파일을 사용할 수 있다. open, read, write 등의 시스템 콜을 호출하는 것은 IO 장치에 대고 input, output하는 것과 똑같다.
- 디바이스별로 파일 이름이 할당되고 /dev 디렉토리 안에 존재한다.
device에는 Major number, Minor number를 부여한다.
- Major number는 디바이스 종류이다. 적절한 드라이버를 찾는 데 사용된다.
- 커널은 Major number를 통해 어떤 드라이버가 어떤 디바이스를 제어하는지 확인한다.
- Minor number는 포트 번호, 버전 넘버 등의 정보를 담고 있고 드라이버에 파라미터로 전달되어 특정 유닛을 지정한다.
- 파일을 protection 하듯이 I/O device 또한 protection이 가능하다. 파일에 대해 권한을 부여해서 해당 디바이스에 대해 권한을 부여하는 것이고, 어떤 종류의 디바이스던 파일로 다루므로 굉장히 좋은 인터페이스이다.
Error Reporting
- 이 인터페이스가 해야 하는 중요한 일은 error reporting이다. I/O 디바이스는 기계적 장치기 때문에 항상 실패할 수 있다.
- 대신 에러가 생기면 에러를 해결할 필요는 없다. 왜 에러가 났는지, 어디서 났는지를 잘 리포팅해야 하고 그걸 잘하는 게 장치를 파일로 보는 인터페이스이다. 프로그래머가 실수했는지, 기계장치가 잘못되었는지를 잘 알려준다.
- 에러를 핸들링하는 방식은 에러 코드와 함께 system call을 종료하거나, 에러를 무시하거나, 몇 번 재시도하거나, 프로세스를 죽이거나 할 수 있다.
Device-Independent I/O SW에서 더 위로 올라가면 User-Space I/O Software가 있다. 라이브러리로 제공되는 fopen, fgets, scnaf 이런 게 존재하고 사용자가 실제로 사용하기 위한 인터페이스이다. fopen은 결국 open 시스템 콜로 바뀌게 되고 fgets나 fscanf나 결국 read 시스템 콜로 바뀌게 되는 것이다.
I/O System Layer 총 정리
- User Processes가 I/O를 호출한다.
- Device-independent software가 file을 기반으로 어떤 디바이스를 오픈했는지, blocking인지 character인지 판단하고, 권한이 있는지 확인한 뒤에 드라이버에 요청한다.
- 드라이버는 레지스터를 세팅해서 하드웨어로 바로 보낸다. 여기서 Direct I/O, Memory Mapped I/O로 나뉜다.
- 하드웨어가 I/O를 수행하는데, Programmed I/O 방식이면 CPU가 관여하고 DMA 방식이면 DMA Controller가 관여한다.
- 작업이 끝났는지 확인하는 방식은 Polling I/O라면 CPU가 계속 체크하고, Interrupt-driven I/O라면 Interrupt를 발생시켜 Interrupt handler가 작동한다.
- Interrupt handler는 다시 계층을 올라가면서 I/O가 끝나게 된다.