시스템 호출: 두 판 사이의 차이

내용 삭제됨 내용 추가됨
잔글편집 요약 없음
편집 요약 없음
1번째 줄:
'''시스템 호출'''({{lang|en|system call}})은 [[운영 체제]]의 [[커널]]이 제공하는 [[서비스]]에 대해, [[응용 프로그램]]의 요청에 따라 커널에 접근하기 위한 [[인터페이스 (컴퓨터 과학)|인터페이스]]이다. 보통 C나 C++과 같은 [[고급 언어]]로 쓰여진 프로그램들은 직접 시스템 호출을 사용할 수 없기 때문에 고급 [[API]]를 통해 시스템 호출에 접근하게 하는 방법이다.
 
운영체제의운영 체제의 구성상, 커널과 응용프로그램은응용 프로그램은 CPU의 [[권한 수준]](privilege levels)이나 하드웨어 접근 능력이 다르다. 커널은 CPU 시스템의 RAM/FLASH 등에 물리주소가 일치하는 링커구조를 가지고 특정 메모리 위치에서 동작한다. 이때 커널의 기계어 코드에서 사용하는 모든 주소는 물리주소로 고정되어 컴파일되고 로드되어 실행된다. 따라서 커널은 부팅과정에서 전체 메모리 리소스 중에 일정하게 점유하여 동작하고 모든 인터럽트 등이나 하드웨어 접근이 가능하다. 그러나 응용프로그램은응용 프로그램은 커널이 제공한 자원을 사용하여 어느 위치든 상황에 따라 메모리에 점유하고 실행한다. 응용프로그램은응용 프로그램은 사용자 요청에 따라 실행되는 프로그램이므로 물리주소를 확정할 수 없다. 따라서 응용프로그램이응용 프로그램이 작성되면 메모리 위치를 처음부터 로드된다고 생각하고 개발도구에서 링크된다. 보통 MMU을 통해 논리주소를 물리주소로 변환된다. 그리고 응용프로그램은응용 프로그램은 CPU의 권한수준이 사용자 공간(user space)에서 동작하며 특정한 기계어 명령어 실행이 불가능하다. 이와 같은 상황에서 응용프그램이응용 프그램이 파일시스템을 사용하거나 기타 여러상황에서 커널에 의존해야만 한다. 응용프로그램에서응용 프로그램에서 커널의 서비스를 사용하는 방법이 '''시스템 호출'''이다. 커널의 인터럽트 처리등의 과정을 프로그램하려면 [[어셈블리어]]와 C와의 혼용구조로 구성한다. 그리고 CPU나 컴퓨터 시스템의 구조나 상황이 다르므로 CPU에 따라 분리되어 작성되고 커널소스 폴더구조에서 소스가 분리되어 작성되고 저장 관리된다. asmlinkage는 어셈블리어와 관계가 있는 예약어이다.
 
시스템 호출이란 프로그래밍 언어에서 지원하지 않는 기능에 대하여 운영체제의운영 체제의 루틴을 호출하여 이용하는 것을 말한다. 시스템 호출의 세 가지 기능은 다음과 같다.
# 사용자 모드에 있는 응용 프로그램이 커널의 기능을 사용할 수 있도록 하는 것.
# 시스템 호출을 부르면 사용자 모드에서 커널 모드로 바뀐다
18번째 줄:
[[명령어 인터프리터]] 또는 [[셸]]을 통해 입력된 명령을 수행하는 과정에서 새로운 [[프로세스]]를 시작하기 위해서는 시스템 호출을 해야 한다. 예를 들어 [[유닉스]] 시스템에서는 새로운 프로세스를 시작하기 위해 [[exec]] 시스템 호출 이후 [[fork]] 시스템 호출이 뒤따른다. exec 호출이 호출 프로세스 위로 다른 실행가능한 새로운 프로세스를 띄우는 동안, fork 호출은 현재 실행 중인 프로세스를 복제한다.
 
[[리눅스]]의 [[커널]]은 권한수준이 최고수준(x86, Ring 0)에서 실행되며 하드웨어 제어 및 응용프로그램의응용 프로그램의 스케쥴링 및 시분할 실행을 하도록 제어한다. 하드웨어 제어를 하는 모든 권한을 커널에서 가지고 있기 때문에 파일시스템 같은 경우 응용프로그램에서는응용 프로그램에서는 직접 제어할 수 없다. 따라서 응용프로그램에서응용 프로그램에서 하드웨어의 데이터를 가져오거나 쓰려면 커널의 디바이스장치 드라이버와 연동되어 실행되어야 한다.
결국 응용프로그램이응용 프로그램이 파일시스템을 이용하려면 커널의 파일시스템 드라이버로 넘어가 실행되어야 하므로 시스템 호출 방법을 사용한다.
 
=== 리눅스 커널의 디바이스장치 드라이버와 시스템 호출 예 ===
 
* 리눅스 커널의 디바이스장치 드라이버 예
: 권한수준 커널 공간(kernel space, x86 레벌 링0, ARM 슈퍼바이저 모드(Supervisor Mode))에서 실행.
 
41번째 줄:
};
</source>
와 같은 구조로 디바이스를장치를 정의한다. 이 경우 각각의 함수는 응용프로그램의응용 프로그램의 요청에 따라 커널에서 실행된다.
 
* 응용 프로그램 예
: 권한수준 사용자 공간(user space, x86 링3, ARM 사용자 모드(User Mode))에서 실행.
: 응용프로그램에서의응용 프로그램에서의 리눅스 커널의 디바이스장치 드라이버 호출.
 
<source lang="cpp">
66번째 줄:
</source>
 
응용프로그램은응용 프로그램은 CPU의 권한수준이 사용자 공간에서 실행되므로 커널 공간이 필요한 하드웨어 제어를 할 수 없으므로 위와 같이 커널의 디바이스에서장치에서 넣어 하드웨어 제어를 한다.
 
다음과 같은 절차로 응용프로그램응용 프로그램 함수가 커널의 함수와 연결된다:
# 응용프로그램에서응용 프로그램에서 open(...) 함수를 실행하면 libc에서 제공한 open 함수속에서 인수 데이터를 레지스터에 넣고 소프트웨어 [[인터럽트]]를 실행한다.
# 소프트웨어 인터럽트에 의해 ISR(Interrupt Service Routine)이 있는 커널의 인터럽트 처리 위치를 찾아 해당 주소로 실행을 옮긴다. 이때 CPU은 권한수준이 최고수준의 실행모드가 된다. CPU의 인터럽트 메카니즘에 의해 자동변환 된다.
# 많은 시스템 호출 함수중에 해당 인터럽트 벡터숫자를 이용해 함수의 위치를 탐색하고 해당주소로 점프한다. 커널 속의 디바이스장치 목록에서 해당 디바이스를장치를 찾고 드라이버의 함수 '''.open'''에서 정의된 '''mydrv_open'''(...)가 호출된다.
# mydrv_open()함수의 '''return'''에 따라 커널의 함수 호출이 완료되고, 커널은 다시 해당 응용프로그램을응용 프로그램을 스케쥴링에 의해 활성화하고 해당 [[프로세서]]로 전환한다. 이 때 CPU의 권한수준은 다시 사용자모드로 전환된다.
 
만약 write함수나 read 함수의 호출에 의해, 커널의 함수가 호출된 후 return에 의해 종료되지 않으면 응용프로그램은응용 프로그램은 스케쥴링에서 빠져 커널의 상태에서 머물면서 블럭킹 현상이 발생한다. 해당 드라이버의 인터럽트 등으로 블럭킹을 해제할 수 있다.
 
== 같이 보기 ==