6 분 소요

1. 컴퓨터 시스템의 구조

image

좌측 : 컴퓨터 내부 장치, 우측 : 컴퓨터 외부 장치

  • 컴퓨터는 외부장치에서 내부 장치로 데이터를 읽어와 각종 연산을 수행한 후, 그 결과를 외부장치로 다시 내보내는 방식으로 업무를 처리한다.
    • 컴퓨터 내부로 데이터가 들어오는 것을 입력(Input)이라 하고
    • 컴퓨터 외부 장치로 데이터가 나가는 것을 출력(output)이라 한다.
  • 메모리 및 입출력장치 등의 각 하드웨어 장치에는 컨트롤러라는 것이 붙어있다.
    • 컨트롤러 : 일종의 작은 CPU. 컴퓨터 전체에 CPU라는 중앙처리장치가 있듯이 컨트롤러는 각 하드웨어 장치마다 존재하면서 이들을 제어하는 작은 CPU라고 볼 수 있다.
  • 운영체제
    • 일종의 프로세스
    • 컴퓨터가 부팅되었을 때부터 항상 수행되면서 각종 자원들을 관리해야 하므로 항상 메모리에 올라가 있다.
    • 그러나 운영체제의 모든 코드를 다 메모리에 상주시키면 메모리의 낭비 발생
    • 따라서 운영체제 중 항상 메모리에 올라가 있는 부분은 전체 운영체제 중 핵심적인 부분에 한정되며, 이 부분을 커널(kernel)이라고 부른다.

2. CPU 연산과 I/O 연산

  • 컴퓨터에서 연산을 한다는 것 = CPU가 무언가 일을 한다는 것
    • 입출력 장치들의 I/O 연산 ⇒ 입출력 컨트롤러가 담당
    • 컴퓨터 내에서 수행되는 연산 ⇒ 메인 CPU가 담당
  • 로컬 버퍼
    • 장치 컨트롤러는 장치로부터 들어오고 나가는 데이터를 임시로 저장하기 위한 작은 메모리를 갖는데 이것을 로컬 버퍼라 한다.
    • 예 : 1) 프로그램 B가 수행 중에 디스크에서 데이터를 읽어오라는 명령을 내리면, 디스크 컨트롤러가 물리적인 디스크에서 내용을 읽어 이를 로컬버퍼에 저장한다.

      2) 원하는 데이터를 로컬버퍼로 다 읽어오고 나면 B는 자신이 필요로 하는 데이터를 다 읽어왔으므로 메인 CPU에서 다음 일을 수행할 수 있다.

      3) 이때 로컬버퍼로 읽어오는 작업이 끝났는지를 메인 CPU가 지속적으로 체크하는 것이 아니라, 장치에 있는 컨트롤러가 인터럽트를 발생시켜 CPU에 보고하게 된다.

  • 인터럽트 라인 (inturrupt line)
    • 기본적으로 CPU는 매 시점 메모리에서 명령(instuction)을 하나씩 읽어와서 수행한다.
    • 이때 cpu 옆에는 인터럽트 라인이 있어서, CPU가 자신의 작업을 하던 중간에 인터럽트 라인에 신호가 들어오면, 하던 일을 멈추고 인터럽트와 관련된 일을 먼저 처리한다.
    • 좀 더 정확히 말하면, CPU는 명령 하나를 수행할 떄마다 인터럽트가 발생했는지 확인한다.

