应用程序首先用适当的值填充到寄存器中,然后调用一个特殊的指令跳转到内核的固定的位置,内核根据应用程序填充的固定的值来找到相应的函数执行。
比如像如下程序:
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)
/* 7 was sys_waitpid */
#define __NR_creat(__NR_SYSCALL_BASE+ 8)
2)特殊的指令
a)在inter Cpu中,这个指令由中断0X80实现
b)在ARM中,这个指令是SWI
3)固定的位置
在ARM体系中,应用程序跳转到的固定内核位置是ENTRY(vector_swi)<entry-common.s>
4)相应的函数
内核根据应用程序传递来的系统调用号,从系统调用表sys_call_table找相应的内核函数。
CALL(sys_exit)
我们现在知道了其工作原理,下面我们就来添加一个我们自己的的系统API
1)添加新的内核函数(kernel\sys.c)
asmlinkage int sys_add(int a,int b)
{
return a +b;
}
// asmlinkage:使用堆栈传递参数
2)更新头文件unistd.h,添加我们的系统调用号
#define __NR_add(__NR_SYSCALL_BASE+ 361)
3)跟新系统调用表(kernel/call.s)
CALL(sys_add)
测试程序:
#include<stdio.h>
#include<unistd.h>
int main()
{
int result;
result = syscall(361,1,2);
printf(“%d\n”,result);
}
人生没有彩排,只有现场直播,所以每一件事都要努力做得最好