CS

CS_운영체제_인터럽트 & 시스템콜

99duuk 2024. 6. 16. 21:59

프로그램 실행과 모드 전환

우리가 개발하는 프로그램은 일반적으로 유저 모드에서 실행된다. 

 

프로그램 실행 중에 인터럽트가 발생하거나 

시스템콜을 호출하게 되면 커널 모드로 전환된다. 

(User mode --> Kernel mode)

 

커널 모드에서의 작업

커널 모드 (Kernel Mode):

 

  • 프로그램의 현재 CPU 상태 저장: 인터럽트나 시스템 콜이 발생하면, 먼저 프로그램의 현재 CPU 상태를 저장한다.
  • 커널의 직접 처리: 커널은 인터럽트나 시스템 콜을 직접 처리한다. 이 과정에서 CPU는 커널 코드를 실행한다.
  • CPU 상태 복원: 처리가 완료되면, 중단됐던 프로그램의 CPU 상태를 복원하고, 커널은 중단된 프로그램을 다시 실행한다. (다른 프로그램을 먼저 실행한 후에 중단된 프로그램을 재개할 수도 있다.)
  • 통제권 반환: CPU 상태가 복원되면, 통제권을 프로그램에게 반환한다. (Kernel mode --> User mode)이렇게 하면 중단됐던 프로그램이 중단된 부분부터 다시 실행된다.

 

 

 

커널(kernel)

운영체제의 핵심으로, 시스템 전반을 관리/감독하는 역할을 한다.

특히 하드웨어와 관련된 작업을 직접 수행한다.

 

 

시스템을 보호하기 위해 커널 모드가 존재한다.  

커널모드가 없다면, 프로그램이 hw를 모두 점유해서 사용하고,

다른 프로세스가 영향을 받는다면 전체 시스템이 붕괴될 수도 있다.

 

따라서 시스템 전반적인 부분과 hw와 관련된 부분은 커널이 담당하고,

프로그램은 커널을 통해서 시스템의 기능이나 하드웨어를 사용한다.

 

 

 

 

 

인터럽트

프로그램을 실행하는 도중에 예기치 않은 상황이 발생할 경우 현재 실행 중인 작업을 즉시 중단하고,

발생된 상황에 대한 우선 처리가 필요함을 CPU에게 알리는 것이다.

즉, 지금 수행 중인 일보다 더 중요한 일(ex. 입출력, 우선 순위 연산 등)이 발생하면 그 일을 먼저 처리하고 나서 하던 일을 계속해야한다.



인터럽트가 발생하면 cpu는 즉각적으로 인터럽트 처리를 위해

커널 코드를 커널 모드에서 실행한다. 

 

인터럽트의 종류

하드웨어 인터럽트 (External Interrupt)

하드웨어 인터럽트는 CPU 외부에서 발생한 이벤트(입출력 장치, 타이밍 장치, 전원 등)에 의해 발생한다. 이러한 인터럽트는 주로 하드웨어 신호에 의해 발생한다.

  • 전원 이상: 전원에 문제가 생겼을 때 발생
  • 입출력 완료: I/O 작업이 완료됐을 때 발생
  • 타이머 인터럽트: 시간이 다 됐을 때 발생
  • 기타 외부 신호: 기계 착오나 외부 장치의 신호 등으로 발생

 

내부 인터럽트 (Internal Interrupt)

내부 인터럽트는 주로 잘못된 명령이나 데이터를 사용할 때 발생하며, 트랩(Trap)이라고도 부른다.

  • 0으로 나눴을 때: 산술 연산에서 0으로 나눌 때 발생
  • 오버플로우: 연산 결과가 저장할 수 있는 범위를 초과할 때 발생
  • 잘못된 명령어 사용: 명령어를 잘못 사용한 경우 발생
  • 잘못된 메모리 접근: 잘못된 메모리 공간에 접근을 시도할 때 발생

 

소프트웨어 인터럽트 (Software Interrupt)

