프로그램의 구조와 인터럽트

  • A라는 프로그램이 CPU를 할당받고 명령을 수행하고 있는데 인터럽트가 발생하면 A는 현재 수행중인 명령의 위치를 저장해 놓는다. 그 후 운영 체제 내부 코드인 인터럽트 처리 루틴으로 넘어가서 인터럽트 처리를 하고 다시 돌아와 A의 이전 작업 지점부터 수행을 계속 이어가게 된다.

  • 이때 이전 작업 지점을 저장할 별도의 공간이 필요한데, 이를 PCB(Process Control Block)이라고 부른다.

  • 인터럽트가 발생했을 때, 그 프로그램으 어느 부분까지 수행했는지를 저장하기 위한 영역

컴퓨터 시스템의 작동 개요

PC (Program Counter)

  • CPU는 현재 수행해야 할 메모리 주소의 명령을 있는 그대로 처리한다.

  • CPU가 수행해야 할 메모리 주소를 담고 있는 레지스터를 프로그램 카운터라고 한다. (CPU는 매번 프로그램 카운터가 가리키는 메모리 영역의 명령을 처리한다.)

  • 일반적으로, 조건문이나 반복문, 함수 호출 등에 의한 주소 이동이 없는 이상 프로그램 카운터는 항상 바로 다음 주소의 명령을 가리키게 되어 코드의 순차적인 수행이 이루어진다.

  • Instruction Controller는 메모리에서 인스트럭션을 읽어온다.

  • 메모리에서 읽은 인스트럭션은 instruction register에 임시저장

  • CPU가 명령을 처리하면 Program Counter가 증가하면서 다음 인스트럭션을 읽어온다.

image.png

프로그램의 실행

  • 프로그램이 실행되고 있다는 것은 컴퓨터 시스템 차원에서 볼 때 디스크에 존재하던 실행 파일이 메모리에 적재됨을 의미하고, 프로그래밍 cpu를 할당받고 기계 명령(instruction)을 수행하고 있는 상태를 의미한다.

  • 실행 파일이 메모리에 적재될 때에 실행 파일 전체가 메모리에 한꺼번에 올라가기보다는 일부분만 메모리에 올라가고 나머지는 디스크의 특정 영역에 내려가 있다.

    • 당장 실행에 필요한 부분은 메모리에 올려놓고, 그렇지 않은 부분은 디스크 중 메모리 연장 공간으로 사용되는 스왑 영역에 내려 놓는 방식으로 운영
  • 현재 수행중인 프로그램을 프로세스(process)라고 부르고, 커널의 데이터 영역 중에는 각 프로세스의 상태,CPU 사용 정보,메모리 사용 정보 등을 유지하기 위한 자료구조인 PCB를 두고 있다.

  • 프로그램이 실행되어 자기 자신의 코드 내에서 함수 호출 및 복귀주소를 유지하기 위해서는 자기 주소 공간 내의 스택을 사용하고, 시스템 콜 등 커널 내의 함수를 호출하는 경우에는 커널의 주소공간에 존재하는 커널 스택을 사용

프로그램이 사용하는 함수

  • 프로그래머가 직접 작성하는 함수는 사용자 정의 함수라고 한다.
  • 라이브러리 함수는 프로그래머가 직접 장성하지는 않았지만 이미 누군가가 작성해 놓은 함수를 호출만 하여 사용
  • 사용자 정의 함수, 라이브러리 함수는 해당 프로세스의 주소 공간에 포함된다.
  • 커널 함수는 운영체제 커널의 코드에 저장된 함수를 의미하고, 시스템 콜 함수와 하드웨어 및 소프트웨어가 cpu의 서비스를 요청하기 위해 발생시키는 인터럽트 처리 함수가 있다.
  • 커널 함수는 운영 체제 커널의 주소 공간에 코드가 정의된다.
  • 삼각함수 sin()은 라이브러리 함수이고, 문자열을 출력하는 printf()는 그 자체로는 라이브러리 함수이지만 궁극적으로 특권 명령인 입출력을 수행하므로 printf()내에서 커널 함수 호출인 시스템 콜을 동반한다.

인터럽트

