콰이엇의 개발기록

[운영체제] 3. 컴퓨터 시스템의 동작 원리

by 콰이엇
반효경 교수님의 "운영체제와 정보기술의 원리" 책을 학습하고 정리한 글입니다.

 

1. 컴퓨터 시스템 구조

1. 컴퓨터 내부 : CPU + 메모리로 구성

  • CPU : 기계어 연산을 담당 (mode bit, Interrupt Line, Registers)
  • 메모리 : CPU 연산을 위한 작업 공간
  • 커널(Kernel) : 운영체제의 핵심 프로그램 (메모리에 상주)

2. 컴퓨터 외부 : I/O 장치 (디스크, 키보드, 마우스, 모니터, 네트워크 장치 등)

  • 입력(input) : 컴퓨터 내부로 데이터가 들어오는 것
  • 출력(output) : 컴퓨터 외부장치로 데이터가 나가는 것
  • 디바이스 컨트롤러 : 각 하드웨어 장치(메모리 및 입출력장치 등)에 붙은 일종의 작은 중앙처리장치(cpu)
  • 각 I/O 장치는 local buffer(로컬 버퍼)를 가지며, 이는 각 컨트롤러의 작업 공간

 

1-1. Device Controller

📌 I/O device controller

해당 I/O 장치 유형을 관리하는 일종의 작은 CPU

  • 제어 정보를 위해 control register, status register를 가짐
  • local buffer를 가짐 (일종의 data register)
  • I/O는 실제 device와 local buffer 사이에서 일어남
  • Device controller는 I/O가 끝났을 경우 interrupt로 CPU에 그 사실을 알림

📌 device driver (장치 구동기)

OS 코드 중 각 장치별 처리 루틴 (Software)

  • CPU가 해당 디바이스에 어떤 작업을 요청할 수 있는 방법 (코드)
  • device driver는 컴퓨터 내부에서 CPU가 실행하는 코드

📌 펌웨어 (Firmware)

해당 디바이스의 작업을 가능하게 해주는 코드

 

2. CPU 연산과 I/O 연산

2-1. 인터럽트 (Interrupt)

CPU의 Interrupt Line에 의해 CPU 제어권을 자동으로 운영체제에 넘어갈 수 있도록 만드는 방법

  • Interrupt (하드웨어 인터럽트) : 하드웨어가 발생시킨 인터럽트
  • Trap (소프트웨어 인터럽트)
    - Exception : 프로그램이 오류를 범한 경우 (0으로 나누는 연산 등)
    - System call : 프로그램이 커널 함수를 호출하는 경우

 

🧐 인터럽트 이해하기

더보기

ex. 프로그램 B는 현재 CPU를 할당받아 프로그램 코드를 실행하고 있다고 가정하자

 

프로그램 B가 수행 중에 디스크에서 데이터를 읽어오라는 명령을 내리면, 디스크 컨트롤러가 물리적인 디스크에서 내용을 읽어 이를 로컬 버퍼에 저장한다. 프로그램 B는 필요로 하는 데이터를 다 읽어왔으므로 CPU에서 다음 일을 수행할 수 있다. 이때 로컬 버퍼로 읽어오는 작업이 끝났는지를 CPU가 지속 체크하는 것이 아니라, 장치에 있는 컨트롤러가 인터럽트를 발생시켜 CPU에게 보고한다.

 

기본적으로 CPU는 매순간 메모리에서 명령(Instruction)을 하나씩 읽어와서 수행한다. 이때 CPU는 인터럽트 라인(Interrupt line)을 통해 명령 하나를 수행할 때마다 인터럽트 발생을 확인한다. 인터럽트 라인에 신호가 들어오면 다음 명령을 수행하기 전에 인터럽트 처리를 하게 된다. 즉, 인터럽트는 장치 입출력 작업 완료 등 CPU에 알려줄 이벤트가 생겼을 때 컨트롤러가 발생시키는 것이다.

 

이때 수행하는 일은 디스크 로컬 버퍼에 있는 데이터를 프로그램 B의 메모리로 전달하고, 해당 프로그램이 CPU를 할당받을 경우 다음 명령을 수행할 수 있음을 표시한다. 인터럽트 처리를 완료하고 나면 원래 수행하던 작업으로 돌아가 중단되었던 일을 계속해서 수행하게 된다.

 

 

