본문 바로가기
JSCODE CS/운영체제 스터디

[JSCODE 운영체제 1주차] 2. 컴퓨터 구조 기본 개념

by dev_writer 2024. 11. 1.

안녕하세요. dev_writer입니다.

 

바로 이어서 운영체제 학습에 있어 도움이 되는 컴퓨터 구조의 기본 개념에 대해 정리해 보겠습니다.

 

컴퓨터 구조

컴퓨터의 구조는 크게 CPU / 메모리 / 보조기억장치 / 입출력장치로 나눌 수 있습니다.

 

이미지 출처: 혼자 공부하는 컴퓨터구조+운영체제

 

1️⃣ CPU (Central Processing Unit)

  • 중앙처리장치입니다.
  • 메모리에 저장된 명령어를 읽어 들이고, 읽어 들인 명령어를 해석하고 실행합니다.

ALU (Arithmetic Logic Unit)

  • 산술논리연산장치로, 계산만을 위해 존재하는 부품입니다.
  • 컴퓨터 내부에서 수행되는 대부분의 계산을 처리합니다.

레지스터

  • CPU 내부에 있는 작은 임시 저장 장치입니다.
  • 프로그램을 실행하는 데 필요한 값들을 임시로 저장합니다.
  • CPU 안에는 여러 개의 레지스터가 존재하며, 각기 다른 이름과 역할을 가지고 있습니다.
    • 프로그램 카운터: 메모리에서 가져올 명령어의 주소를 저장합니다.
    • 명령어 레지스터: 메모리에서 읽어 들인 명령어의 주소를 저장합니다.
    • 플래그 레지스터: ALU 연산 결과, CPU 상태에 대한 부가적인 정보를 저장합니다.
    • 이 외에도 다양한 레지스터들이 있습니다.

CU (Control Unit)

  • 제어 장치입니다.
  • 제어 신호 (control signal)를 내보내고, 명령어를 해석합니다.
    • 제어 신호는 컴퓨터 부품들을 관리하고 작동시키기 위한 일종의 전기 신호입니다. (메모리 읽기, 쓰기 등)

 

2️⃣ 메모리

  • 주기억장치라고도 합니다. RAM과 ROM으로 구분되나, 보통 RAM을 지칭합니다.
  • 현재 실행되는 프로그램 (= 프로세스)의 명령어와 데이터를 저장하는 부품입니다.
  • 프로그램이 실행되려면 반드시 해당 프로그램의 데이터와 명령어가 메모리에 저장되어 있어야 합니다.
    • 다만, 운영체제의 페이징 (Paging)을 다루면 실행되는 프로그램의 데이터와 명령어를 절약할 수 있습니다.
  • 저장된 명령어와 데이터의 위치가 정돈되어 있어야 빠르게 접근할 수 있기 때문에, 주소라는 개념이 사용됩니다.

 

3️⃣ 보조기억장치

메모리는 가격이 비싸 저장 용량이 적습니다. 또한, 전원이 꺼지면 저장된 내용을 잃는다는 단점이 있습니다. (휘발성)

 

보조기억장치는 이런 문제를 해결해 주는 저장 장치입니다. 하드디스크가 대표적인 보조기억장치의 예입니다.

 

메모리실행할 정보를, 보조기억장치보관할 정보를 저장합니다.

 

4️⃣ 입출력장치

입출력장치는 컴퓨터 외부에 연결되어 컴퓨터 내부와 정보를 교환하는 장치입니다.

 

사실 하드디스크, SSD 등도 컴퓨터 외부에 연결되긴 하지만, 이들은 입출력 기능에 비해 메모리를 보조하는 것이 더 주된 기능이다 보니 보조기억장치로 분류되곤 합니다.

 

🚌 시스템 버스와 메인 보드

위의 컴퓨터 부품들이 연결될 수 있는 판메인 보드라 하며, 이 컴퓨터 부품들은 버스 (bus)를 이용해 서로 정보를 주고받을 수 있습니다.

 

그리고 버스 중 가장 중요한, 즉 컴퓨터의 네 가지 핵심 부품을 연결하는 가장 중요한 버스시스템 버스라 합니다.

 

CPU는 어떻게 명령어를 처리하는가?

가장 중요한 것은, CPU가 도대체 어떤 흐름으로 명령어를 처리하는지입니다.

 

CPU가 명령어를 처리하는 정형화된 흐름명령어 사이클이라 합니다.

 

♻️ CPU의 명령어 사이클

  1. 우선 CPU는 메모리로부터 명령어를 가져옵니다. 메모리에는 현재 실행되는 프로그램의 명령어와 데이터가 보관되어 있기 때문입니다. (이 단계를 인출 사이클이라 합니다.)
  2. 가져온 명령어를 실행합니다. (이 단계를 실행 사이클이라 합니다.)

