Notice
Recent Posts
Recent Comments
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

topcue

[OS] I/O Devices 본문

Operating System

[OS] I/O Devices

topcue 2021. 9. 3. 23:32

System Architecture

다음은 전형적인 컴퓨터 시스템을 도식화한 그림이다.

CPU가 memory bus를 통해 메인 메모리와 연결되어 있는 것을 볼 수 있다. 그리고 몇몇 장치들이 general I/O bus(PCI)를 통해 연결되어 있다. 더 내려가보면 SCSI, SATA, USB와 같은 peripheral bus를 볼 수 있다.

이렇게 계층적인 구조를 갖는 이유는 물리적 한계와 비용 때문이다.

A Canonical Device

이번에는 canonical device를 고려해보자.

크게 interfaceinternals로 나눌 수 있다.

The Canonical Protocol

아주 간략화한 위 그림에서는 세 레지스터밖에 없다.

  • status register

장치의 현재 상태를 나타내는 레지스터.

  • command register

장치가 수행해야 할 특정 task를 가리키는 레지스터.

  • data register

데이터를 장치로 보내거나, 장치에서 데이터를 가져오기 위한 레지스터.


이번에는 OS와 장치 사이의 전형적인 상호작용을 살펴보자.

While (STATUS == BUSY)
	; // wait until device is not busy
Write data to DATA register
Write command to COMMAND register
	(Doing so starts the device and executes the command)
While (STATUS == BUSY)
	; // wait until device is done with your request

프로토콜은 4 단계로 나누어져 있다.

  1. OS는 status register를 반복적으로 읽으면서 장치가 명령어를 받을 준비가 될 때까지 기다린다. 이것을 '장치를 polling한다'라고 부른다.
  1. OS가 데이터를 data register로 보낸다. 예를 들어 디스크라면 4KB disk block을 장치로 전달하기 위해 여러 번의 쓰기가 필요하다는 것을 생각해 볼 수 있다. 메인 CPU가 데이터 이동을 참조한다면 이를 PIO(programmed I/O)라고 부른다.
  1. OS가 command register에 명령어를 쓴다.
  1. OS는 loop에서 polling하면서 장치가 작업을 끝내고 성공/실패를 나타내는 에러 코드 등을 기다린다.

그러나 위 프로토콜은 몇 가지 문제를 포함하고 있다.

문제점 중 하나는 polling이 비효율적이라는 것이다. 장치의 동작은 매우 느릴 수 있는데, 그동안 다른 ready 프로세스로 switch하지 않고 CPU를 낭비하면서 기다린다.

Lowering CPU Overhead With Interrupts

이 interaction을 개선하는 좋은 방법은 interrupt를 이용하는 것이다.

장치를 반복적으로 polling하는 대신 OS가 요청을 통해 프로세스를 sleep하게 하고 context switching으로 다른 작업으로 전환할 수 있다.

장치의 작업이 끝나면 하드웨어 인터럽트가 발생해 CPU가 정해진 ISR(Interrupt Service Routine)에서 OS로 점프하거나 interrupt handler를 작동시킨다.

하지만 interrupt가 만능은 아니다. 실제로는 polling과 interrupt를 적절히 섞어서 사용한다.

More Efficient Data Movement With DMA

위 프로토콜(canonical protocol)의 또 다른 문제점 다음과 같다.

위 그림은 프로세스1이 수행되다가 데이터를 디스크에 쓰기 위해 메모리에서 데이터를 복사한다(c). 복사가 완료된 뒤 디스크 I/O가 시작되면서 sleep하고 프로세스2가 실행되는 모습이다. 이때 데이터를 복사하는 동안(c) CPU가 낭비된다.

이런 문제는 DMA(Direct Memory Access)를 사용하는 것이다. DMA는 CPU를 쓰지 않고 메모리와 장치 간의 데이터 전송을 조율하는 장치다.

다음 그림은 DMA를 이용해 위 작업을 수행한 것이다.

메모리의 데이터 복사를 DMA가 수행해 그동안 CPU가 프로세스2를 수행하는 것을 알 수 있다.

OS가 DMA에게 데이터의 위치, 복사할 크기, 데이터를 받을 장치를 알려주면 DMA가 복사를 처리하고, 이후 DMA 컨트롤러가 interrupt를 이용해 복사가 완료되었음을 OS에게 알린다.

Methods Of Device Interaction

이번에는 OS와 장치가 interaction하는 방법을 알아보자.

먼저 명시적으로 I/O instruction을 사용하는 방법이 있다. OS가 특정 device register에 데이터를 전송하는 방법을 지정해 위에서 다룬 프로토콜을 구성해 사용한다.

두 번째는 memory-mapped I/O 방식이다. 이 방식으로 하드웨어에서 device register를 메모리처럼 사용할 수 있다. 특정 레지스터에 접근하기 위해 OS는 주소를 LD/ST 하며 하드웨어는 이를 장치로 라우팅한다.

현재는 이 두 가지 방법을 적절히 섞어서 사용하고 있다.

Fitting Into The OS: The Device Driver

마지막 문제는 장치마다 다른 인터페이스를 가지고 있는데, 이를 하나의 OS에서 사용할 수 있도록 하는 것이다.

예를 들어 파일 시스템만 살펴보아도 SCSI, IDE 디스크, USB 드라이브 등 여러 종류의 파일 시스템이 존재하는데, 이들이 한 OS에서 동작해야 한다.

이를 위해 device driver라는 소프트웨어가 필요하다. device driver를 이용해 장치의 모든 interaction을 캡슐화할 수 있다.

Case Study: A Simple IDE Disk Driver

device driver를 자세히 다루기 위해 실제 장치인 IDE disk drive를 예로 살펴보자.

IDE 디스크는 control, command block, status, error 네 가지 레지스토러 구성된 인터페이스를 제공한다. 이 레지스터들은 in, out I/O instruction을 사용해 특정 I/O address를 읽거나 쓸 수 있다.

이 인터페이스가 장치와 상호작용하는 기본적인 프로토콜을 살펴보자. 이때 초기화는 되어있다고 가정하자.

  • Wait for drive to be ready.

    장치가 READY일 때까지 status register를 읽는다.

  • Write parameters to command registers.

    command register에 sector count, 접근할 섹터의 LBA(logical Block Address), drive number를 쓴다.

  • Start the I/O. READ-WRITE command를 command register에 써서 read/write를 실행한다.
  • Data transfer (for writes):

    드라이브 상태가 READY 및 DRQ(Drive Request for data)가 될 때까지 기다리고, data port에 데이터를 쓴다.

  • Handle interrupts.

    전송된 각 섹터에 대한 interrupt를 각각 처리하거나 일괄로 처리한다.

  • Error handling.

    각 동작 이후에 status register를 읽는다. 만약 ERROR 비트가 켜져있으면 error register를 읽어 세부사항을 확인한다.


'Operating System' 카테고리의 다른 글

[OS] Files and Directories  (0) 2021.09.03
[OS] Hard Disk Drives  (0) 2021.09.03
[OS] DeadLock  (0) 2021.09.03
[OS] Semaphores  (0) 2021.09.03
[OS] Condition Variables  (0) 2021.09.03
Comments