📌 로컬 버퍼 (Local Buffer)

장치의 입출력 데이터를 임시로 저장하기 위한 작은 메모리

📌 컨트롤러 (Device Controller)

각 하드웨어 장치(메모리 및 입출력장치 등)에 붙은 일종의 작은 중앙처리장치(CPU)

📌 인터럽트 처리 루틴 (Interrupt Service Routine, 인터럽트 핸들링)

CPU에 인터럽트가 발생했을 때 처리해야 할 일들의 절차

📌 인터럽트 벡터 (Interrupt vector)

인터럽트 종류마다 번호를 정해 처리해야 할 코드가 위치한 부분을 가리키는 자료구조

 

현대의 운영체제는 인터럽트에 의해 구동된다

 

2-2. System Call

사용자 프로그램이 운영체제의 서비스를 받기 위해 커널 함수를 호출하는 것

사용자 프로그램은 모든 권한을 가지고 있지 않기 때문

 

🧐 시스템콜 이해하기

더보기

사용자 프로그램이 실행 중 디스크에게 다른 파일을 읽어와야 할 때, I/O 작업을 필요로 하게 된다. I/O 작업은 '특권 명령'으로 규정되어 있어 사용자 프로그램의 기계어로 실행할 수 없다.

 

따라서 이를 가능하게 하기 위해 'System Call'을 통해 운영체제에게 요청하게 된다. 운영체제는 CPU를 통해 디스크 컨트롤러에게 파일 읽기를 요청하게 되고, 위 "인터럽트 이해하기" 과정이 발생하게 된다.

 

 

2-3. 인터럽트 핸들링

인터럽트가 발생했을 때 처리해야 할 일의 절차

 

🧐 인터럽트 핸들링 이해하기

더보기

CPU에서 명령이 실행될 때 레지스터에 데이터를 읽거나 쓰면서 작업을 하는데, 이때 인터럽트가 발생해 새로운 명령을 실행하면 기존의 레지스터 값들이 지워지게 되므로 CPU 내의 이러한 상태를 저장해야 인터럽트 처리를 진행할 수 있다.

 

이때, 운영체제는 현재 시스템 내에서 실행되는 프로그램들을 관리하기 위해 PCB라는 자료구조를 둔다. 즉, 인터럽트가 발생하면 현재 프로그램의 실행 상태를 PCB에 저장한 후 CPU의 제어권이 인터럽트 처리루틴으로 넘어가게 되며, 인터럽트 처리가 끝나면 저장된 상태를 PCB로부터 CPU 상에 복원해 인터럽트 당하기 직전의 위치부터 실행을 이어하게 된다.

 

오늘날의 컴퓨터에서 운영체제는 인터럽트가 발생할 때만 실행된다. 시스템이 부팅 후 정상 상태에 머무르게 되면 CPU가 항상 사용자 프로그램에 의해 사용되며, 운영체제는 단지 인터럽트가 발생했을 때만 CPU 제어권을 획득할 수 있기 때문이다. 즉, 운영체제가 직접 CPU를 점유하는 경우는 인터럽트에 의하지 않고는 발생하지 않는다.

 

 

📌 Registers

CPU 내부의 임시 기억장치

📌 PCB (Process Control Block)

현재 시스템 내의 각 프로그램마다 어느 부분이 실행 중이었는지를 저장하는 자료구조

⇒ 프로그램이 실행 중이던 코드의 메모리 주소, 레지스터값, 하드웨어 상태 등이 저장

 

🧐 CPU 작업 권한이 프로그램으로부터 운영체제로 넘어가는 경우
공통적으로 Interrupt가 걸리는 경우

  1. 하드웨어 장치(디바이스 컨트롤러)들이 Interrupt를 설정하는 경우
    ⇒ 진정한 의미의 Interrupt
  2. 소프트웨어가 Interrupt를 설정하는 경우 (Trap)
    - System Call : 프로그램 본인의 코드로는 I/O 작업(특권명령)을 실행할 수 없으므로 System Call을 통해 Interrupt 설정
    - Exception : 잘못된 연산 또는 권한이 없는 기계어를 실행할 때 스스로 Interrupt 설정

 