3. 인터럽트의 일반적 기능

  • 인터럽트 처리 루틴
    • 운영체제 커널에는 인터럽트가 들어왔을 때 해야 할 일이 미리 다 프로그래밍 되어 그 코드가 보관돼 있다. 이것을 인터럽트 처리 루틴이라 한다.
    • 인터럽트 처리 루틴은 다양한 인터럽트에 대해 각각 처리해야 할 업무들을 정의하고 있다.
    • 앞의 예와 같이, 디스크 컨트롤러가 인터럽트를 발생시키면, CPU는 하던 일을 잠시 멈추고 이 인터럽트가 발생했을 때 수행하도록 정의된 코드를 찾아 수행한다.

    이때 수행하는 일은 디스크의 로컬버퍼에 있는 내용을 사용자 프로그램의 메모리로 전달하고, 해당 프로그램이 CPU를 할당받을 경우 다음 명령을 수행할 수 있음을 표시해두는 일이다.

  • 인터럽트
    • 인터럽트에는 하드웨어 인터럽트와 소프트웨어 인터럽트가 존재함.
    • 둘 다 CPU의 서비스가 필요한 경우, CPU 옆에 있는 인터럽트 라인에 신호를 보내서 인터럽트가 발생했음을 알려주는 방식은 동일하다.
      • 하드웨어 인터럽트 : 컨트롤러 등 하드웨어 장치가 CPU의 인터럽트 라인을 세팅
      • 소프트웨어 인터럽트 : 소프트웨어가 그 일을 수행한다.
    • 일단 인터럽트가 발생하면, CPU는 하던 일을 멈추고 운영체제 커널 내에서 해당 인터럽트의 처리를 위해 정의된 코드를 찾게 된다.
    • 운영체제는 할 일을 쉽게 찾아가기 위해 인터럽트 벡터 (interrupt vector)를 가지고 있다.
      • 인터럽트 벡터 : 인터럽트 종류마다 번호를 정해서, 번호에 따라 처리해야할 코드가 위치한 부분을 가리키고 있는 자료구조
      • 인터럽트 처리 루틴 or 인터럽트 핸들러 : 실제 처리해야할 코드
    • CPU는 인터럽트 처리루틴을 통해 해당하는 인터럽트 처리를 완료하고 나면 원래 수행하던 작업으로 돌아가 중단되었던 일을 계속해서 수행.
      • 이때, 인터럽트 처리 후 돌아갈 위치를 알아야 하므로 인터럽트 처리 전에 수행 중이던 작업이 무엇이엇는지 반드시 저장해두어야 한다.
  • 소프트웨어 인터럽트(=trap)
    • 소프트웨어 인터럽트의 예로는 예외상황(exception)과 시스템 콜(system call)이 있다.
    • 예외 상황 (Exception)
      • 사용자 프로그램이 0으로 나누는 연산 등 비정상적인 작업을 시도하거나, 자신의 메모리 영역 바깥에 접근하려는 시도 등 권한이 없는 작업을 시도할 때, 이에 대한 처리를 위해 발생시키는 인터럽트를 말한다.
    • 시스템 콜 (System call)
      • 사용자 프로그램이 운영체제 내부에 정의된 코드를 실행하고 싶을 때 운영체제에 서비스를 요청하는 방법
      • 사용자 프로그램에 정의되지 않고 운영체제 커널에 있는 코드를 사용자 프로그램이 실행하고자 할 때에는 인터럽트 라인 세팅을 통해 CPU 제어권을 운영체제로 넘겨 실행하는 것
      • 예 : 애플리케이션 개발자가 프로그램 작성 중 키보드 입력이나 화면 출력 등의 입출력 작업이 필요할 경우 본인이 직접 입출력을 수행하는 코드를 작성하는 것이 아니라 이미 존재하는 커널의 코드를 호출해서 처리한다.

      image

4. 인터럽트 핸들링

  • 인터럽트 핸들링 : 인터럽트가 발생한 경우에 처리해야 할 일의 절차를 의미한다.
  • 프로그램 A가 실행되고 있을 때 인터럽트가 발생하면 A의 현재 상태를 먼저 저장한다.
    • 현재 상태란, 현재 CPU에서 실행 중인 명령의 메모리 주소를 포함해 몇 가지 부가적인 정보들을 의미한다.
    • CPU에서 명령이 실행될 때에는 CPU 내부에 있는 임시 기억장치인 레지스터(register)에 데이터를 읽거나 쓰면서 작업을 하는데, 이때 인터럽트가 발생해 새로운 명령을 실행하면 기존의 레지스터 값들이 지워지게 되므로 cpu 내의 이러한 상태를 저장해두어야 한다. 이것을 모두 저장한 후에야 인터럽트 처리가 이루어질 수 있는 것이다.
  • 프로세스 제어 블록 (PCB)
    • 운영체제는 현재 시스템 내에서 실행되는 프로그램들을 관리하기 위해 프로세스 제어블록 (Process Control Block)이라는 자료구조를 둔다.
    • PCB는 각각의 프로그램마다 하나씩 존재하며 해당 프로그램의 어느 부분이 실행 중이었는지를 저장하고 있다. (구체적으로는 프로그램이 실행 중이던 코드의 메모리 주소와 레지스터 값, 하드웨어 상태 등이 저장된다.)
    • 예 : 어떤 프로그램이 실행되던 중에 인터럽트가 발생 → 그 프로그램의 실행 상태를 PCB에 저장한 후 CPU의 제어권이 인터럽트 처리루틴으로 넘어감 → 인터럽트 처리가 끝나면 저장된 상태를 PCB로부터 CPU 상에 복원해 인터럽트 당하기 직전의 위치부터 실행이 이어지게 됨

image

운영체제의 주소 공간 구조 (=커널의 데이터 영역)

5. DMA

