230 likes | 576 Views
Linux Kernel 수업 3 번째. System Call. 목 차. System call 처리 과정 System call 추가 실습 파라미터를 이용한 시스템 콜 실습 구조체를 이용한 시스템 콜 실습. System call. Libraries (ex: C Runtime Library). User Program & Application. User Level. System Call Interface (X86 Interface 0x80). Kernel Level. Memory Management.
E N D
Linux Kernel 수업 3번째 System Call
목 차 • System call 처리 과정 • System call 추가 실습 • 파라미터를 이용한 시스템 콜 실습 • 구조체를 이용한 시스템 콜 실습 OS2 강의교재
System call Libraries (ex: C Runtime Library) User Program & Application User Level System Call Interface (X86 Interface 0x80) Kernel Level Memory Management Virtual File System (VFS) Process Management Buffer Char Block Device Driver Kernel Level Hardware Control Hardware Control H/W Level OS2 강의교재
System call 처리과정 • 시스템 콜 흐름의 예 1. 사용자 프로세스에서 시스템 콜 사용 2. Libc.a Argument stack에 넣음 시스템 콜 번호 저장 트랩발생 3. system_call() IDT 에 의해 트랩 시작 sys_call_table 사용 핸들러 실행 4. 시스템 콜 핸들러 함수 시스템 콜 핸들러 함수는 256개 까지 가능(커널 2.4.20) OS2 강의교재
IDT 0x00 devide_error(); Debug(); Nmi(); ... System_call(); ... 0x80 sys_call_table 1 2 3 4 .. sys_exit(); sys_fork(); sys_read(); sys_write(); ... System call 처리과정 • fork system call의 흐름 ENTRY(system_call) /* arch/i386/kernel/entry.S */ SAVE_ALL … Call *SYMBOL_NAME(sys_call_table) (, %eax, 4) …ret_from_sys_call(schedule, signal, bh_active, nested interrupt handling) user task main() { ..// fork(); ... } libc.c ... fork() { ... movl 2, %eax int $0x80 …} ... sys_fork(); /* kernel/fork.c */ OS2 강의교재
IDT(interrupt Descriptor Table) • I386에서는 IDT를 통해 모든 인터럽트가 관리 • 시스템 콜은 0x80번의 인터럽트를 사용 OS2 강의교재
파일 구성 • 모든 시스템 콜 번호는 /include/asm/unistd.h 에 정의 • 시스템 콜 테이블은 /arch/i386/entry.S에 정의 #define __NR_exit 1 #define __NR_fork 2 #define __NR_read 3 ... #define __NR_sched_getaffinity 242 .long SYMBOL_NAME(sys_ni_syscall) .long SYMBOL_NAME(sys_exit) .long SYMBOL_NAME(sys_fork) .long SYMBOL_NAME(sys_read) ... .long SYMBOL_NAME(sys_getaffinity) OS2 강의교재
실 습 • 시스템 콜 추가 • syscall_number할당 • linux/include/asm/unistd.h 에 정의 • 맵핑 테이블 등록(sys_call_table) • arch/i386/entry.S에 시스템 콜 테이블 등록 • new system call 함수를 커널에 작성 • /kernel 디렉토리에 newcall.c 를 작성 • 커널 재 컴파일 • 새로 추가한 system call을 사용해 applicatioin 작성 • 시스템 콜이 추가된 커널로 부팅하여 응용 프로그램을 작성 OS2 강의교재
실 습 • 시스템 콜 추가 • linux/include/asm/unistd.h 을 편집 • ‘#define __NR_newcall 253’ 을 추가 OS2 강의교재
실 습 • arch/i386/kernel/entry.S 을 편집해서 시스템콜 테이블 등록 • .long SYMBOL_NAME(sys_newcall) 을 추가 OS2 강의교재
실 습 • /kernel 디렉토리에 newcall.c 를 작성 OS2 강의교재
실 습 • /kernel 디렉터리에 /kernel/Makefile 을 편집 • newcall.o 를 추가 • 커널 컴파일 시에 자동으로 목적 파일을 생성함 OS2 강의교재
실 습 • 커널 재컴파일 • 앞장 참조 • 새로 컴파일한 커널을 부트로더에 등록 • 리부팅 후 새로 컴파일한 커널로 부팅 OS2 강의교재
실 습 • 새로운 시스템 콜(253번)을 사용할 프로그램 test.c 파일 작성 • 시스템 콜의 사용을 위한 stub 작성이 필요함 • _syscall0(type,name)은 인자가 없음을 의미 ( type:함수리턴형 , name:함수이름 ) • _syscall1(type,name,type1,type_name)형식 지정한 type1 변수는 ebx cpu범용레지스터에 들어감 • 인자가 2개면 _syscall2,.. • unistd.h에는 인자 6까지 변환하는 매크로 존재. OS2 강의교재
실 습 • 파일 작성후 컴파일시 에러 • 개발 커널에서의 unistd.h 불일치 수정 OS2 강의교재
실 습 • Application 실행 • dmesg 명령어를 사용하면 Hello Kernel 메세지를 볼 수 있음 OS2 강의교재
파라미터를 전달하는 시스템 콜 • 커널 영역과 유저 영역 사이에 값을 교환하는 Kernel API • put_user(x, ptr) • 유저영역으로 값 하나를 복사함 • get_user(x, ptr) • 유저영역에서 값 하나를 받아옴 • copy_to_user(void __user * to, const void * from, unsigned long n) • 유저영역으로 블록데이터를 복사 • copy_from_user(void * to, const void __user * from, unsigned long n) • 유저영역에서 블록데이터를 받아옴 OS2 강의교재
실 습 • kernel/newcall.c 를 편집 OS2 강의교재
실 습 • 커널 컴파일 후 응용 프로그램 수정 파라메터가 3개이므로 _syscall3을 이용 내부 선언되는 개수는 8개가 됨. OS2 강의교재
구조체를 사용한 시스템 콜 • newcall.c 편집 OS2 강의교재
실 습 • 커널 컴파일 후, 응용 프로그램 수정 OS2 강의교재