3. 입출력 구조

3-1. 동기식 입출력 / 비동기식 입출력

📌 입출력 (I/O)

컴퓨터 시스템이 컴퓨터 외부의 입출력 장치들과 데이터를 주고받는 것

📌 동기식 입출력 (Sychronous I/O)

어떤 프로그램이 입출력 요청을 했을 때 작업이 완료된 후 후속 작업을 수행할 수 있는 방식

⇒ 입출력이 완료될 때까지 다음 명령을 수행할 수 없기 때문에 그동안 CPU가 낭비된다

📌 비동기식 입출력 (Asynchronous I/O)

CPU의 제어권을 입출력 연산을 호출한 그 프로그램에게 곧바로 다시 부여하는 방식

 

🧐 비동기식 입출력 처리 과정

더보기

CPU 제어권이 입출력을 요청한 프로세스에게 곧바로 다시 주어지며, 입출력 연산이 완료되는 것과 무관하게 처리 가능한 작업부터 처리한다. 입출력 연산이 완료되지 않았다면 CPU를 할당해도 명령을 수행하지 못하므로 이 프로그램의 상태를 봉쇄 상태(Blocked state)로 전환시킨다.

 

입출력 연산이 완료되면 동기식과 마찬가지로 인터럽트를 통해 이를 CPU에게 알려준다. 그러면 그 시점부터 읽어온 데이터를 필요로 하는 명령을 수행할 수 있도록 로컬 버퍼에 있는 프로그램의 데이터를 메모리 영역으로 읽어오고 해당 프로그램의 봉쇄 상태를 해제시켜 해당 프로그램이 다시 CPU를 할당할 수 있음을 표시한다. 이후 자신의 차례가 되면 CPU를 할당받아 입출력 연산 이후의 작업을 수행한다.

 

 

동기식/비동기식 입 출력 모두 I/O의 완료는 인터럽트로 알려준다.

 

4. DMA (Direct Memory Access)

CPU를 대신하여 데이터를 로컬 버퍼로부터 메모리로 읽어오는 작업을 수행하는 하드웨어

⇒ 너무 잦은 인터럽트를 방지하기 위한 장치

  • 빠른 입출력 장치를 메묄에 가까운 속도로 처리하기 위해 사용
  • 바이트(Byte) 단위가 아니라 블록(Block)이라는 큰 단위의 정보를 메모리로 읽어온 후 인터럽트를 발생

 

🧐 DMA 동작 과정

더보기

입출력 장치는 어떤 작업이 완료되었음을 인터럽트를 통해 알리고, CPU는 명령어를 실행하기 전 인터럽트 여부를 확인하여 데이터를 로컬 버퍼로부터 메모리로 가져오는 작업을 수행한다.

 

만약 CPU에 의해서만 메모리 접근 작업이 이루어진다면 요청이 잦아질 때 CPU 업무가 방해되어 사용 효율성이 떨어지는 문제가 발생한다. 이를 방지하기 위해, 입출력 장치의 로컬 버퍼로부터 메모리로 데이터를 읽어오는 작업을 DMA라는 장치를 통해 대신 수행하여 CPU가 메모리 접근 요청에 의해 인터럽트 당하는 것을 막아준다.

 

 

5. 저장장치

5-1. 저장장치의 구조

  1. 주기억장치 (메모리)
    전원이 나가면 저장되었던 내용이 모두 사라져버리는 휘발성(volatile)의 RAM을 매체로 사용
  2. 보조기억장치
    전원이 나가도 저장된 내용을 기억할 수 있는 비휘발성(nonvolatile)의 마그네틱 디스크를 주로 사용

✍🏻 보조기억장치의 용도

더보기
  1. 파일 시스템 (file system)
    전원이 나가도 유지해야 할 정보가 있을 때 파일 형태로 저장
  2. 스왑 영역 (swap area)
    메모리의 크기는 한정되고, 가격이 상대적으로 비싼데다가 용량이 적은 경우가 대부분이다. 운영체제는 프로그램 수행에 당장 필요한 부분만 메모리에 올려두고 그렇지 않은 부분은 디스크의 스왑 영역에 내려놓게 된다.(스왑 아웃, swap out) 스왑아웃된 부분이 필요할 때는 다시 메모리 영역으로 올리게 된다.

 

 

