首页 > 代码库 > Linux内核-系统调用
Linux内核-系统调用
Linux内核-系统调用
1.与内核通信
#系统调用在用户空间进程和硬件设备之间增加了一个中间层
作用:1.为用户空间提供了一种硬件的抽象接口
2.系统调用保证了系统的稳定和安全
3.出于每个进程都运行在虚拟系统中的考虑
#系统调用是用户空间访问内核的唯一手段
2.API、POSIX和C库
#应用程序通过API而不是直接系统调用来编程
#一个API定义了一组应用程序使用的编程接口
3.系统调用
#内核必需提供系统调用所希望完成的功能,但它完全可以按照自己的方式去实现,只要最后结果正确
#所有的系统调用都要asmlinkage限定词
#为保证32/64位兼容,系统调用在用户空间返回值时int,内核空间为long
1.系统调用号:
#在Linux中每个系统调用被赋予一个系统调用号
#系统调用号一旦分配不可改变,否则编译好的应用会崩溃
#Linux上有一个“未实现”的系统调用sys_ni_syscall(),它除了返回-ENOSYS外不做其他任何工作
如果一个系统调用被删除,或变的不可用,这个函数去填补空缺
2.系统调用的性能
#Linux系统调用比其他操作系统要快,原因:
1.Linux很短的上下文切换时间
2.系统调用处理程序和每个系统调用非常简洁
4.系统调用处理程序
#通知内核的机制靠软中断实现,通过引发异常来促使系统切换到内核态去执行异常处理程序(系统调用处理程序)
#指定恰当的系统调用:
在x86上通过eax寄存器将系统调用号传递给内核
system_call()函数通过将给定的系统调用号与NR_syscalls()作比较来检查其有效性
#参数传递:在x86-32系统上,ebx,ecx,edx,esi,edi按照顺序存放前五个参数
给用户空间的返回值通过eax寄存器传递(x86)
5.系统调用的实现
#实现系统调用:
每个系统调用都有一个明确的用途
系统调用的接口力求简洁,参数尽可能少
设计接口的时候要尽量为将来多做考虑
#参数验证:
#系统调用必须验证他们所有的参数是否合法有效,最重要的检查时检查用户提供的指针是否有效
#在接受一个用户空间的指针之前,内核必须保证:
1.指针指向的内存区域属于用户空间,进程决不能让内核去读取内核空间的数据
2.指针指向的内存区域在进程的地址空间,进程决不能让内核去读取其他进程的数据
3.如果是读,内存标记为可读;如果是写,标记为可写;如果标记为可执行,进程决不能绕过内存访问限制
6.系统调用上下文
#绑定一个系统调用的最后步骤:
1.首先,在系统调用表的最后加入一个表项
2.系统调用号定义于<asm/unistd.h>中
3.系统调用必须被编译进内核映像(不能编译为模块)
#建立新的系统调用的利与弊:
利:#系统调用创建容易且使用方便
#Linux系统调用高性能
弊:#需要一个系统调用号,由官方分配
#系统调用加入稳定内核后被固化,它的接口不允许改动
#需要将系统调用分别注册到每个需要支持的结构体系去
#在脚本中不容易调用,也不能从文件系统直接访问系统调用
#在主内核树之外很难维护和调用系统调用
Linux内核-系统调用