운영체제,

OS(Operating System) - I/O, polling, Interrupt, DMA

Mar 17, 2021 · 4 mins read

  • 공룡책 10판(Operating System Concepts 10th)과 수업 내용을 참고로 한 내용 정리이다.
  • 정리 목적 그리고 배우는 입장의 포스팅이기에 잘못된 내용이 있을 수 있다.



I/O System(입출력 시스템)

컴퓨터의 주요 작업을 꼽으라면 계산과 입출력 작업을 들 수 있다. 운영체제는 입출력 시 입출력 작업 및 입출력 장치를 관리하고 제어한다.

I/O는 device와 컨트롤러의 버퍼 사이에서의 데이터 흐름이다.(CPU는 컨트롤러의 버퍼와 메인 메모리를 오가며 데이터를 읽어낸다.), 컨트롤러 하나가 여러 장치를 담당하기도 한다.

  • 각 하드웨어에는 컨트롤러라는 것이 존재하는데, 일종의 작은 CPU로 하드웨어를 제어한다. 그리고 이 컨트롤러 안에는 데이터를 임시로 저장하는 작은 메모리 공간을 가지고 있으며 이를 Local Buffer(버퍼)라고 한다.

I/O Operations


입출력 전송을 위해서 처리기는 명령어와 데이터를 컨트롤러에 전달해야 하는데 여러 가지 방법들이 존재한다.

1.Memory Mapped I/O
앞에서 컨트롤러를 언급하며 버퍼를 가지고 있다고 하였는데 사실 레지스터도 가지고 있다.
그래서 본체의 프로세서는 컨트롤러의 레지스터에 비트 패턴을 쓰거나 읽으며 입출력을 수행하게 되고 이 방법 중 하나는 바로 특별한 입출력 명령어를 사용하는 것이다. 입출력 명령어는 한 바이트나 워드를 어떤 입출력 포트 주소로 전달하도록 지정한다.
쉽게 설명하면 buffer에 주소를 통해 접근하는 방법이다. 이 방법은 메모리에 기록하는 것이 매번 입출력 명령어를 사용하는 것보다 빠르기에 현재의 I/O는 대부분 이 방식을 채택한다.

2.Special I/O:
port I/O라는 특수한 명령어 제공
장점: 메모리 주소를 공유하지 않는다(메모리맵드는 메모리 접근, I/O 접근에 동일한 명령어를 사용)
단점: 명령어를 구축해야하는 부담이 생긴다.

3.Polling I/O(Programmed I/O)

  • 모든 입출력 작업을 CPU 명령어를 이용한다.
  • CPU는 계속해서 입출력 장치의 상태를 확인한다. 문제점:
    CPU가 버퍼를 계속 확인(= polling)해야 하므로 비효율적이다.(polling을 하느라 다른 작업을 제대로 수행하지 못함.)
    장치의 제한된 버퍼로는 CPU의 도움이 없다면 오버플로우가 발생할 확률이 높다.

    - Polling
    컨트롤러는 상태 레지스터의 비지 비트를 통해 자신의 상태를 나타냄(바쁠때 1, 다음 명령 대기 = 0), 호스트는 명령 레지스터의 명령 준비 완료 비트(command-read bit)를 통해 입출력을 원한다는 신호를 함.

    호스트는 다음과 같은 방법으로 핸드셰이킹을 통해 컨트롤러와 협력하며 포트를 통해 출력한다.

    –> CPU가 상태 레지스터의 비지 비트가 0이 될때까지 검사
    –> CPU는 명령 레지스터의 write bit를 설정하고 data-out(출력) register에 보낼 데이터를 써줌
    –> CPU는 control register안의 command-ready bit을 설정
    –> 장치 컨트롤러가 command-ready bit의 설정을 발견하고 자신의 비지 비트 설정
    –> 장치 컨트롤러는 명령 레지스터를 읽고 쓰기 명령임을 판단, 출력 레지스터를 읽어 장치로 출력한다.
    –> 장치 컨트롤러는 command-ready bit를 0으로 하고 입출력이 성공했음을 알리기 위해 상태 레지스터의 오류 비트를 0으로 바꾸고, 입출력도 완료하였으니 비지 비트도 0으로 바꾼다.

여기서 CPU는 첫번째 과정에서 비지 비트가 소거될 때까지 루프를 돌며 검사를 반복한다(이 과정이 polling이다). 그리고 이 시간이 길어지면 매우 비효율적일 것이며 몇몇 장치들은 호스트가 빨리 서비스해주지 않으면 데이터는 계속 들어오는데 막상 CPU는 하드웨어가 동작이 끝날 때까지 상태를 체크하니 다른 처리가 계속 미뤄지고 오버플로우를 일으키게 될 것이다.

이런 비효율적인 상황을 보완하기 위해 생겨난 것이 바로 Interrupt이다. 이는 입출력 장치가 CPU에 자신의 상태 변화를 통보하는 하드웨어 기법이다.(반복적인 폴링보다 하드웨어 컨트롤러가 자신의 상태가 바뀔 때 CPU에 통보하는 것이 더 효율적)

Interrupt


인터럽트(Interrupt)란 CPU가 처리 중에 있을 때, 입출력 하드웨어 장치나 다른 예외적 상황의 발생으로 처리가 필요한 상황에 CPU를 불러 처리하도록 하는 것이다.
‘장치 컨트롤러가 인터럽트를 걸면 CPU는 이를 캐치’

즉 치킨을 주문해놓고 문 앞에서 목빠지게 기다렸던 것이 polling 방식이라면, 치킨이 튀겨지는 동안 은행 등의 다른 볼일을 보다가 치킨 집에서 연락이 오면(인터럽트) 맞춰서 찾아가는 효율적인 방식이라고 생각하면 편할 것 같다.

하지만 polling 방식도 높은 처리량을 보이는 I/O에 사용되기에 때로는 polling과 interrupt가 함께 사용되기도 한다.(I/O 발생률이 낮으면 인터럽트, 높으면 폴링 방식으로 전환)

CPU는 IRQ(Interrupt ReQuest) Line을 가지고 있는데, 하나의 명령어의 실행을 완료할 때마다 항상 이 선을 검사한다. 컨트롤러가 이 라인에 신호를 보내면 CPU는 하던 일을 잠깐 멈추고(경우에 따라 인터럽트를 지연시키기도 한다.) 현재 작업 내용을 Context에 잠깐 저장한 상태로 Interrupt handling을 하게 된다. 처리가 끝나면 context를 다시 불러와 작업을 재개한다.
Interrupt handling

  • 시스템 스택에 context를 저장해놓고 일이 끝나면 pop시켜 다시 작업을 한다.
    Polling: 비효율적
    Vectored interrupt system: 가장 많이 쓰이는 방식으로 IRQ에 벡터 값을 넣어서 분기한다.



DMA(Direct Memory Access)


고속 장치에서 들어오는 인터럽트는 CPU에게 부담을 준다. 그래서 부담을 덜어주기 위한 대행자를 만들었는데 그것이 DMA 컨트롤러이다.

역할: 컨트롤러가 장치와 메모리 사이에서 CPU가 개입하지 않고 데이터 전송을 대행해준다.
만약 DMA 컨트롤러가 없다면 CPU에게 매 바이트마다 인터럽트가 들어올 것이다.(물론 CPU가 직접할 때도 있다)




Written by