Chinaunix首页 | 论坛 | 博客
  • 博客访问: 77341
  • 博文数量: 11
  • 博客积分: 140
  • 博客等级: 入伍新兵
  • 技术积分: 208
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-22 00:51
个人简介

天外有天,人外有人。

文章分类

全部博文(11)

文章存档

2013年(10)

2012年(1)

我的朋友

分类: LINUX

2013-09-04 22:36:44

系统调用通过软中断0x80来使系统切换到内核态执行第0x80号中断服务程序,中断则定义有entry.S:

ENTRY(system_call)

            cmpl $(nr_syscalls), %eax     #eax寄存器中放的是系统调用号,判断是否为有效系统调用号

            jae syscall_badsys

syscall_call:

            call*sys_call_table(,%eax,4)  #sys_call_tablesyscall_tables.S中定义的#///系统调用表(数组)的起始地址,4table中各项占用字节数

 

2.4相关文件:

Arch/kernel/entry.S   定义ENTRY(sys_call_table)

Include/Linux/Sys.h   #define NR_syscalls 256规定了syscalls的最大个数

2.6相关文件:

为了更增可读性,2.6中将原位于entry.S中的ENTRY(sys_call_table)拿出来单独放在Arch/kernel/syscall_tables.S 中,不过也includeentry.S中了。2.6.15内核有294.

Arch/kernel/entry.S中计算系统调用表的大小的方法:

#include "syscall_table.S" //定义系统调用表

syscall_table_size=(.-sys_call_table)

 

相同点: 实现机制上没有太大的区别。内核在执行系统调用时处于进程上下文,current指向系统调用的那个进程。

 

例:(内核中现成的)

1.      arch/kernel/syscall_table.S 系统表中加入相应表项         .long sys_getpid  /*20*/

2.      include/asm/unistd.h      中加入系统调用号         #define __NR_getpid                       20

3.      系统调用代码实现:

asmlinkage long sys_getpid(void)

{

return current->tgid;

}

4.一般系统调用由glibc提供支持,用户通过头文件和glibc库链接实现。也可以用_syscallN(…)宏来实现,其中N0-6,代表参数个数,在使用调用前声明该宏(从宏的定义中可以看出其作用)

#define _syscall0(type,name) \  //其实就是定义一个ox80号中断

type name(void) \

{ \

long __res; \

__asm__ volatile ("int $0x80" \

            : "=a" (__res) \

            : "0" (__NR_##name)); \    //参数,类似__NR_getpid这样的系统调用号

__syscall_return(type,__res); \ //errno

}

 

注意,系统调用不能随便更改,否则许多原有程序可能无法使用。
阅读(1482) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~