5-2. 저장장치 계층 구조

✍🏻 컴퓨터 시스템의 저장장치 계층 구조

  • 빠른 저장장치는 단위 공간당 가격이 높기 때문에 적은 용량을 사용
  • 느린 저장장치는 가격이 저렴해 대용량을 사용하는 반면 접근 속도가 느리다는 약점

⇒ 따라서, 가장 필요한 정보는 빠른 저장장치에 넣어두어 수행 속도를 높이고, 그렇지 않은 정보는 상대적으로 느린 저장장치에 보관

 

📌 캐싱 기법

상대적으로 용량이 적은 빠른 저장장치를 이용해 느린 저장장치의 성능을 향상시키는 총체적 기법

 상대적으로 느린 저장장치에 있는 내용 중 당장 사용되거나 빈번히 사용될 정보를 빠른 저장장치에 선별적으로 저장함으로써 두 저장장치 사이의 속도를 완충

 

6. 하드웨어의 보안

6-1. 커널 모드와 사용자 모드

✍🏻 하드웨어 보안 기법

흔히 사용하는 운영체제는 여러 프로그램을 동시에 실행할 수 있는 다중 프로그래밍 환경에서 동작한다. 따라서, 각 프로그램이 다른 프로그램의 실행을 방해하거나 프로그램 간 충돌을 일으키는 문제를 막아야 한다.

 

만약 어떤 프로그램이 이상한 명령을 수행시켜 다른 프로그램의 메모리 또는 파일 영역을 침범할 때 중요한 정보에 접근해 위험한 상황을 초래할 수 있는 연산커널모드에서만 실행하게 한다.

 

📌 커널 모드 (kernel mode, system mode)

운영체제가 CPU의 제어권을 가지고 운영체제 코드를 실행하는 모드

  • 모든 종류의 명령을 다 실행할 수 있다.
  • 시스템의 중요한 영향을 미치는 연산은 커널모드에서만 실행 가능하도록 함으로써 하드웨어 보안 유지

📌 사용자 모드 (user mode)

일반 사용자 프로그램이 실행되며 제한적인 명령만을 수행하는 모드

 

6-2. Mode bit

사용자 프로그램의 잘못된 수행으로 다른 프로그램/운영체제에 피해가 가지 않도록 하기 위한 보호 장치

 

✍🏻 Mode bit의 사용 목적

더보기

사용자 프로그램이 CPU를 가지고 있는 동안에는 운영체제가 자신의 코드를 실행하지 못하므로 사용자 프로그램을 감시할 방법이 없어, 사용자 프로그램이 그런 종류의 연산을 실행하는 것을 막을 수 있는 방법이 존재하지 않는다. 왜냐하면 운영체제 자신이 CPU 제어권을 가져오는 방법은 없기 때문이다.

 

이때, CPU 내부에 모드 비트(mode bit)를 두어 사용자 프로그램을 감시한다.

  • 0 : 커널 모드(= 시스템 모드, 모니터 모드) : 운영체제 코드 실행, 모든 명령을 수행
  • 1 : 사용자 모드 : 사용자 프로그램 실행, 제한된 명령만을 수행

운영체제가 CPU를 점유해 자신의 코드를 실행하다가 사용자 프로그램에게 CPU의 제어권을 넘길 때 모드 비트를 1로 설정하여 넘기면, 사용자 프로그램은 보안과 관련된 중요한 명령 수행에 제약을 받아 하드웨어를 보호할 수 있다. 따라서, 인터럽트가 발생할 때 모드 비트는 자동으로 0이 설정된다.

 

따라서, 모드 비트(mode bit)는 어떤 목적으로 CPU를 실행하는지 구분하기 위한 장치다.

 

📌 특권 명령

시스템의 보안과 관련된 명령, 모드 비트가 0일 때만 수행할 수 있다

 

🧐 하드웨어 장치에서 보안이 유지되는 방식

