System Call과 Interrupt

JISU LIM·2023년 8월 14일
2

CS-Tech

목록 보기
1/16
post-thumbnail
post-custom-banner

System Call

시스템 호출 또는 시스템 콜(system call), 시스콜(syscall)은 운영체제의 커널이 제공하는 서비스에 대해, 응용 프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스이다. 보통 C나 C++와 같은 고급 언어로 작성된 프로그램들은 직접 시스템 호출을 사용할 수 없기 때문에 고급 API를 통해 시스템 호출에 접근하게 하는 방법이다.

커널에 접근한다던지, 시스템을 호출한다던지 아직은 와닿지 않는다. 이를 이해하기 위해서는 프로그램이 실행될 수 있는 두 가지 모드에 대해서 먼저 알아야 한다.

프로그램이 실행될 수 있는 두 가지 모드 - Dual Mode

운영체제는 커널 모드와 사용자 모드로 나뉘어 구동되며, 운영체제는 다양한 서비스들을 수행하기 위해서 하드웨어를 직접적으로 관리한다.

사용자 모드(User Mode)

  • 프로그램이 사용자 모드에서 실행중인 경우 메모리 등의 하드웨어 리소스에 직접 엑세스 할 수 없다.
  • 사용자 모드에서 실행중인 프로그램에서 충돌 등의 문제가 발생하더라도 전체 시스템이 정지되지는 않는다.(하드웨어 리소스에 직접 엑세스하고 있지 않기 때문)
  • mode bit = 1로 관리된다.

커널 모드(Kernel Mode)

  • 프로그램이 커널 모드에서 실행중인 경우 메모리 등의 하드웨어 리소스에 직접 엑세스할 수 있다.
  • 이를 특권 모드(Privileged mode)에 있다고도 말한다.
  • 그러나 커널 모드에서 실행중인 프로그램에 문제가 발생할 경우 전체 시스템이 충돌되거나 정지된다는 문제가 있다. (하드웨어 리소스에 직접 엑세스하고 있기 때문)
  • mode bit = 0으로 관리된다.

즉, 프로그램이 항상 특권을 가진 커널 모드에 있다는 것은 전체 시스템에 장애를 일으킬 수 있는 위험을 수반한다. 그러므로 상대적으로 안전한(Safety) 모드인 사용자 모드에서 프로그램을 실행하고, 하드웨어 자원에 엑세스가 필요한 경우 시스템을 호출(System call)하여 커널 모드로 운영체제에게 모드의 전환을 요청하는 것이다.

이렇게 운영체제의 원활한 작동과 기능을 위해서 사용자로부터 시스템 자원 접근을 제한하는 보호 장치 역할을 하도록 두 가지 모드로 구분하는 것을 이중 동작 모드(Dual Mode)라고 한다.

이때, 유저모드에서 커널모드로, 커널모드에서 유저모드로 전환될 때 Context Switching이 발생한다.

운영체제에서의 처리 과정

시스템 콜 구분 방법

통상적으로 시스템 콜은 여러 종류의 기능으로 나뉘어져 있으며, 각 시스템 콜에는 번호가 할당된다. System Call Interface는 이러한 번호에 따라 인덱스 테이블을 관리하고 서로 다른 시스템 콜을 구분할 수 있다.

일부 운영체제에서는 지정된 함수의 이름이 운영체제 내부에서 시스템 콜 번호로 변환되어 호출하는 과정에서 시스템 콜을 구분하여 실행한다.

위 두 방법 중 하나 또는 둘을 조합하여 시스템 콜을 구분하고 처리한다.

운영체제에서의 시스템 콜 처리 과정 예시

user application에서 system call open, write, close에 해당하는 함수의 실행은 user mode에서 수행되어 관련 라이브러리를 호출하고, 실행의 흐름은 kernel mode로 전환된다. 커널은 호출을 실행해서 반환 값을 전달(수행)하고 다시 user mode로 돌아와 다음 단계를 진행한다.

필요한 자원의 정보를 운영체제에 전달하는 방법

  1. 매개변수를 CPU 레지스터 내에 전달한다.
    • 이 경우 매개변수의 개수가 CPU 내의 총 레지스터 개수보다 많을 수 있다.
  2. 매개변수를 메모리에 저장하고 메모리의 주소를 레지스터에 전달한다.
  3. 프로그램에 의해 스택(stack)으로 전달(push)한다.
    • 2, 3번 방법의 경우 전달되는 매개변수의 개수나 길이에 제한이 없기 때문에 특정 운영체제에서 선호되는 방식이다.

시스템 콜의 유형

시스템 콜은 아래와 같이 크게 여섯가지로 분류된다.

프로세스 제어(Process Control)

  • fork()
  • exit()
  • wait()
  • etc

파일 조작(File Manipulation)

  • open()
  • read()
  • write()
  • close()
  • etc

장치 조작(Device Manipulation)

  • ioctl()
  • read()
  • write()
  • etc

정보 유지(Information Maintenance)

  • getpid()
  • alarm()
  • sleep()
  • etc

통신(Communication)

  • pipe()
  • shm_open()
  • mmap()

보호(Protection)

  • chmod()
  • umask()
  • chown()

Interrupt

마이크로프로세서(CPU)에서 인터럽트(interrupt) 란, CPU에서 프로그램을 실행하고 있을 때, 입출력하드웨어 등의 장치에 예외상황이 발생하여 처리가 필요할 경우에 마이크로프로세서에게 알려 처리할 수 있도록 하는 것을 말한다.

