Linux下的系统调用的原理

应用程序首先用适当的值填充到寄存器中,然后调用一个特殊的指令跳转到内核的固定的位置,内核根据应用程序填充的固定的值来找到相应的函数执行。

比如像如下程序:

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);

}

人生没有彩排,只有现场直播,所以每一件事都要努力做得最好

Linux下的系统调用的原理

相关文章:

你感兴趣的文章:

标签云: