系统调用 syscall

系统调用(syscall”)是用户级程序要求操作系统为它做某些事情的途径。
所有的系统调用都需要asmlinkage限定词。asmlinkage限定词用于通知编译器进从栈中提取该函数的参数。
在Linux中,每个系统调用被赋予一个系统调用号,这样,通过这个独一无二的号就可以关联系统调用,而不是系统调用的名称。系统调用号相当关键,一旦分配就不能再有任何变更,否则编译好的应用程序就会崩溃。
Linux有一个“未实现”系统调用sys_ni_syscall(),它除了返回-ENOSYS外不做任何其他工作,这个错误号就是专门针对无效的系统调用而设的。如果一个系统调用被删除或是不可用,这个函数就负责“填补空位”。
内核记录了系统调用表中的所有已注册过的系统调用的列表,存储在sys_call_table中。

powerpc 32位的系统调用处理程序是DoSyscall,定义在在arch/powerpc/kernel/head_32.S

/* System call */
    . = 0xc00
SystemCall:
    EXCEPTION_PROLOG
    EXC_XFER_EE_LITE(0xc00, DoSyscall)

EXCEPTION_PROLOG 是一个宏,负责从用户空间到内核空间的切换,这需要保存用户进程的寄存器状态。使用此例程的地址和函数 DoSyscall

的地址来调用 EXC_XFER_EE_LITE。最后,某些状态将会被保存,DoSyscall 将会被调用。DoSyscall函数最终使用系统调用号将系统调用表的地址和索引加载到它。DoSyscall 找到正确的系统调用地址后,它将控制权转交给那个系统调用。

powerpc 64位的系统调用处理程序是system_call_common定义在在arch/powerpc/kernel/head_64.S

如何新增一个系统调用?

以Powerpc平台为例:

首先在相应的unistd.h文件里定义好系统调用号,该系统调用号是未被使用的。
#define _NR_mycall 356
修改__NR_syscalls的值,-表示原来的值,+表示重新定义的值。
-#define __NR_syscalls          356
+#define __NR_syscalls          357

在kernel/sys.c定义系统调用。
SYSCALL_DEFINE1(mycall, unsigned int, len)
{
    ...
}

宏SYSCALL_DEFINEn,其中n是从1到6,代表传递给系统调用的参数个数,第一个参数是系统调用的名称,后面的参数是按照系统调用参数的顺

序排列的每个参数的类型和名称。
在相应的systbl.h文件把系统调用号添加到系统调用表中。具体操作如下:
SYSCALL(get_cpu_clock)


系统调用的优缺点

建立一个新的系统调用的好处:
系统调用创建容易且使用方便。
Linux系统调用的高性能显而易见。
问题是:
你需要一个系统调用号。系统调用被加入文档内核后就被固化了,为了避免应用程序的崩溃,它不允许做改动。
需要将系统调用分别注册到每个需要支持的体系结构中去。
在脚本中不容易调用系统调用,也不能从文件系统直接访问系统调用。
如果仅仅进行简单的信息交换,系统调用就大材小用了。
替代方法:
创建一个设备节点,通过read()和write()访问它。用ioctl进行特别的设置操作和获取特别信息。
一些接口如信号量,可以用文件描述符表示以进行操作。

把增加的信息作为一个文件放在sysfs的合适位置。


参考文档:

《Linux内核设计与实现》

理解Linux的系统调用  http://os.51cto.com/art/200512/13510.htm


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值