image.png

  • 인터럽트는 하드웨어 인터럽트와 소프트웨어 인터럽트로 나눌 수 있다.
  • 하드웨어 컨트롤러가 cpu의 서비스를 요청하기 위해 발생시키는 인터럽트가 일반적인 의미의 인터럽트(하드웨어 인터럽트)

좁은의미의 인터럽트

  • cpu는 특별한 일이 없으면 현재 수행중인 프로세스의 다음 명령을 순차적으로 수행한다.
  • 일반적으로 인터럽트는 cpu가 아닌 다른 하드웨어 장치가 cpu에게 어떤 사실을 알려 주거나 cpu의 서비스를 요청해야할 경우 cpu내에 있는 인터럽트 라인을 세팅해 발생시킨다.
  • cpu는 매번 프로그램 카운터가 가리키고 있는 지점의 명령을 하나씩 수행하고나서 다음 명령을 수행하기 직전에 인터럽트 라인이 세팅되어 있는지 확인 한다.
  • 인터럽트 라인이 세팅되어 있으면, 현재 수행하던 프로세스를 멈추고 운영체제의 인터럽트 처리 루틴으로 이동해서 인터럽트 처리를 수행한다.

넓은의미의 인터럽트

  • 하드웨어 인터럽트와 트랩(trap)을 모두 포함하는 개념이다.
  • 트랩이란 소프트웨어가 발생시키는 인터럽트를 말한다.
  • 트랩의 종류에는 예외 상황(exception)과 system call이 있다.
  • 예외상황은 허용되지 않은 연산을 수행하려고 할 때 자동적으로 발생하는 것으로 운영체제는 예외 상황이 발생했을 때 CPU의 제어권을 획득해 해당 상황에 대한 조치를 취한다.
    • 예외상황은 0으로 나누는 연산, 자신의 주소 공간을 넘어서는 메모리 참조등이 있다.
    • 운영체제는 예외상황 처리 루틴을 자신의 코드 영역에 가지고 있다.
  • 시스템 콜은 사용자 프로세스가 운영 체제의 서비스를 요청하기 위해 커널의 함수를 호출하는 것이다.
  • 시스템 콜, 예외 상황 모두 사용자 프로세스로부터 cpu의 제어권이 운영체제에 이양되어 처리되는데 이 과정에 인터럽트 라인을 세팅하여 인터럽트를 발생시킨 후 제어권이 넘어가므로 인터럽트라고 부를 수 있다.

인터럽트 벡터

  • 여러 가지 인터럽트에 대해 해당 인터럽트 발생시 처리해야 할 루틴의 주소를 보관하고 있는 테이블을 의미한다.
  • 함수를 가리키는 포인터라고도 할 수 있다.

인터럽트 핸들러(인터럽트 서비스 루틴)

  • 실제 인터럽트를 처리하기 위한 루틴으로 인터럽트 서비스 루틴이라고도 부른다.
  • 운영 체제 코드 부분에는 각종 인터럽트별로 처리해야할 내용이 이미 프로그램되어 있으며, 이 부분을 인터럽트 서비스 루틴 또는 인터럽트 핸들러라고 한다.
  • 일반적으로, 인터럽트 발생전의 프로세스에게 cpu제어권이 넘어가지만, 타이머 인터럽트는 해당 프로세스가 독점하고 있어서 발생한 인터럽트 이므로 다른 프로세스에게 cpu제어권을 넘겨준다.

시스템 콜

