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.系统调用必须被编译进内核映像(不能编译为模块)
#建立新的系统调用的利与弊:
利:#系统调用创建easy且使用方便
#Linux系统调用高性能
弊:#须要一个系统调用号,由官方分配
#系统调用增加稳定内核后被固化,它的接口不同意修改
#须要将系统调用分别注冊到每一个须要支持的结构体系去
#在脚本中不easy调用。也不能从文件系统直接訪问系统调用
#在主内核树之外非常难维护和调用系统调用