[입출력 장치]
- 컴퓨터 외부에 연결되어 컴퓨터 내부와 정보를 교환하는 장치이다.
- 다양한 장치가 존재하며, 장치마다의 속도, 데이터 전송 형식도 저마다 달라서 이렇게 다양한 입출력 장치와 정보를 주고받는 방식을 규격화 하기 어렵다.
- 일반적으로 CPU와의 데이터 전송률은 메모리에 비해 낮은 편이다.(속도가 빠른 장치도 있으나, 일반적으론 대게 느린 편이다)
[장치 컨트롤러]
- 입출력 제어기(I/O controller) | 입출력 모듈(I/O module) 로 불린다.
- CPU 와 입출력 장치 간의 통신 중개를 해줌으로써 CPU 와 입출력 장치간의 번역기 역할을 수행한다.
- 오류를 검출해줌으로써 입출력 장치에 이상이 없는지를 확인해준다.
- 데이터 버퍼링, 즉 전송률이 높은 장치와 낮은 장치 사이에 주고 받는 데이터를 '버퍼' 라는 임시 저장 곤강에 저장하여 전송률을 비슷하게 맞춰주는 기능을 제공한다. 데이터를 버퍼에 일정량을 모아둔 뒤 한 번에 전송하는 방식을 사용함으로써 전송률 차를 줄여준다.
장치 컨트롤러는 크게 다음과 같은 구조로 이뤄져 있다.
데이터 레지스터 - CPU 와 입출력 장치 사이에 주고받을 데이터가 담기는 레지스터(버퍼)
RAM 을 사용하기도 한다.
상태 레지스터 - 상태 정보를 저장
입출력 장치가 입출력 작업을 할 준비가 되었는지 확인입출력 작업이 완료되었는지 확인입출력 장치에 오류는 없는지 등의 상태 확인
제어 레지스터 - 입출력 장치가 수행할 내용에 대한 제어 정보 저장
(상태 레지스터와 제어 레지스터는 하나의 상태/제어 레지스터로 사용되기도 한다)
이 레지스터들이 입출력 버스에 연결되어 입출력 장치와의 데이터 교환을 이뤄준다.
[장치 드라이버]
장치 컨트롤러의 동작을 감지하고 제어하는 프로그램
컴퓨터(운영 체제)가 연결된 장치의 드라이버 인식하고 실행할 수 있으면 입출력 장치와 정보를 주고 받을 수 있지만, 그렇지 않다면 주고 받을 수 없다.
[입출력 방식]
- 입출력 방식은 다음과 같이 세 가지 방식으로 나눠진다.
1. 프로그램 입출력 - 프로그램 속 명령어로 입출력 장치에 연결된 장치 컨트롤로는 제어하는 방법
메모리에 저장된 정보를 하드 디스크에 백업을 할 시(HDD 에 새로운 정보를 쓸 시) 구동 방식으로 설명하자면
1. CPU 는 HDD 컨트롤러의 제어 레지스터에 쓰기 명령을 내보낸다.
2. HDD 컨트롤러는 HDD 상태를 확인해서 준비가 되었다면 상태 레지스터에 준비 완료로 표시해준다.
3. CPU 는 상태 레지스터를 주기적으로 읽으면서 HDD 의 준비 여부를 확인하고, 준비가 되었다면 백업할 메모리의 정보를 데이터 레지스터에 쓰는에 이 과정이 백업이 끝날 때까지 수행한다.
CPU가 장치 컨트롤러의 레지스터 값을 읽고 씀으로서 이루어지는 방식이다.
위와 같이 레지스터를 찾아서 읽는 방식이 가능한 이유로는 메모리 맵 입출력과 고립형 입출력
메모리 맵 입출력 - 메모리에 접근하기 위한 주소 공간과 입출력 장치에 접근하기 위한 주소 공간을 하나의 주소 공간으로 간주하는 방법
즉, 어떠한 컴퓨터가 사용할 수 있는 총 주소 공간을 메모리를 위해서만이 아닌 입출력 장치를 위한 공간으로도 같이 사용한다는 것이다.
이렇게 운영했을 때, 입출력을 읽는 과정의 명령어는 메모리를 읽는 과정의 명령어와 똑같은 형식을 사용하여 읽을 수 있다.
고립형 입출력 - 메모리를 위한 주소 공간과 입출력 장치를 위한 주소 공간을 분리하는 방법
입출력 전용 명령어 형식을 사용함으로써 입출력 전용 버스를 통해서 읽고 쓴다.
2. 인터럽트 입출력 - 장치 컨트롤러에 의해 발생하는 인터럽트를 CPU 가 읽어서 작동하는 방법
인터럽트 신호가 CPU에 전달되기 때문에 프로그램 입출력 처럼 CPU가 상태 레지스터를 계속 읽어야하는 작업이 없어도 돼 조금더 효율적인 운영이 가능하다.
동시 다발적인 인터럽트가 발생할 때 플래그 레지스터 속 인터럽트 비트를 비활성화하면 인터럽트를 순차적으로 처리가 가능하다.
순차적으로 처리가 불가능한 인터럽트(NMI, Non maskable Interrupt)는 예외로 먼저 처리 하겠끔 되어있어, 여기서 말하고자 하는 인터럽트는 <하드웨어 인터럽트>에 한해서 성립되는 내용이다.
하지만 인터럽트에는 우선 순위란게 존재하기 때문에 모든 인터럽트를 순차적으로 처리할 수 없다.
그래서 플래그 레지스터 속 인터럽트 비트를 활성화하면 우선 순위를 반영한 인터럽트 처리를 할 수 있다.
NMI 처리도 이러한 방식으로 처리된다.
PIC(Programmable Interrupt Controller) - 여러 장치 컨트롤러에 연결되어 장치 컨트롤러들과 CPU 사이에서 장치 컨트롤러의 h/w 인터럽트의 우선 순위를 판단한 뒤, CPU 에게 지금 처리해야 하는 인터럽트가 무엇인지 판단해주는 하드웨어이다.
(NMI 의 우선 순위는 판단하지않고, 하드웨어 인터럽트의 우선 순위만 판단한다)
PIC 는 여러 개를 사용하기도 한다.
3. DMA(Direct Memory Access) 입출력 - 위의 두 가지 방식은 CPU가 데이터 이동을 주도하고, 이동하는 데이터도 반드시 CPU를 거치는데,
DMA는 DMA 컨트롤러를 통해서 CPU 를 거치지 않고 입출력 장치가 메모리에 직접적으로 접근 가능한 방법이다.
DMA 는 CPU 의 과도한 업무량을 줄여주는 서포팅을 제공한다.
그 과정은 다음과 같이 이뤄진다.
1. CPU 는 DMA 컨트롤러에 입출력 작업을 명령한다.
2. DMA 컨트롤러는 CPU 대신 장치 컨트롤러와 상호작용하면 입출력 작업을 수행한다.
3. 입출력 작업이 끝나면 DMA 컨트롤러는 인터럽트를 통해 CPU 에 작업이 끝났음을 알린다.
DMA 과정에선 시스템 버스를 이용하는데, 시스템 버스는 공용 자원이기 때문에 복수의 장치가 동시에 사용할 순 없다.
CPU 가 시스템 버스 사용시 DMA 컨트롤러는 시스템 버스를 사용할 수 없고,
DMA 컨트롤러가 시스템 버스를 사용시 CPU 는 시스템 버스를 사용할 수 없게 된다.
그렇기 때문에 DMA 컨트롤러는
CPU 가 시스템 버스를 이용하지 않을 때마다 조금씩 사용하거나,
CPU 가 일시적으로 시스템 버스를 이용하지 않도록 허락을 구해서 사용하는 방식을 이용한다.
이 방식들이 마치 CPU 의 시스템 버스 이용 사이클을 도둑맞는 듯하게 보여
Cycle Stealing 이라고도 부른다.
위에서 보여준 그림을 보면 장치 컨트롤러들이 시스템 버스에 직접 연결되어 있지만, 이같이 장치 컨트롤러들이 시스템 버스에 직접 연결하게 되면 DMA 컨트롤러는 불필요하게 시스템 버스를 두 번 이용하게 된다 (메모리에서 읽어올 때, 장치 컨드롤러를 쓸 때) 이런 식이면 시스템 버스를 점유 시간이 늘어나는 경향도 생기며, CPU 의 시스템 버스 활용면에서도 영향이 생길 수 있는데 이를 해결할 방법이 프로그램 입출력 부분에서 고립형 입출력에서 언급한 입출력 전용 버스를 사용하는 것이다.
이렇게 입출력 전용 버스를 이용함으로써 시스템 버스 사용 빈도를 낮출 수 있다.
입출력 전용 버스로는 PCI 버스, PCI express(PCIe) 버스 등이 있다.
그림에 표시된 슬롯들이 결국 입출력 버스와 연결되는 슬롯이라고 보면된다.
DMA 는 오늘날 더 발전해서 입출력 전용 프로세서(입출력 채널)를 사용하기도 한는데,
이는 DMA 컨트롤러가 입출력 작업을 수행하는 입출력 전용 명령어를 실행하는 것까지도 수행하는 방식이다.
(이런식으로 입출력 장치에 RAM 이 탑재되거나 입출력 전용 CPU를 탑재하는 하드웨어도 있다)