이렇게 단순히 인출 사이클과 실행 사이클을 반복하여 명령어 사이클이 이뤄진 경우도 있지만, 메모리 접근이 추가로 필요한 상황이 발생하기도 하며 (명령어의 주소 지정 방식 등에 따라 달라짐), 인터럽트가 발생하는 경우도 있습니다.

 

💥 인터럽트란?

인터럽트란 CPU의 작업을 방해하는 신호 (interrupt: 가로막기)입니다. 인터럽트가 발생하면, CPU는 자신이 하던 일을 잠시 중단하고 다른 일을 수행하게 됩니다.

 

동기 인터럽트 (예외)

동기 인터럽트는 CPU에 의해 발생하는 인터럽트입니다. 인터럽트가 CPU의 작업을 방해하는 신호인데 발생 주체가 CPU라니 조금 어색하지만, CPU가 명령어를 수행하는 도중 예상치 못한 상황에 마주하거나, 프로그래밍 오류와 같은 예외적인 상황에 마주쳤을 때에는 이렇게 인터럽트가 발생할 수 있습니다.

 

이러한 동기 인터럽트를 예외라고도 합니다.

 

동기 인터럽트의 종류는 아래와 같습니다.

  • 폴트: 예외를 처리한 직후 예외가 발생한 명령어부터 실행을 재개합니다.
  • 트랩: 예외를 처리한 직후 예외가 발생한 명령어의 다음 명령어부터 실행을 재개합니다. 주로 디버깅할 때 사용됩니다.
  • 중단: CPU가 실행 중인 프로그램을 강제로 중단시킬 수밖에 없는 심각한 오류를 발견했을 때 발생합니다.
  • 소프트웨어 인터럽트: 이전 글에서 정리한 시스템 콜이 발생했을 때 나타납니다.

 

비동기 인터럽트 (하드웨어 인터럽트)

비동기 인터럽트는 주로 입출력장치에 의해 발생하는 인터럽트입니다.

 

예시로 CPU가 프린터와 같은 입출력장치에 입출력 작업을 부탁하면, 작업을 끝낸 입출력장치가 CPU에게 완료되었다는 알림을 보냅니다.

 

만약 CPU가 프린터의 작업이 끝날 때까지 계속 완료되었는지를 물어본다면 CPU를 효율적으로 쓸 수 없겠죠?

 

이렇게 입출력장치가 알림을 보내기 전까지 CPU가 다른 일을 수행할 수 있다 보니, 동기 인터럽트와 다르게 비동기 인터럽트라 칭하는 것입니다.

 

하드웨어 인터럽트와 다르게, 입출력 장치의 상태는 어떤지, 처리할 데이터가 있는지 주기적으로 확인하는 방식을 폴링 (polling) 방식이라 합니다. 주기적으로 확인하는 만큼, 하드웨어 인터럽트보다 CPU의 부담이 더 크다고 할 수 있습니다.

 

인터럽트 처리 순서

인터럽트가 발생했다면 CPU는 아래 순서를 따라 작업을 실행합니다.

  1. CPU는 실행 사이클이 끝나고 명령어를 인출하기 전 인터럽트 여부를 확인합니다.
  2. CPU는 인터럽트 요청을 확인하고 인터럽트 플래그를 통해 현재 인터럽트를 받아들일 수 있는지 여부를 확인합니다.
    • CPU가 인터럽트 요청을 수용하기 위해서는 플래그 레지스터의 인터럽트 플래그가 활성화되어 있어야 합니다.
    • 특히 하드웨어 인터럽트의 경우에는 막을 수 있는 인터럽트 (maskable interrupt)와 막을 수 없는 인터럽트 (non maskable interrupt)가 있습니다.
  3. 인터럽트를 받아들일 수 있다면 CPU는 지금까지의 작업을 백업합니다.
  4. CPU는 인터럽트 벡터를 참조하여 인터럽트 서비스 루틴을 실행합니다.
    • 인터럽트 서비스 루틴은 인터럽트를 처리하기 위한 프로그램입니다.
    • 인터럽트 벡터는 서로 다른 여러 개의 인터럽트 서비스 루틴을 식별하기 위한 정보입니다.
  5. 인터럽트 서비스 루틴 실행이 끝나면 4에서 백업해 둔 작업을 복구하여 실행을 재개합니다.

 

컴퓨터는 어떻게 외부 정보를 인식하는가?

이번에는 컴퓨터가 외부 정보를 인식하는 것에 대해 알아보겠습니다.

 

지금 이렇게 제가 키보드로 글을 쓰는 것도, 결국 컴퓨터가 외부 정보를 인식했기 때문에 가능한 일입니다.

 

그렇기에 외부 정보를 인식하지 못한다면, 컴퓨터를 사용하는 이유가 없을 것입니다.

 

🕹️ 장치 컨트롤러와 장치 드라이버

먼저, 외부 정보를 인식하도록 하는 장치인 입출력장치는 컴퓨터에 직접 연결되지 않습니다.

 

