티스토리 뷰

시스템 콜?

정의

시스템 콜은 응용프로그램에서 운영체제에게 기능(시스템 자원)을 수행해달라고 하는 하나의 수단이다. 


효과

저수준 프로그래밍을 몰라도 되므로 프로그래밍이 쉬워지며, 프로그램 호환성이 좋아진다. 

사용자 요청을 처리하기전에 인터페이스 수준에서 올바른 요청인지 검사할 수 있으므로 시스템의 보완성이 높아진다.


시스템콜의 이해

사용자프로세서가 소프트웨어 인터럽트를 통해 커널의 기능을 이용하기 위한 서비스를 요청하는 하나의 방법이다.


처리방식 

사용자 프로세서가 시스템콜을 요청하면 제어가 커널로 넘어간다. (사용자모드 -> 커널모드) 

커널은 내부적으로 각각의 시스템콜을 구분하기 위해 기능별로 고유번호를 할당해 놓는다. 

해당번호는 커널내부에 제어루틴을 정의한다.


커널은 요청받은 싯템 콜에 대응하는 기능번호를 확인한다.


커널은 그 번호에 맞는 서비스 루틴을 호출하게 된다.


서비스 루틴을 모두 처리하고나면 커널 모드에서 사용자 모드로 다시 넘어온다.


시스템콜의 종류 

프로세서 제어

파일조작

장치관리

시스템 정보 및 자원관리

통신 관련


시스템콜의 초기화는 시스템 부팅시 커널초기화 과정에서 trap_init()함수내의 set_system_date(SYSCALL_VECTOR, &system_call)을 수행해서 0x80인터럽트를 위한 게이트 디스크립터를 설정한다.

SYSCALL_VECTOR : 0x80로 정의된 상수 

&system_call :  시스템콜을 위한 핸들러 주소 


시스템콜 처리과정 

시스템콜은 소프트웨어 인터럽트이다.


사용자 프로세서 에서 fork()시스템콜을 호출한다고 가정한다,.

1. C라이브러리 (libc.a)에서 fork()시스탬콜의 고우번호인 '2'를 eax레지스터에 저장하고 0x80인터럽트를 발생한다.

2. 커널은 IDT에서 0x80 주소에 있는system_call()을 찾는다.

//system_call()는 arch/sparc/kernel/entry.S에 구현되있다.

3. system_call()함수에서는 호출된 시스템콜 번호와 모든 레지스터를 스택에 저장하고 올바른 시스템콜 번호인지 검사후 sys_calll_table[시스템콜테이블]에서 시스템콜 번호에 해당하는 함수를 호출한다.

4.이 함수가 종룔 하면 entry.S에 정의되어 있는 ret_from_sys_call()함수에 의해 사용자 프로세서로 돌아간다. 


IDT(Interrupt Descriptor Table)테이

리눅스는 인터럽트 처리를 위해 IDT를 사용한다. 

각 인터럽트를 처리하기 위한 서비스 루틴을 함수로 구현해두고, 각 함수의 시작점 주소(핸들러함수)를 IDT에 등록 [트랩과 시스템콜도 들어 있다.]

IDT는 메모리에 위한다, 이 IDT의 위치를 가리키는 레지스터를 IDTR이라 한다.


인터ㄹ버트발생 >> IDTR을 통해 IDT를 알아냄 >> 인터럽트 번호에 대응되는 테이블 엔트리에서 핸들러를 찾아서 이 루틴에 정의된 내용을 처리한다. 


IDT는 총 256개의 엔트리를 가진다. (각 엔트리는 8Byte크기의 디스크립터로 구성되었다.) 256 * 8 2048byte가 필요하다.


커널 내부의 인터럽트 수행과정 

인터럽트 >> 실행중인 프로세스 중지 >> 커널모드 전환 >> do_IRQ() 함수 호출 >> PIC에게 응답신호 보낸다. >> 실제 핸들러 함수를 호출 >> 뒤로 미뤄진 softirq가 있으면 처리 >> do_IRQ()함수가 종료되면 ret_from_intr 주로로 복귀 >> 다시 사용자 모드로 전환한다. 