즉, 시스템에서 발생한 다양한 종류의 이벤트, 혹은 그런 이벤트를 알리는 메커니즘인 인터럽트(Interrupt)가 발생한 경우에도 System Call을 호출했을 때와 마찬가지로 시스템 보호 차원에서 커널 모드로의 전환을 수행하여 OS에게 하드웨어에 접근할 권한을 요청하게 된다.

인터럽트의 유형

인터럽트의 유형은 이벤트가 어디에서 발생했는지에 따라 크게 HW 인터럽트와 SW 인터럽트로 나눌 수 있다.

HW 인터럽트

키보드, 마우스 또는 프린터와 같은 외부 하드웨어 장치로부터도 발생할 수 있지만, 하드웨어 타이머 같은 경우 CPU 내부에서 클락(clock)을 일정한 주기를 가지고 인터럽트로 발생시킨다.

  • 전원(power)에 문제가 생겼을 때
  • I/O 작업이완료됐을 때
  • 시간이 다 됐을 때(timer 관련) 등

SW 인터럽트

시스템 콜을 통해서 의도적으로 발생시킬 수도 있지만, 프로그램 실행 중에 트랩(trap) 또는 예외(exception)로 발생할 수 있다.

  • 시스템 콜도 SW 인터럽트
  • 0으로 나눴을 때
  • 잘못된 메모리 공간에 접근을 시도할 때 등

위와 같은 인터럽트가 발생하면 CPU에서는 즉각적으로 인터럽트의 처리를 위해 현재 CPU 상태를 저장하고, 유저 모드에서 커널 모드로 전환을 수행한 후 인터럽트 처리 관련 커널 코드를 커널 모드에서 실행한다.

인터럽트와 폴링

폴링(polling)이란 하나의 장치 또는 프로그램이 다른 장치나 프로그램의 상태를 주기적으로 검사하여 일정한 조건을 만족할 때 송수신 등의 자료처리를 하는 방식을 말한다. 따라서 주기적으로 장치의 레지스터를 읽어야 하며, 이 작업이 진행되는 동안 다른 장치는 체크가 힘들어 자원이 낭비된다.

폴링이 대상을 주기적으로 감시해서 상황 발생시 처리한다면, 인터럽트는 대상이 CPU에게 일을 처리해 달라고 요청하는 수단으로 대비되는 개념이다.

동시에 두 개 이상의 인터럽트가 발생한다면? - 인터럽트의 우선순위

여러 장치에서 인터럽트가 동시에 발생하거나 인터럽트 서비스 루틴 수행 중 인터럽트가 발생했을 경우 우선순위를 따져서 처리한다.

전원 이상(Power fail) > 기계 착오(Machine Check) > 외부 신호(External) > 입출력(I/O) > 명령어 잘못 > 프로그램 검사(Program Check) > SVC(SuperVisor Call)

일반적으로 하드웨어 인터럽트가 소프트웨어 인터럽트보다 우선 순위가 높고 내부 인터럽트 보다 외부 인터럽트가 우선 순위가 높다.

인터럽트와 시스템 콜 처리 예제 : file read

가정 : running thread1(t1)과 ready thread2(t2)가 있고, single core에서 동작

  • file을 read하기 위해서 system call - read를 호출함
    • 커널 모드로 진입
    • t1의 cpu상태 저장
    • 파일을 읽을 준비(ssd)
      • read system call 은 block system call이기 때문에 t1이 파일을 읽을 준비를 마칠 때까지 기다려야 함 → t1을 waiting 상태로 변경
    • 그러면 현재 cpu는 동작하고 있는 것이 없기 때문에 ready중이던 t2를 running상태로 변경
    • 다시 커널모드에서 유저모드로 전환(현재 cpu자원 통제권은 t2에 있음)
  • ssd쪽에서 t1이 file을 읽을 준비가 되었다고 인터럽트를 통해 알려줌
    • 인터럽트를 처리하기 위해 커널모드로 진입
    • t2의 cpu상태를 저장
    • t1을 ready상태로 변경
    • 이전 t2의 cpu상태 복원, 인터럽트 전 중단되었던 부분부터 시작
  • (가정 : 멀티 쓰레드 환경) t2가 주어진 timer를 모두 소요함 → 인터럽트 발생
    • 커널모드 진입
    • t2 cpu상태 저장, ready상태가 됨
    • t1이 running상태, file read system call 호출 시 저장했던 t1의 cpu상태가 복원됨
    • 유저모드로 전환
  • 이제 통제권은 다시 t1에게, 파일을 읽을 준비를 마친 t1은 이제 실제로 읽어오는 작업을 이어서 수행하게 됨

🙏 본 개념의 정리에 대한 피드백과 질문은 환영입니다!

✏️ Tech Interview Study

본 개념의 다른 정리 및 피드백, 인터뷰 주제의 순서는 테크 인터뷰 스터디 Repository에서 확인 가능합니다.

📚 Reference

profile
Grow Exponentially
post-custom-banner

4개의 댓글

comment-user-thumbnail
2023년 8월 14일

개발자로서 배울 점이 많은 글이었습니다. 감사합니다.

1개의 답글
comment-user-thumbnail
2023년 8월 14일

자세하고 쉽게 설명해주셔서 이해하기 너무 좋았습니다. 감사합니다.

1개의 답글