소프트웨어 인터럽트는 명령어의 수행에 의해 발생하며, 프로그램 처리 중 명령의 요청에 의해 발생합니다. SVC 인터럽트라고도 한다

  • 시스템 콜: 프로그램이 운영체제의 기능을 사용하고자 할 때 발생한다
  • 프로그램 실행 요청: 사용자가 프로그램을 실행시킬 때 발생한다
  • 자원 할당: 소프트웨어 이용 중에 다른 프로세스를 실행시키면 시분할 처리를 위해 자원 할당 동작이 수행된다.

 

 

인터럽트가 발생하면, 현재 실행 중인 프로세스는 일시 정지되고, 커널이 해당 인터럽트를 처리한다.

인터럽트 처리가 완료되면, 이전에 중단되었던 프로세스는 원래 상태로 복원되어 계속 실행된다.

이를 통해 시스템은 다양한 이벤트를 신속하게 처리하고 안정성을 유지할 수 있다. 

 

 

인터럽트 발생 처리 과정

  1. 인터럽트 발생: 주 프로그램이 실행되다가 인터럽트가 발생하면, 현재 수행 중인 프로그램을 멈추고, 상태 레지스터와 PC(프로그램 카운터) 등을 스택 잠시 저장한 뒤에 인터럽트 서비스 루틴으로 간다. (잠시 저장하는 이유는, 인터럽트 서비스 루틴이 끝난 뒤 다시 원래 작업으로 돌아와야 하기 때문이다.) 
  2. 인터럽트 처리: 커널 모드로 전환되어 커널이 인터럽트 핸들러를 실행하여 해당 인터럽트를 처리한다.
  3. CPU 상태 복원: 인터럽트 처리가 완료되면, 스택에 저장된 상태 레지스터와 PC를 복원하고, 이전에 중단되었던 프로그램을 다시 실행한다. (서비스 루틴 시작점으로 -> 스택 복구 -> 재게)

 

인터럽트의 필요성

만약 인터럽트 기능이 없었다면, 컨트롤러는 특정한 어떤 일을 할 시기를 알기 위해 계속 체크를 해야 한다.

이를 폴링(Polling)이라고 한다.

폴링을 하는 시간에는 원래 하던 일에 집중할 수 없게 되어 많은 기능을 제대로 수행하지 못하는 단점이 있다.

 

자원을 효율적으로 사용하고, 중요한 이벤트에 신속하게 대응

 

 

컨트롤러가 입력을 받아들이는 방법(우선순위 판별 방법)에는 두 가지가 존재한다:

  • 폴링 방식: 사용자가 명령어를 사용해 입력 핀의 값을 계속 읽어 변화를 알아내는 방식. 인터럽트 요청 플래그를 차례로 비교하여 우선순위가 가장 높은 인터럽트 자원을 찾아 이에 맞는 인터럽트 서비스 루틴을 수행한다. (하드웨어에 비해 속도가 느림)
  • 인터럽트 방식: MCU 자체가 하드웨어적으로 변화를 체크하여 변화 시에만 일정한 동작을 하는 방식. Daisy Chain 방식이나 병렬 우선순위 부여 방식 등을 사용한다. 인터럽트 방식은 하드웨어로 지원을 받아야 하는 제약이 있지만, 폴링에 비해 신속하게 대응하는 것이 가능하다. 따라서 실시간 대응이 필요할 때는 필수적인 기능이다.

즉, 인터럽트는 발생 시기를 예측하기 힘든 경우에 컨트롤러가 가장 빠르게 대응할 수 있는 방법이다.

 

 

 

 

시스템콜

커널 모드의 기능을 사용자 모드가 사용가능하게 하는 것이다. (User mode --> Kernel mode)

     (ㄴ> "사용 가능하게 한다" = 사용자 모드에서 실행되는 프로그램이 커널 모드의 기능을 안전하게 사용할 수 있도록 한다는 의미)

(요청에 따라 커널에 접근하기 위한 인터페이스)

프로그램이 특정 기능을 수행하기 위해 시스템 자원에 접근해야 할 때 시스템 콜을 호출한다.