이는 입출력장치의 종류가 매우 많아 규격화하기 어렵기 때문이며, 입출력장치의 데이터 전송률은 CPU와 메모리의 전송률보다 낮기 때문입니다.

 

그렇기에 입출력장치는 컴퓨터에 직접 연결되지 않고, 장치 컨트롤러를 통해 연결됩니다.

 

중간에 장비가 추가되는 것인데 어떻게 더 빠르게 되는 것일까?

공부를 하며 이 점이 문득 궁금했습니다. 뭔가 장비가 별도로 더 추가되면 느려질 것 같은데, 왜 장치 컨트롤러를 추가한 것일까요?

 

그것은 아래 두 가지 이유 때문입니다.

  • 정보 규격화의 문제: 장치 컨트롤러는 일종의 번역가 역할을 할 수 있어, 입출력장치가 가졌던 규격화의 어려움을 해결할 수 있습니다. 이 과정에서 오류를 검출하기도 합니다.
  • 데이터 버퍼링: 전송률이 높은 장치와 낮은 장치 사이에 주고받는 데이터를 버퍼에 저장하여 전송률을 비슷하게 맞춥니다.

 

장치 컨트롤러의 구조: 레지스터

장치 컨트롤러의 대략적인 구조는 데이터 레지스터, 상태 레지스터, 제어 레지스터가 있습니다.

  • 데이터 레지스터: CPU와 입출력장치 사이에 주고받을 데이터가 담기는 레지스터 (버퍼)입니다.
  • 상태 레지스터: 입출력장치가 입출력 작업을 할 준비가 되었는지, 입출력 작업이 완료되었는지 등의 상태를 저장합니다.
  • 제어 레지스터: 입출력장치가 수행할 내용에 대한 제어 정보와 명령을 저장합니다.

 

장치 드라이버

장치 컨트롤러가 입출력장치를 연결하기 위한 하드웨어적인 통로라면, 장치 드라이버는 입출력장치를 연결하기 위한 소프트웨어적 통로입니다.

 

장치 컨트롤러의 동작을 감지하고 제어함으로써 장치 컨트롤러가 컴퓨터 내부와 정보를 주고받을 수 있도록 할 수 있는 프로그램입니다. (그렇기에 메모리에 저장됩니다.)

 

다양한 입출력 방법

마지막으로, 입출력 방법들이 어떤 것이 있는지 살펴보겠습니다.

 

프로그램 입출력

  • 프로그램 속 명령어로 입출력장치를 제어하는 방법입니다.
  • CPU가 프로그램 속 명령어를 실행하는 과정에서 입출력 명령어를 만나면 CPU는 입출력 장치에 연결된 장치 컨트롤러와 상호작용하며 입출력 작업을 수행합니다.
  • CPU가 장치 컨트롤러의 레지스터 값을 읽고 씀으로써 이루어집니다. 이때 장치 컨트롤러의 레지스터 위치는 메모리 맵 입출력, 고립형 입출력 방식으로 저장될 수 있습니다.

 

인터럽트 기반 입출력

  • 인터럽트 기반의 입출력입니다.
  • 장치 컨트롤러가 입출력 작업을 끝낸 뒤 CPU에게 인터럽트 요청 신호를 보내면, CPU는 하던 일을 잠시 백업하고 인터럽트 서비스 루틴을 실행합니다.
  • 여러 개의 입출력장치에서 동시다발적으로 인터럽트가 발생하는 경우, PIC (Programmable Interrupt Controller)를 이용하여 우선순위를 판단한 뒤 가장 먼저 처리해야 할 인터럽트를 찾고 처리합니다.

 

DMA 입출력

  • 프로그램 입출력과 인터럽트 기반 입출력은 모두 CPU와 직접 상호작용합니다. 이는 하드 디스크 백업 등 CPU 부담이 매우 크다면 비효율적입니다.
  • DMA 입출력 방식은 CPU를 직접 거치지 않고 DMA (Direct Memory Access)를 이용하여 입출력장치와 메모리가 CPU를 거치지 않고도 상호작용 할 수 있도록 하는 방식입니다.
  • DMA 입출력 방식은 시스템 버스에 연결된 DMA 컨트롤러가 필요합니다.
  • CPU는 이제 입출력의 시작과 끝에만 관여합니다.
  • 그러나 시스템 버스는 CPU와 DMA 컨트롤러가 동시에 사용할 수 없기 때문에, DMA 컨트롤러는 CPU가 시스템 버스를 이용하지 않을 때마다 조금씩 시스템 버스를 이용하거나 CPU가 일시적으로 시스템 버스를 이용하지 않도록 허락을 구하고 시스템 버스를 이용합니다. (이를 사이클 스틸링이라고도 합니다.)

 

지금까지 운영체제 공부에 필요한 컴퓨터 구조 개념을 정리해 봤습니다.

 

다음 글에서는 실제로 JSCODE에서 스터디를 하고 나서 추가로 학습한 점에 대해 기록해 보겠습니다.

 

Reference