다양한 입출력 방법
* 혼자공부하는 컴퓨터구조 운영체제를 공부하며 정리해였습니다.
세가지 입출력 방식
- 프로그램 입출력
- 인터럽트 기반 입출력
- DMA 입출력
1. 프로그램 입출력
- 입출력장치에 연결된 장치 컨트롤러를 프로그램속 명령어로 제어하는 방법이다.
메모리에 저장된 정보를 하드 디스크에 백업하는 과정을 생각해보자
(== 하드디스크에 새로운 정보 쓰기)
1. CPU는 하드 디스크 컨트롤러의 제어 레지스터에 쓰기 명령 내보내기
2. 하드 디스크 컨트롤러는 하드 디스크 상태 확인 -> 상태 레지스터에 준비 완료 표시
3-1 CPU는 상태 레지스터를 주기적으로 읽어보며 정보를 데이터 레지스터에 쓴다.
3-2 하드 디스크가 준비되었다면 백업할 메모리의 정보를 데이터 레지스터에 쓴다.
** 아직 백업작업(쓰기 작업)이 끝나지 않았다면 1번부터 반복, 쓰기가 끝났다면 작업 종료
CPU가 장치 컨트롤러의 레지스터 값을 읽고 씀으로써 이루어진다.
그런데, CPU가 이 장치 컨트롤러의 레지스터들 (입출력장치의 주소)를 어떻게 알까?
그러니까, 이런 명령어들은 어떻게 명령어로 표현되고, 어떻게 메모리에 저장될까?
- 프린터 컨트롤러의 상태 레지스터를 읽어라
- 프린터 컨트롤러의 데이터 레지스터에 100을 써라
- 키보드 컨트롤러의 상태 레지스터를 읽어라 등등 이런 명령어들
두가지 방법이 있다.
- 메모리 맵 입출력
- 고립형 입출력
1) 메모리 맵 입출력
- 메모리에 접근하기 위한 주소 공간과 입출력자치에 접근하기 위한 주소공간을 하나의 주소 공간으로 간주하는 방법
ex)
516번지: 프린터 컨트롤러의 데이터 레지스터
517번지: 프린터 컨트롤러의 상태 레지스터 등등
518번지: 하드 디스크 컨트롤러의 데이터 레지스터
519번지: 하드 디스크 컨트롤러의 상태 레지스터
2) 고립형 입출력
- 메모리를 위한 주소공간과 입출력 장치를 위한 주소 공간을 분리하는 방법이다.
- 1024개의 공간이 있다면 1024 모두 메모리로도 쓸 수 있고 입출력으로도 쓸 수 있다.
- 입출력 전용 명령어를 실행하여 할당한다. (입출력 읽기 / 쓰기 선을 활성화 시키는)
즉 차이점은, 명령어가 다르다는 점이다.
2. 인터럽트 기반 입출력
- 하드웨어 인터럽트는 사실 장치컨트롤러에 의해 발생한다.
- CPU는 좀 더 효율적으로 일할 수 있다.
** 인터럽트와 반대되는 개념을 폴링이라고 한다.(일반 프로그램 입출력, CPU가 주기적으로 확인 할 수 밖에 없는 입출력)
그러나 입출력장치는 굉장히 많다.
그렇기 때문에 동시다발적으로 인터럽트는 발생하게 되는데.
이때 실제로 인터럽트 발생 순서대로 순차적으로 처리하게 끔 할 수 있으나 (하드웨어 인터럽트)
순차적으로 처리가 불가능한 인터럽트들(non - maskable / NMI - 하드웨어 고장, 정전 등 빨리 처리해야하는 크리티컬한 상황)은 순차적으로 처리 할 수가 없다. (우선 순위가 있다.)
가장 대표적인 해결 방식: PIC (Programmable Interrupt Controller)
- 여러 장치 컨트롤러에 연결되어, 하드웨어 인터럽트의 우선순위를 판단한 뒤
- CPU에게 지금 처리해야 하는 인터럽트가 무엇인지 판단하는 하드웨어
- ** NMI 우선순위까지 판단하지는 않음 - NMI가 발생하면 CPU에 다이렉트로 바로 처리하는 경우가 많음
- PIC는 장치컨트롤러와 CPU 사이에서 어떤 인터럽트를 가장 먼저 처리해야되는지를 판단해서 CPU에게 알려준다.
보통 여러개를 사용한다고 합니다.
공통점: 입출력장치와 메모리 간의 데이터 이동은 CPU가 주도하고 이동하는 데이터도 반드시 CPU를 거친 다는 점이다.
DMA 입출력 방식
가뜩이나 바쁜 CPU가 입출력장치와 메모리 사이에 전송되는 모든 데이터가 반드시 CPU를 거쳐야 한다면 입출력장치를 위한 연산 때문에 시간을 뺏기게 될 것이다. 특히 하드디스크 백업과 같이 대용량 전송이라면??
-> 이를 해결한 부분이 DMA이다. (Direct Memory Access)
- CPU를 거치지 않고 입출력장치가 메모리에 직접적으로 접근하는 기능
- DMA는 CPU를 거치지 않고 메모리와 입출력장치간의 데이터를 주고받는 입출력 방식이다.
- DMA 컨트롤러가 필요.
순서
1. CPU는 DMA 컨트롤러에 입출력 작업을 명령
2. DMA 컨트롤러는 CPU 대신 장치 컨트롤러와 상호작용하며 입출력 작업을 수행
(이때 DMA 컨트롤러는 필요한 경우 메모리에 직접 접근한다.)
3. 입출력 작업이 끝나면 DMA 컨트롤러는 인터럽트를 통해 CPU에 작업이 끝났음을 알린다.
4. 결과적으로 CPU는 입출력 작업의 시작과 끝만 관여한다.
단점: DMA 과정에서 시스템 버스를 이용, 그런데 시스템 버스는 공용 자원이기때문에 동시 사용이 불가능하다.
-> CPU와 DMA 둘중 하나가 쓰고있으면 반대편은 쓰지 못함.
그래서 DMA 컨트롤러는 2가지 방법으로 시스템 버스를 이용한다.
1) CPU가 시스템 버스를 이용하지 않을 때마다 조금씩 시스템 버스 이용
2) CPU가 일시적으로 시스템 버스를 이용하지 않도록 허락을 구하고 시스템 버스 이용 -> Cycle stealing이라고 한다.
수많은 장치컨트롤러들이 시스템버스에 연결되어 있어도 괜찮을까?
- 사실 괜찮지는 않다.
- 직접적으로 연결되면 DMA를 하는 과정에서 시스템버스를 2번 이용하게 된다.
- 이를 방지하기 위해 장치컨트롤러는 입출력버스라는 버스에 연결되게 된다.
입출력버스 -> PCI 버스, PCI express(PCIe) 버스와 입출력 장치를 연결짓는 슬롯
슬롯 -> 입출력버스 -> 시스템버스
더욱 발전한 DMA, 입출력 프로세서 (입출력 채널)을 다는 수준까지 올랐다.
최근에는 RAM을 탑재하거나 CPU를 탑재하는 경우도 생기고 있다.