시스템 콜이 발생하면, 해당 커널 코드가 커널 모드에서 실행된다.

 

 

 

요청에 따라 커널에 접근하기 위한 인터페이스로

프로그램이 커널 모드의 기능을 사용하기 위해 사용하는 시스템 함수이다.

 

 

시스템 콜의 역할

사용자 모드에서 실행되는 프로그램이 커널 모드의 기능을 직접 사용할 수 없으므로, 특정한 인터페이스가 필요하다.

이 역할을 하는 것이 바로 시스템 콜이다.

시스템 콜을 통해 사용자 모드의 프로그램이 커널 모드의 기능을 "사용 가능하게" 된다.

 

시스템 콜의 처리 과정

  1. 시스템 콜 호출: 프로그램이 특정 시스템 기능을 요청한다.
  2. 커널 모드로 전환: 시스템 콜 인터럽트가 발생하여 CPU는 커널 모드로 전환된다.
  3. 현재 상태 저장: 프로그램의 현재 CPU 상태가 저장된다.
  4. 시스템 콜 처리: 커널이 시스템 콜을 처리합니다. 예를 들어, 파일을 열거나 데이터를 읽는 작업을 수행한다.
  5. CPU 상태 복원: 시스템 콜 처리가 완료되면, 저장된 상태가 복원된다.
  6. 통제권 반환: CPU는 커널 모드에서 유저 모드로 전환되고, 프로그램은 원래 작업을 계속한다.

 

시스템 콜의 종류

  1. 프로세스/스레드 관련: 프로세스 생성, 종료, 스레드 관리 등
    • 프로세스 관리 : 
    • fork(): 새로운 프로세스를 생성합니다. 부모 프로세스의 주소 공간을 그대로 복사하여 자식 프로세스를 만든다.
    • exec(): 현재 프로세스를 새로운 프로그램으로 대체합니다. 프로세스의 주소 공간을 새로운 프로그램으로 덮어쓴다.
    • exit(): 프로세스를 종료합니다. 프로세스가 실행을 마치고 운영체제에 종료를 알리는 데 사용된다.
  2. 파일 I/O 관련: 파일 열기, 읽기, 쓰기, 닫기 등
    • 파일 시스템 관리 :
    • open(): 파일을 엽니다. 파일 디스크립터를 반환하며, 이후 파일 작업에 사용된다.
    • read(): 파일에서 데이터를 읽습니다. 파일 디스크립터와 버퍼, 읽을 바이트 수를 인수로 받다.
    • write(): 파일에 데이터를 씁니다. 파일 디스크립터와 버퍼, 쓸 바이트 수를 인수로 받는다.
    • close(): 파일을 닫습니다. 파일 디스크립터를 인수로 받다.
  3. 소켓 관련 (네트워크): 소켓 생성, 데이터 송수신 등
    • 통신 :
    • socket(): 네트워크 통신을 위한 소켓을 생성다.
    • connect(): 소켓을 통해 원격 서버에 연결한다.
    • send(): 소켓을 통해 데이터를 보낸다.
    • recv(): 소켓을 통해 데이터를 받는다.
  4. 장치 관련: 키보드 입력, 마우스 클릭 등
    • 장치 관리 :
    • ioctl(): 장치의 제어 명령을 수행합니다. 다양한 장치 특수 기능을 수행하는 데 사용된다.
    • read(), write(): 장치에서 데이터를 읽고 쓰는 데 사용됩니다. 파일 시스템 관리의 read(), write()와 유사하게 작동한다.
  5. 프로세스 통신 관련: 프로세스 간 데이터 교환, 신호 전달 등
    • 프로세스 통신 : 
    • pipe(): 두 프로세스 간에 통신할 수 있는 파이프를 생성한다.
    • shmget(): 공유 메모리 영역을 할당하거나 얻는다.
    • msgget(): 메시지 큐를 생성하거나 얻는다.
    • semget(): 세마포어를 생성하거나 얻는다.
    • kill(): 신호를 특정 프로세스에 보낸다.