linux系统调用
Linux内核中,设置了一组用于实现各种系统功能的函数------系统调用
Linux下对文件操作有两种方式:系统调用(system call)和普通函数调用。
Linux系统调用VS普通函数调用
系统调用由操作系统内核实现,运行于内核态。普通函数调用由函数库或用户自己提供。
库函数fread()对系统调用做了一定的封装。
工作原理概述:
void main()
{
creat(("testfile",0666) < 0);
}
<1>、把适当的值填充寄存器(include/asm/unistd.h)中为每一个系统调用规定了唯一的编号。
#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
#define __NR_exit (__NR_SYSCALL_BASE+ 1)
#define __NR_fork (__NR_SYSCALL_BASE+ 2)
#define __NR_read (__NR_SYSCALL_BASE+ 3)
#define __NR_write (__NR_SYSCALL_BASE+ 4)
#define __NR_open (__NR_SYSCALL_BASE+ 5)
#define __NR_close (__NR_SYSCALL_BASE+ 6)
<2>、特殊的指令
在Intel的CPU 中,由INT 0x80实现。
在ARM中,有指令SVC(以前用SWI)指令,软中断指令进入某一固定的内核资源。
<3>、固定位置
ARM中是通过ENTRY(vector_swi)
ENTRY(vector_swi)
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0 - r12
ARM( add r8, sp, #S_PC )
ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr
THUMB( mov r8, sp )
THUMB( store_user_sp_lr r8, r10, S_SP ) @ calling sp, lr
mrs r8, spsr @ called from non-FIQ mode, so ok.
str lr, [sp, #S_PC] @ Save calling PC
str r8, [sp, #S_PSR] @ Save CPSR
str r0, [sp, #S_OLD_R0] @ Save OLD_R0
zero_fp
<4>、相应的函数
内核根据应用程序传递来的系统调用号,从系统调用表sys_call_table找到相应的内核函数。(calls.S)
/* 0 */ CALL(sys_restart_syscall)
CALL(sys_exit)
CALL(sys_fork_wrapper)
CALL(sys_read)
CALL(sys_write)
/* 5 */ CALL(sys_open)
CALL(sys_close)
CALL(sys_ni_syscall) /* was sys_waitpid */
CALL(sys_creat)
CALL(sys_link)
实现内核调用:向内核中添加新得到系统调用,3个步骤:
<1>、添加新的内核函数
<2>更新头文件unistd.h
<3>针对这个新函数更新系统调用表calls.S
<4>、编写应用程序测试