image

  • 원칙적으로 메모리는 CPU에 의해서만 접근할 수 있는 장치
  • 따라서 CPU 외의 장치가 메모리의 데이터에 접근하기 위해서는 CPU에게 인터럽트를 발생시켜 CPU가 이를 대행하는 식으로만 가능
    • 컨트롤러가 CPU에게 인터럽트를 발생시킴 → CPU는 컨트롤러의 로컬버퍼와 메모리 사이에서 데이터를 옮기는 일을 수행
  • 그러나 모든 메모리 접근 연산이 CPU에 의해서만 이루어지게되면, 입출력 장치가 메모리 접근을 원할 때마다 인터럽트에 의해 CPU의 업무가 방해를 받게 되어 CPU 사용의 효율성이 떨어지는 문제점이 발생
  • 이를 극복하기 위해 CPU 이외에 메모리 접근이 가능한 장치를 하나 더 둠 ⇒ DMA

  • DMA
    • 일종의 컨트롤러
    • 로컬버퍼에서 메모리로 읽어오는 작업을 CPU 대신 DMA가 수행
    • 이때 DMA는 byte 단위가 아니라 block 이라는 큰 단위로 정보를 메모리로 읽어온 후에 CPU에게 인터럽트를 발생시켜서 해당 작업의 완료를 알림
    • 따라서 CPU에 발생하는 인터럽트의 빈도를 줄임

6. 하드웨어의 보안

  • 우리가 흔히 사용하는 운영체제는 여러 프로그램이 동시에 실행될 수 있는 다중 프로그래밍(multi-programming) 환경에서 동작함
  • 따라서 각 프로그램이 다른 프로그램의 실행을 방해하거나 프로그램 간에 충돌을 일으키는 문제를 막기 위해 하드웨어에 대한 각종 보안 기법이 필요
  • 하드웨어적 보안을 위해 운영체제는 기본적으로 커널모드사용자 모드의 두 가지 모드를 지원한다.
    • if ) 어떤 프로그램이 이상한 명령을 수행시켜 다른 프로그램의 메모리 영역이나 파일 영역을 침범하는 경우가 발생
    • 따라서 중요한 정보에 접근해 위험한 상황을 초래할 수 있는 연산 (=시스템에 중요한 영향을 미치는 연산)은 커널모드에서만 실행되도록 함. (일반 사용자 프로그램이 직접 위험한 명령을 수행할 수 없도록)
  • 커널 모드
    • 운영체제가 CPU의 제어권을 가지고 운영체제 코드를 싱행하는 모드.
    • 이 모드에서는 모든 종류의 명령을 다 실행할 수 있다.
  • 사용자 모드
    • 일반 사용자 프로그램이 실행되며 제한적인 명령만을 수행
  • 하지만 사용자 프로그램이 CPU를 가지고 있는 동안에는 운영체제가 자신의 코드를 실행하지 못하므로 사용자 프로그램을 감시할 방법이 없음 → 따라서 (시스템에 중요한 영향을 미치는) 연산을 사용자 프로그램이 수행해버려도 운영체제는 알 방도가 없음

    ⇒ 이를 방지하기 위해서는 하드웨어적인 지원이 필요 ⇒ 모드비트(mode bit) 도입

  • 모드 비트 (mode bit)
    • CPU 내부에 모드 비트를 두어 사용자 프로그램을 감시
      • 모드비트가 1 : 사용자 모드. 제한 된 명령만을 수행
      • 모드 비트가 0 : 커널 모드 : 모든 명령 수행 가능
    • CPU는 보안과 관련된 명령을 수행하기 전에는 항상 모드비트를 조사해 그 값이 0으로 세팅된 경우에만 그 명령을 수행한다.
    • 사용자 프로그램이 수행되다가 보안이 필요한 중요한 명령을 수행해야 할 경우 → 시스템 콜을 통해 운영체제가 대신해줄 것을 요청 → 인터럽트가 발생할 때 모드 비트는 자동으로 0이 세팅됨.
    • 운영체제가 CPU를 점유해 자신의 코드를 수행하다가 사용자 프로그램에게 CPU의 제어권을 넘김 → 모드비트를 1로 세팅해서 넘긴다.

image

7. CPU 보호

  • 특정 프로그램이 CPU를 독점해 무한반복문을 수행하는 것을 방지하기 위해 타이머 존재
  • 타이머
    • CPU가 하나의 프로그램에 의해 독점되는 것을 막기 위한 하드웨어 장치
    • 정해신 시간이 지나면 인터럽트를 발생시켜 운영체제가 CPU의 제어권을 획득할 수 있도록 함
    • 타이머에 의해 발생되는 인터럽트 처리 루틴 : 지금 CPU를 점유하고 명령을 실행 중인 프로그램으로부터 CPU를 빼앗아 다른 프로그램에게 CPU를 이양하는 것

참고

운영체제와 정보기술의 원리 - 이화여자대학교출판문화원 출판, 반효경 저