Skip to content

Latest commit

 

History

History
104 lines (71 loc) · 8.01 KB

File metadata and controls

104 lines (71 loc) · 8.01 KB

시스템 콜(System Call)

image 시스템 콜은 GUI, CLI와 같은 UI와 운영체제가 제공하는 서비스들 사이에 위치한다. 사용자가 운영체제에게 일을 요청하고 싶을 때 시스템 콜을 이용한다. 즉 응용프로그램에서 운영체제에게 어떠한 기능(시스템 자원)을 수행해달라고 하는 하나의 수단이다. 다르게 정리하면 커널 영역의 기능을 사용자 모드가 사용 가능하게 하는 하나의 수단이다 -> 프로세스가 하드웨어에 접근해서 필요한 기능을 사용할 수 있게 함

먼저 듀얼모드(커널 모드, 사용자 모드)에 대해서 알아보자

  • 사용자와 운영체제는 시스템 자원을 공유
  • 사용자에게 제한을 두어 사용자가 메모리 내의 주요 운영체제 자원에 직접적으로 접근할 수 없도록 함(보안)
  • 운영체제에서 프로그램이 구동되는데 있어, 파일을 읽어오거나, 쓰거나 화면에 메시지를 출력하는 등 많은 부분이 커널모드를 사용

image

  1. 커널 모드

프로그램 카운터가 운영체제가 존재하는 부분을 가리키고 있다면, 현재 운영체제의 코드를 수행 중이며 CPU가 커널 모드에서 수행 중이라고 한다.

  1. 사용자 모드

프로그램 카운터가 사용자 프로그램이 존재하는 메모리 위치를 가리킬 경우, 사용자 프로그램을 수행 중이며 CPU가 사용자 모드에서 수행 중이라고 한다

  • 일반 명령 : 메모리에서 자료를 읽어와서 CPU에서 계산하고 결과를 메모리에 쓰는 일련의 명령들. 모든 프로그램이 수행할 수 있음(사용자 모드)
  • 특권 명령 : 보안이 필요한 명령으로 입출력 장치, 타이머 등 각종 장치를 접근하는 명령(커널 모드)
  • CPU 내에 모드 비트를 두어 두 명령을 수행한다
  • 사용자 프로그램이 디스크의 파일을 접근하거나, 화면에 결과를 출력하는 등의 작업이 필요한 경우가 있다. 하지만, 이러한 작업은 특권 명령의 수행을 필요로 한다
  • 이와 같은 경우, 사용자 프로그램은 스스로 특권 명령을 수행할 수 없으므로 운영체제에게 특권 명령의 대행을 요청한다. 이러한 서비스 요청은 시스템 콜이라고 부른다.(즉 특권 명령의 대행을 요청하여 사용자 프로그램이 커널 영역의 기능을 수행하게 해준다.)
디스크에서 자료를 읽어오는 시스템 콜이라고 가정!
  1. 사용자 프로그램이 시스템 콜을 하게 되면 운영체제는 자신의 커널 영역에 정의된 시스템 콜 처리 코드를 수행한다
  2. CPU가 컨트롤 레지스터를 세팅해 디스크 컨트롤러에게 데이터를 읽어오라고 명령한다
  3. 디스크 컨트롤러는 디스크로부터 데이터를 읽어와서 자신의 로컬 버퍼에 저장한다
  4. 작업이 완료되면 디스크 컨트롤러가 CPU에게 인터럽트를 발생시켜 입출력 작업이 완료되었음을 통지한다

image

통상적으로 시스템 콜은 여러 종류의 기능으로 나뉘어져 있다. 각 시스템 콜에는 번호가 할당되고 시스템 콜 인터페이스는 이러한 번호에 따라 인덱스되는 테이블을 유지한다. 아래 그림은 open() 시스템 콜을 호출했을 때, 운영체제에서 어떻게 처리되는지를 보여준다 image

