07. 인터럽트

  • 인터럽트란?

    • CPU가 프로그램을 실행하고 있을 때,

      입출력 하드웨어 등의 장치나 또는 예외 상황이 발생하여 처리가 필요할 경우

      CPU에 알려서 처리하는 기술

      어느 한 순간 CPU가 실행하는 명령은 하나! 다른 장치와 커뮤니케이션 어떻게?

    • 컴퓨터 구조단 생각해보기

      • PC(program counter)는 (instruction) code 한줄 한줄을 실행하는데 집중

      • 외부 이벤트 처리해야할 때, 정보를 어떻게 처리할까

      • 처리가 끝났다는 것을 OS에 알려주기.

    • OS 코드 레벨로 생각해보기

      • 저장 매체에서 파일을 읽어 들일 때, blocking상태(event)에 빠진 상태를

        어떻게 CPU에 끝났다고 알려서 ready 상태 로 변경?

        (이 기술을 interrupt라고 한다)

      • 즉, event 발생 => (인터럽트) => 처리(kernel code)

      • (현재 사용 중인 사용자 프로그램을 잠시 멈추고, CPU의 제어권을 운영체제로 양도한다)

    • 예외 상황 핸들링

      • CPU가 프로그램을 실행하고 있을 떄, 입출력 하드웨어 등의 장치 또는 예외 상황 발생한 경우 CPU가 해당 처리를 할 수 있도록 CPU에 알려 줘야 함.

      • 0으로 나누는 연산과 같은 예외 발생 상황도, CPU는 처리를 하려고 한다.

        그래서 문제가 생길 수 있다. 이런 예외 상황을 운영체제, 스케쥴러에 알려서

        프로세스를 kill(error 메세지 발생) 해야 한다. 이 때 정보를 알려 주는 것을 인터럽트라고 할 수있다.

    • 선점형 스케쥴러에서 사용되는 방법

    • 이벤트를 정의하고, 발생했을 때 처리하는 것을 인터럽트라고 한다.

    • 인터럽트는, 일종의 이벤트로 불린다.

    • 이벤트에 맞게 운영체제가 처리하도록 구현되어있다.

  • 인터럽트 종류

    • 내부 인터럽트(trap, sw인터럽트)

      • 주요 프로그램 내부에서 잘못된 명령(예외 상황) 또는 잘못된 데이터 사용 시 발생

      • 주로 프로그램 내부에서 발생하므로, 소프트웨어 인터럽트라고도 함

        • Divide-by-Zero Interrupt: 0으로 나누는 코드 실행 시

        • 사용자 모드(user mode)에서 허용되지 않는 명령 또는 공간 접근 시

          • C언어에서 pointer가 가리키는 주소가 잘못됬을 때

            • Linux에서 0-4GB를 '프로세스'공간이라고 함. 이 때,

            • 0-3GB는 user mode

            • 3-4GB를 kernel mode라고 함.

            • 사용자 모드에서 process로 실행하다가, 포인터가 kernel모드를 가리켰을 때 에러 발생

        • 계산 결과가 Overflow/Underflow 날 때

          • int 변수 type 지정시, 32bit

            • unsigned(부호 없는 것)

            • signed(부호 있는 것) (2³¹만큼 수 표현)

              • 이 때 1 bit는 부호를 표시함.

              • 2³¹ + 2³¹ => overflow

              • (컴구에서 overflow본것 다시 정리)

              • 음수로 표현 가능한 범위를 벗어난 경우 =>underflow

    • 외부 인터럽트(hw인터럽트):

      • 주로 하드웨어에서 발생되는 이벤트(프로그램 외부)

      • 주로 하드웨어에서 발생하므로, 하드웨어 인터럽트라고도 함.

        • 전원 이상

        • 기계 문제

        • I/O 관련 이벤트: 프린터, 마우스, 키보드, 저장 매체(SSD등)

        • timer interrupt: 선점형 스케쥴러 위해 필요

          • H/W로 부터 일정시간마다 타이머 인터럽트를 OS(kernel모드)에 알려줌

          • 일정 시간마다, process를 교체하겠다.

  • 인터럽트 내부 동작

    • 시스템콜 인터럽트

      • 시스템콜 실행을 위해서는 강제로 코드에 인터럽트 명령을 넣어, CPU에게 실행 시켜야 한다.

      • 시스템 콜 실제 코드(어셈블리어_인텔기준)

        • eax 레지스터에 시스템 콜 번호를 넣고,

        • ebx 레지스터에 시스템 콜에 해당하는 인자 값을 넣고,

        • 소프트웨어 인터럽트 명령을 호출하면서 0 X 80 값을 넘겨줌.

          • 여기서 쓰인 int = interrupt

            mov eax, 1
            mov ebx, 0
            int 0 X 80
      • 시스템 콜 인터럽트 명령을 호출하면서, 0X80 값을 넘겨줌

        • CPU는 사용자 모드를 커널 모드로 바꿔줌

        • IDT(Interrupt Descriptor Table)에서 0 X 80에 해당하는 주소(함수) 찾아 실행

          [interrupt 번호 : 주소(함수 코드)]

        • system_call()함수에서 eax로부터 시스템 콜 번호를 찾아서, 해당 번호에 맞는 시스템콜 함수로 이동

          [시스템콜번호: kernel function(system call)]

        • 해당 시스템콜 함수 실행 후, 다시 커널 모드에서 사용자 모드로 변경하고, 다시 해당 프로세스 다음 코드 실행

    • 인터럽트와 IDT

      • 인터럽트는 미리 정의되어 각각 번호와 실행 코드를 가리키는 주소가 기록되어있다.

        • 어디에? IDT(Interrupt Descriptor Table)에 기록

        • 언제? 컴퓨터 부팅 시 운영체제가 (테이블을) 기록

        • 어떤 코드? 운영체제 내부 코드

      • 정리

        • 항상 인터럽트가 발생하면, IDT(Interrupt Descriptor Table)을 확인한다.

        • 시스템콜 인터럽트 명령은 0X80 번호가 미리 정의.

        • 인터럽트 0X80 에 해당하는 운영체제 코드는 system_call()이라는 함수

        • 즉 IDT에는 0X80 => system_call()과 같은 정보가 기록되어있음.

      • 리눅스 예

        • 0~31: 예외상황 인터럽트(내부/소프트웨어 인터럽트)

          • 일부는 정의 안된 채로 남겨져 있음

        • 32~47: 하드웨어 인터럽트(주변장치 종류/갯수따라 변경가능)

        • 128: 10진수로 0X80을 표현

  • 인터럽트와 프로세스 정리

    • 프로세스 실행 중, 인터럽트 발생

    • 현 프로세스 실행 중단

    • 인터럽트 처리 함수 실행(운영체제, 커널 모드)

    • 현 프로세스 재 실행

  • 선점형 스케쥴러 예시

    • 수시로 timer interrupt가 발생

      • OS 가 timer interrupt횟수를 기억했다가 예를 들어 5번 이상 발생한다면 현재 프로세스 중지하고, 다른 프로세스 실행한다.

Last updated