더보기

모든 입출력 명령특권명령으로 규정하여 사용자 프로그램이 직접 입출력을 하는 것을 차단한다.

 

사용자 프로그램이 디스크에 저장된 파일을 자유롭게 접근할 수 있다면 보안상 문제가 발생하게 된다. 왜냐하면 자신의 소유가 아닌 다른 프로그램의 파일에 접근할 수 있기 때문이다. 따라서, 사용자 프로그램이 입출력을 하고 싶다면 시스템 콜로 운영체제에 요청하는 방식을 사용해야 한다.

 

그러면, 운영체제가 CPU를 할당 받고 인터럽트 처리 루틴을 통해 운영체제가 입출력을 수행한다. 한편, 운영체제는 입출력 요청이 올바른 요청인지 확인한 후 입출력을 실행하기 때문에 파일에 대한 보안을 유지할 수 있다.

 

 

7. 메모리 보안

7-1. 기준 레지스터 & 한계 레지스터

두 개의 레지스터를 사용해서 프로그램이 접근하려는 메모리 부분이 합법적인지 체크하여 메모리를 보호한다.

 

📌 기준 레지스터 (base register)

어떤 프로그램이 수행되는 동안 합법적으로 접근할 수 있는 메모리 상의 가장 작은 주소를 보관한다.

📌 한계 레지스터 (limit register)

그 프로그램이 기준 레지스터 값부터 접근할 수 있는 메모리 범위를 보관한다.

 

🧐 메모리 보안 방식

더보기

여러 프로그램이 메모리에 동시에 올라가 실행되기 때문에 하나의 사용자 프로그램이 다른 사용자 프로그램이나 운영체제가 위치한 메모리 영역을 침범할 수 있다.

 

예를 들어, 하나의 사용자 프로그램이 메모리 주소 참조 연산을 잘못 사용해 다른 사용자 프로그램의 메모리 영역이나 운영체제 커널이 위치한 영역을 참조하려는 시도를 할 수 있다.

 

이때 '기준 레지스터 + 한계 레지스터' 값 사이의 주소 영역에만 접근할 수 있으며, 접근하려는 주소가 이 범위안에 없으면 불법적인 메모리 접근으로 예외 상황 인터럽트가 발생된다. 운영체제는 예외 상황을 발생시킨 프로그램을 강제로 종료하게 된다.

 

 

🧐 메모리 접근 연산과 입출력 연산의 차이점

더보기

메모리 접근 연산은 사용자 프로그램이 CPU를 가지고 있는 동안 수행할 수 있는 연산으로 특권명령이 아니다.

 

사용자 프로그램이 메모리에 접근하기 전에 하드웨어적으로 합법적인지 체크하여 메모리를 보호한다. 따라서 운영체제만이 수행할 수 있는 입출력 연산과 메모리 접근 연산은 차이가 있다고 할 수 있다.

 

메모리 접근 명령은 특권명령이 아니지만, 기준 레지스터와 한계 레지스터의 값을 세팅하는 연산은 특권명령으로 규정해야 한다. 만약 프로그램이 직접 자신의 레지스터 값을 변경한다면 메모리 무한 접근이 가능하기 때문이다.

 

 

8. CPU 보호

8-1. 타이머

정해진 시간이 지나면 인터럽트를 발생시켜 운영체제가 CPU 제어권을 획득할 수 있게 하는 역할

 

🧐 타이머 동작 방식

특정 프로그램이 부적절한 방법(무한 반복문 등)으로 CPU 사용 권한을 독점하고 있을 때 다른 프로그램 및 운영체제가 CPU를 빼앗을 방법이 없게 되므로 타이머로 운영체제가 CPU 제어권을 획득할 수 있도록 하는 역할을 수행한다.

⇒ 시분할 시스템에서 현재 시간을 계산하기 위해서도 사용한다.

 

📌 로드 타이머 (Load timer)

타이머 값을 세팅하는 명령

특권명령에 속한다.

 

참고자료

  • 책 - 운영체제와 정보기술의 원리 (반효경, 2020년 5월)

블로그의 정보

콰이엇의 개발기록

콰이엇

활동하기