필요한 기능이나 시스템 환경에 따라 시스템 콜이 발생할 때, 좀 더 많은 정보가 필요할 수도 있다. 그러한 정보가 담긴 매개변수를 운영체제에 전달하기 위해서는 대략 3가지 정도의 방법이 있다

  1. 매개변수를 CPU 레지스터 내에 전달한다. 이 경우에 매개변수의 갯수가 CPU 내의 레지스터 갯수보다 많을 수 있다.
  2. 위와 같은 경우에 매개변수를 메모리에 저장하고 메모리의 주소가 레지스터에 전달된다(아래 그림 참고)
  3. 매개변수는 프로그램에 의해 스택으로 전달될 수도 있다 image

2,3 번은 전달되는 매개변수의 갯수나 길이에 제한이 없기 때문에 몇몇 운영체제에서 선호하는 방식이다

시스템 콜의 유형

5가지의 범주로 나눌 수 있다

  1. 프로세스 제어 : 프로세스 생성, 종료, 로드, 실행, 프로세스 속성 가져오기, 프로세스 속성 설정, wait이나 signal 이벤트, 메모리 할당 및 해제
  2. 파일 조작 : 파일을 생성하거나 삭제, 읽기, 쓰기, 열기, 닫기, Reposition 등
  3. 장치 관리 : 장치 요구 및 장치 해제, 읽기, 쓰기, 재배치 등
  4. 정보 유지 : 시간과 날짜의 설정과 획득, 시스템 자료의 설정과 획득
  5. 통신 : 통신 연결의 생성 및 제거, 메시지의 송수신, 상태 정보 전달 등
  6. 보호 : 파일 권한 얻기 및 설정

구체적인 시스템 콜의 명령어들을 살펴보자

fork(), exec(), wait()와 같은 것들은 Process 생성과 제어를 위한 System Call이다

  • fork, exec은 새로운 Process 생성과 관련이 되어 있다
  • wait는 Process(Parent)가 만든 다른 Process(Child)가 끝날 때까지 기다리는 명령어임
Fork
  • 새로운 Process를 생성할 때 사용

pid : 29146
parent of 29147 (pid : 29146)
child (pid : 29147)

을 출력한다 (parent와 child의 순서는 non-deterministic하다. 즉, 확신할 수가 없다. scheduler가 결정하는 일이다.

PID : 프로세스 식별자, UNIX 시스템에서는 PID는 프로세스에게 명령을 할 때 사용함

Fork()가 실행되는 순간 프로세스가 하나 더 생기는데, 이 때 생긴 프로세스(Child)는 fork를 만든 프로세스(Parent)와 거의 동일한 복사본을 갖게 된다. 이 때 OS는 위와 똑같은 2개의 프로그램이 동작한다고 생각하고, fork()가 return될 차례라고 생각한다. 그 때문에 새로 생성된 Process(Child)는 main에서 시작하지 않고, if문부터 시작하게 된다

그러나, 차이점이 있다. 바로 Child와 Parent의 fork() 값이 다르다는 점이다. 따라서 완전히 동일한 복사본이라 할 수 없다

Parent의 fork()값 => child의 pid값
Child의 fork()값 => 0

Parent와 Child의 fork값이 다르다는 점은 매우 유용한 방식이다 그러나 Scheduler가 부모를 먼저 수행할지 아닐지 확신할 수 없다. 따라서 아래와 같이 출력될 수 있다.

pid : 29146
child (pid : 29147)
parent of 29147 (pid : 29146)

wait
  • Child 프로세스가 종료될 때까지 기다리는 작업

pid : 29146
child (pid : 29147)
parent of 29147 (wc : 29147 / pid :29146)

wait를 통해서, Child의 실행이 끝날 때까지 기다려줌. Parent가 먼저 실행되더라도, wait()는 Child가 끝나기 전에는 return하지 않으므로, 반드시 child가 먼저 실행됨

exec
  • 단순 fork는 동일한 프로세스의 내용을 여러 번 동작할 때 사용한다
  • Child에서는 Parent와 다른 동작을 하고 싶을 때는 exec을 사용할 수 있다

exec가 실행되면,

execvp(실행 파일, 전달 인자) 함수는, code segment 영역에 실행 파일의 코드를 읽어와서 덮어 씌운다

씌운 이후에는, heap, stack, 다른 메모링 영역이 초기화되고, OS는 그냥 실행한다. 즉 새로운 Process를 생성하지 않고, 현재 프로그램에 wc라는 파일을 실행한다. 그로 인해서, execvp() 이후의 부분은 실행되지 않는다