시스템 호출(System Call)
- 프로그램과 운영체제가 상호작용하기 위한 수단.
- 프로그램한테 보여지는 운영체제 인터페이스
- System Call을 통해 프로그램은 필요로 하는 서비스를 운영체제 커널에 요청한다.
시스템 호출과 함수 호출
- 둘 다 요청한 사항을 수행하고 원래 프로그램으로 복귀 한다는 점은 같다.
- 시스템 호출: 유저 모드(user mode)에서 커널모드(kernel mode)로 전환이 일어남.
- 함수 호출: 유저 모드에서 계속 수행
시스템 호출 방법은 운영체제/기계마다 다르다. 어셈블리 언어(기계어) 수준에서 사용가능하며 고급언어(C언어) 수준에서는 시스템 호출로 이어지는 라이브러리가 제공된다.
System Call의 일종인 File Management
해당 함수들은 운영체제의 System Call이 아닌 운영체제의 라이브러리다.
함수를 호출 하면 System Call을 하는게 아닌 라이브러리 함수를 호출한다.
file을 open하고 read를 할경우 수행되는 과정은 아래와 같다. 또한 아래의 과정에서 System Call이 일어난다.
하얀색 부분은 유저 공간, 회색 부분이 바로 커널 공간이다. 저 곳이 운영체제의 공간이다.
과정)
1, 2, 3은 파일을 읽어오기 위해 스택에 파일의 정보들을 담는 과정이다 이렇게 스택에 담겨지면 4번을 통해 값 들을 넘기고, 5번에선 register에 read를 위한 system code를 삽입한다. 이 후 6번을 통해 운영체제 커널로 제어권이 넘어간다 usermode 에서 kernelmode로 제어권이 넘어간다.
Dispatch는 register의 값을 읽고 system code에 해당하는 handler를 cpu로 보낸다. 명령이 처리되면 System call handler를 통하여 user mode로 되돌아가게 된다.
read 명령어는 System call을 하는 명령어가 아닌 이유이다. 라이브러리의 read를 실행시키면 read 명령어는 User가 생성한 read 명령어의 데이터를 레지스터로 보내게되고 Library procedure read를 통해 Kernel space로 점프하게 된다.
Some System Call For Process Management
fork()
- child process를 만들어준다.
- return 값은 자식의 pid이다.
예를 들어 pid = fork()일 경우 pid값이 0이 아니면 부모프로세스, 0이면 자식 프로세스인 것이다.
프로세스 A는 fork를 통해 B와 C의 자식 프로세스를 생성했다.
프로세스 A의 자식 프로세스인 B는 fork를 통해 D, E, F프로세스를 생성했다.
waitpid(pid, &statloc, option)
자식 프로세스가 종료되길 기다린다.
execve(name, argv, enfironp)
부모 프로세스가 사라진 새로운 프로세스를 생성한다.
간단한 토이shell
이 코드는 간단한 쉘이다.
read_command를 통해 입력받은 명령어(date)를 command 변수에 저장한다.
fork의 리턴값은 자식프로세스의 pid이므로 0이 아니면 부모 프로세스이며, 0이면 부모 프로세스이다.
부모 프로세스인 경우 자식 프로세스의 종료를 기다리며 자식 프로세스인 경우 execve로 부모프로세스와 관련없는 프로세스로 command명령어로 코드를 교체시켜서 실행시킨다.
쉘에서 명령어(ps, date)들은 각기 프로세스라고 할 수 있다. 쉘이 명령어를 실행시키는 방법은 fork를 통해서 라고 할 수 있다. 예를 들어 date명령어를 입력받았다. 라고 하면 shell은 fork를 통해 부모와 같은 코드의 자식 프로세스를 생성한다.
fork가 된 직후 date명령어를 실행한다.
date명령어도 shell이 만든 자식프로세스이며 코드가 date로 교체된 것이라고 할 수 있다.
process에 할당되는 메모리 영역
Process는 운영체제에 의해 관리되고 운영체제는 Process에 메모리를 할당한다.
프로세스에 할당되는 메모리 영역은 4가지 영역으로 구분된다.
Stack에는 지역변수
Data에는 전역변수, 동적할당변수
Text에는 Program Code가 할당된다 Program code는 새로 쓰여지지 않기 때문에 only read이다.
만약 부모 프로세스가 자식 프로세스를 생성할 경우 이 4가지 영역에 대한 메모리 영역이 새로 할당된다.
자식의 text영역은 program code를 저장하기 때문에 text영역은 부모와 같다.
하지만 data와 stack은 전역변수, 동적할당변수와 지역변수를 할당하기 때문에 부모와 무조건 같지 않고 다를 수 있다.