본문 바로가기
Computer Science/운영체제

Operating System - Ch12: I/O systems

by NCTP 2022. 6. 18.

ㅇ본 글은 Operating System Concepts 10판을 기준으로 작성되었습니다...!

 

 

 

이번 챕터에서는 I/O systems에 대해 알아보자.

 

I/O 연산은 CPU의 I/O 명령에 의해 수행된다.

 

CPU가 I/O 장치에게 명령을 내리는 방법에 따라 Direct I/O와 Memory-mapped I/O로 나뉜다.

하드웨어적인 관점으로 볼 때는 I/O device가 I/O 명령을 수행하는 방식에 따라 Programmed I/O, Interrupt, DMA(Direct Memory Access) 세 가지 방식이 있다.

 

- Programmed I/O는 I/O 장치에서 처리한 결과를 CPU register에 직접 전달하는 방식이다. 이 때는 I/O 연산의 결과값이 작은 경우.(키보드나 마우스)

- 그 결과값이 큰 경우에는 DMA를 사용한다.

- DMA는 CPU가 특정 명령을 내릴 때, I/O controller가 DMA에게 요청을 보내면 DMA가 CPU의 허락을 받아 버스를 통해 CPU를 거치지 않고 데이터를 메모리로 직접 올려주는 경우다.

 

CPU가 I/O명령을 내린다는 것은 결국 I/O controller에게 그 명령과 관련 데이터를 전달하는 것인데,  따라서 I/O controller에는 일반적으로 IR (Intruction Register) 과 DR(Data Register)이 존재한다.

 

Direct I/O

I/O처리를 할 때, 메모리 영역과 I/O 장치 영역을 분리시키는 방법.

따라서 메모리에 데이터를 읽고 쓰는 명령어와 I/O 장치에 데이터를 쓰고 읽는 명령어가 따로 필요하다.

Intel이 이런 방식을 채택한다.

 

장점으로는 메모리 영역과 I/O장치 영역을 분리시켰기 때문에 두 영역 간의 Isolation이 가능하다.

단점으로는 CPU 설계상으로 CPU 명령어가 늘어났기 때문에 하드웨어 설계가 어려워지며 CPU의 핀수가 늘어난다.

 

Memory-Mapped I/O

메모리의 특정 영역을 I/O controller에의 명령으로 매핑시켜서 사용하는 방법.

Direct I/O에서는 메모리에 대한 명령과 I/O controller에 대한 명령이 분리되어 있었는데, 이 방식에서는 메모리의 특정 공간에 명령을 내려서 I/O 장치에 명령을 내린다.

ARM 아키텍쳐 시스템이나 임베디드 시스템에서 이 방식을 채택한다.

 

장점으로는 하드웨어 설계가 간단해지고 CPU 핀수가 적어진다. (ARM이 작지 않는가!)

 

Kernel I/O Structure

키보드, 마우스 등등 의 디바이스와 디바이스마다 연결된 devide controller 까지는 하드웨어 영역이다.

각 컨트롤러에 대응하는 드라이버들이 존재한다. 이 드라이버들이 소프트웨어적으로 컨트롤러를 제어하고, 하드웨어 장치와 kernel 간의 연결을 해주게 된다. 

 

- Kernel I/O subsystem: 아래 단계의 hardware-dependent한 녀석들의 일반적인 부분을 선처리해주는 곳.

 

Goals of I/O Software

I/O 소프트웨어의 목표들. 

- Device independence: 프로그램들이 사전동작 없이 어느 I/O 장치에나 접근할 수 있어야 한다.

- Uniform naming: 파일이나 장치의 이름이 간단한 문자열이나 정수여야 한다.

- Error handling: 최대한 하드웨어와 가깝게 에러를 다루어야 한다.

- Synchronous vs asynchronous: blocked transfers vs interrupt-driven

- Buffering

- Sharable vs dedicated devices

 

Buffering

Buffer: 데이터를 임시로 저장하는 장소

Buffering 버퍼에 데이터를 저장하는 행위.

버퍼링 기법을 네 가지로 나눌 수 있다.

- (a) Unbuffered: 아예 버퍼링을 하지 않는다.

- (b) Buffered in user space: 유저 프로세스에 버퍼링한다.

- (c) Buffered in the kernel space: 커널에 버퍼링한다.

- (d) Double buffering in the kernel: 버퍼링을 커널에 이중으로 한다.

 

성능은 c와 d가 좋다. 운영체제에서 지원하는 기능이기에 유저 차원에서 굳이 유저 프로세스에서 처리하지 않고 버퍼에서  데이터를 끌어다 쓸 수 있으므로 캐싱 차원에서의 이점이 있다. 또한 d같은 경우 두 버퍼에 spatial locality 특성 덕분에 cache hit rate가 올라간다. 대신 커널이 메모리를 많이 쓴다.

 

Error reporting

Error reporting을 잘 해줘야 I/O 장치 protection 차원에서 시스템을 안전하게 할 수 있다. 

Error reporting의 방식은 다음과 같이 있다.

- Returning the system call with an error code: 에러 코드를 시스템 콜로 알려주기

- Retrying a certain number of times: 에러가 발생했을 때 특정 횟수만큼 반복하기.

- Ignoring the error: 에러 무시하기

- Killing the calling process: 에러가 발생하는 프로세스 죽이기.

- Terminating the system: 시스템 종료하기.

 

 

Spooling: 버퍼링과 비슷한 개념인데, 애플리케이션이 I/O 장치에 데이터를 쓰려면 커널에게 시스템 콜을 요청하고 그 데이터를 커널에 쓰는데, 커널이 버퍼에 그 내용들을 저장하고 I/O 장치에 전달을 한다. 이 때, 만약 I/O가 너무 느리다면 커널의 버퍼링 사이즈가 점점 커지면서 메모리를 계속 잡아먹는 문제가 발생한다. 따라서 어차피 느린거 어플리케이션에서 파일로 버퍼링을 하는데, 이를 spooling이라고 한다. 메모리에다가 하느냐, 파일에 하느냐의 차이다.

 

 

 

 

 

 

 

댓글