image.png

  • cpu는 매 시점 명령을 수행하기 전에 현재 모드 비트를 체크해 커널 모드인 경우에만 특권 명령을 수행할 수 있도록 제한하고 있다.
  • 운영체제가 사용자 프로그램에게 cpu의 제어권을 넘길 때에는 모드 비트를 0에서 1로 바꾸어 사용자 프로그램이 특권 명령을 수행하는 것을 방지한다.
  • 한편, 사용자 프로그램이 입출력과 같은 특권명령이 필요하면 운영체제에게 system call을 통해 특권 명령 대행을 요청한다. 이때, cpu제어권이 운영체제로 넘어가는데 하드웨어적으로 모드비트가 0으로 자동으로 세팅되기 때문에 특권 명령수행이 가능하다.
  • 사용자 프로그램 입장에서 system call은 자신의 주소공간 밖의 함수를 호출하는 것 이므로, 프로그램 자신이 스스로 인터럽트 라인을 세팅한다
    • 사용자 프로그램에서 디스크 파일 입출력이 필요하면, 시스템 콜로 커널 함수를 호출한다. 이때, 커널 함수는 자신의 공간 밖이므로 사용자 프로그램인 cpu제어권을 운영체제에게 이양한다.(인터럽트 라인을 세팅하는 명령을 통해 이루어진다.)
    • 인터럽트 라인이 세팅되면 cpu는 다음 명령을 수행하기 전에 인터럽트가 발생했는지 점검하게 되며, 인터럽트 발생을 인지하고 사용자 프로그램을 잠시 멈추고 운영체제에게 cpu제어권을 이양시키게 된다.
    • 운영체제는 입출력을 요청하는 인터럽트임을 인지하고, 서비스 루틴으로 이동해서 입출력 작업을 수행한다. 이 과정에서 cpu는 디스크 컨트롤러에게 파일을 읽어오라는 명령을 하게 된다.
    • 한편 디스크에서 데이터를 읽어오는 일은 cpu가 명령을 수행하는 일과 비교할 때 상대적으로 많은 시간이 소요되서 cpu제어권을 다른 프로세스에게 이양시키게 된다.
    • 디스크 컨트롤러는 작업을 완료하면 cpu에게 인터럽트를 발생시켜서 작업 완료를 알려준다. 그러면 진행중이던 프로세스를 멈추고 인터럽트 처리루틴으로 제어권이 넘어가게 되고 디스크 로컬 버퍼에서 내용을 읽어서 메모리로 복사한 후 최초에 입출력을 요청한 프로세스에게 다시 cpu를 획득할 수 있는 권한을 준다.
    • 해당 프로세스는 cpu 대기 큐에 삽입되고, cpu제어권은 다시 인터럽트 당했던 프로세스에게 넘어가 하던 작업을 계속 수행한다.

프로세스 상태

image.png

  • 프로세스의 상태는 실행,준비,봉쇄의 세가지로 크게 나누어 볼 수 있다.
  • 실행 상태는 cpu를 할당받고 기계어 명령을 수행하고 있는 프로세스의 상태를 가리킨다.
    • 시스팀 내에 cpu는 하나밖에 없으므로 컴퓨터 내에서 여러 프로세스가 동시에 수행된다고 해도 실제 cpu에서 실행 상태에 있는 프로세스는 매 시점 하나 뿐이다.
  • 준비 상태는 cpu만 할당받으면 당장 명령을 수행할 수 있지만 cpu가 하나밖에 없어 현재 cpu를 할당받지 못한 프로세스의 상태를 의미
  • 봉쇄 상태는 cpu를 할당받더라도 명령을 수행할 수 없는 프로세스의 상태를 말한다.
    • 프로세스가 요청한 입출력 작업이 진행중인 경우
  • 준비 상태의 프로세스를 줄 세우기 위해 준비 큐(ready queue)를 두고 준비 큐의 제일 앞에 줄 서 있는 프로세스에게 제일 먼저 cpu를 할당한다.
  • 준비 큐에 프로세스를 줄 세우는 방법은 cpu 스케쥴링 방법에 따라 달라진다.
  • 운영체제는 특정 자원을 기다리는 프로세스들을 줄 세우기 위해 자원 별로 큐를 두고 있다.
    • 디스크 입출력을 요청한 프로세스들은 디스크 입출력 큐(disk i/o queue)에 줄 서게 된다.
  • 어떠한 프로세스가 공유 데이터를 사용하고 있는 도중 다른 프로세스가 같은 데이터를 접근하면 데이터 일관성이 훼손되므로, 공유 데이터 접근에 대해서도 큐를 둬서 순차적으로 접근하도록 제어한다.

[참고]

http://firecontrolman.tpub.com/14100/css/Update-The-Program-Counter-113.htm
https://pediaa.com/what-is-the-difference-between-system-call-and-library-call/
https://doc.micrium.com/display/osiiidoc/Handling+CPU+Interrupts