do_IRQ()함수 : 인터럽트에 연관된 모든 인터럽트 서비스 루틴을 실행하기 위해 호출하는 함수 

PIC : 인터럽트 도중 같은 종류의 인터럽트 발생을 막는다. 


PIC에게 응답신호를 보낸루 실제 핸들러 함수를 호출하는 세부과정 

응답신호를 보낸다. 

handle_IRQ_event()함수가 호출된다. 

hanbler(irq.action->dev_id.regs)호출 중에 실제 핸들러 함수를 호출한다. 


커널코드 수정 순서 

1. 시스템 콜 번호 할당 

2. 시스템 콜 테이블 등록

3. 새로운 시스템 콜 작성 

4. 커널 재 컴파일 & 업로드 

5. 추가된 시스템 콜 사용 응용 프로그램 작성

구체적 구현방법 (x86의 경우)

1. 시스템 콜 번호 할당 

경로 : include/asm-i386/unist.h

#define __NR_inotify_add_watch 292

#define __NR_inotify_rm_watch 293

#define __NR_xxx 294            // 새로운 시스템 콜 이름과 번호를 할당 

#define NR_syscalls 295        // 전체 시스템 콜 객수 수정 (마지막 번호 +1)


// 기존에 정의된 시스템 콜 번호 아래에 새로운 시스템 콜 번호를 할당 해야된다. 시스템 콜 이름은 자유지만 할당 번호는 마지막 할당 번호의 다음 번호가 되어야한다. 그리고 전체 시스템 콜 갯수의 경우 마지막 번호 +1이 되어야 한다. 


2 시스템 콜 테이블 등록 

경로 :   2.6버전 > arch/i386/kernel/syscall_table.S

2.4버전 > arch/i386/kernel/entry.S

Entry(sys_call_tabel)

.long sys_inotify_add_watch

.long sys_inotify_rm_watch

.long sys_xxx     // 시스템 콜 추가 


// 응용 프로그램에서 시스템 콜을 호출하면 번호를 보고, 시스템 콜에서 해당 함수가 호출된다.(내부적으로 eax레지스터에 시스템 콜 번호가 저장<moc eax, [시스템콜 번호]>되고, 시스템 콜 인터럽트가 발생 <int 0x80>한다.) 그러므로 시스템 콜 테이블에 등록이 반그시 필요하다. 당연히 sys_뒤에 이름은 앞에서 시스템 번호 할당 시 등록한 __NR_뒤의 이름과 일치해서 등록한다.


3. 새로운 시스템 콜 작성

경로 : /kernel/

#include <lniux/kernel>

/* xxx.c */

#include <linux/kernel.h>

asmlinkage int sys_xxx()

{

return [return value];

}

지정된 경로에서 시스템 콜 데이블에 등록된 동일한 이름의 함수를 작성한다. 그 이후에 Makefile를 수정하여 작성한 파일이 오브젝트 파일로 생성 하도록한다.

4. Makefile 수정 

경로 : kernel/Makefle

obj -y = ...objectflie...\

....................................\

....... xxx.o    //작성한 시스템 콜 함수의 오브젝트 생성을 위해 컴파일 추가


5. 구동방법 
syscall(시스템콜 번호, 인자1, 인자2, .... 인자3)

// 하드웨어 별로 넘길수 있는 인자의 숫자가 한계가 정해져 있다. 주위할것.

http://man7.org/linux/man-pages/man2/syscall.2.html

'Linux' 카테고리의 다른 글

[Linux] Process  (0) 2014.01.22
[Linux] fork, vfork 그리고 posix_spawn 이야기  (0) 2014.01.22
[Linux] GRUB 정의 & 예제  (0) 2014.01.04
[Linux] RT-Linux (추상적 단계 정리)  (0) 2014.01.04
RTLinux (FSM Labs 2001)  (0) 2013.07.29
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함