贝博betball网页提供了一组接口让应用程序受限的访问硬件设备
与贝博betball网页通信
系统调用在用户空间进程和硬件设备之间提供了一个中间层,实现了
硬件抽象接口
保证系统稳定和安全
实现虚拟系统,给进程一种独享CPU和内存的感觉
编程接口一般都是基于POSIX标准的,是一套大体上基于Unix的可移植操作系统标准。
系统调用
访问系统调用(syscall)通常通过C库定义的函数调用来进行
系统调用在用户空间和贝博betball网页空间有不同的返回类型,用户空间为int,贝博betball网页空间为long(保证32位与64位系统兼容)
每个系统调用都有一个系统调用号,可以关联具体哪一个系统调用。
进程不会提及系统调用的名称而是通过系统调用号来表示。
系统调用号一旦被分配不会再有变更,否则编译好的程序将会崩溃。
如果一个系统调用被删除,其所占用的系统调用号不允许被回收利用。
linux有一个“未实现”的系统调用sys_ni_syscall(),仅仅返回-ENOSYS,专门针对无效的系统调用而设置。
贝博betball网页记录了系统调用表中的所有已注册的系统调用列表,存储于sys_call_table中,每一种体系结构中都明确定义了这个表。
系统调用的处理
用户空间的程序无法直接执行贝博betball网页代码,也不能调用贝博betball网页空间的函数。应用程序通过软中断实现通知机制,通过引发一个异常来促使系统切换到贝博betball网页态并执行调用。
如在x86系统上,软中断终端号为128,通过int $0x80指令触发该中断后会使系统切换到贝博betball网页态并执行128号异常处理程序system_call()。他与硬件体系结构紧密相关。
最新的x86处理器增加了sysenter指令,实现了更快的进入贝博betball网页执行系统调用的方式
x86上系统调用号通过eax寄存器传递给贝博betball网页,陷入贝博betball网页之前用户空间就把相应系统调用好放入exa中。system_call函数中将给定的系统调用号与NR_syscalls进行比较,如果大于等于则返回-ENOSYS,否则执行
64位系统:call *sys_call_table(,%rax,8)
32位系统:call *sys_call_table(,%rax,4) 

除了系统调用号以外还需要传输一些外部的参数输入,x86-32上提供了5个寄存器ebx,ecx,edx,esi,edi 需要5个以上参数的情况不多见。
数据返回通过eax寄存器传回
实现系统调用的过程中,linux不提倡通过传递参数来实现多用途的系统调用,传递参数多是需要对系统调用进行改变而向后兼容所设计。
贝博betball网页必须对所有参数进行检查合法性
IO操作的文件描述符是否有效
进程操作相关的PID是否有效
指针传递过程中
如果内存区域属于用户空间,禁止读贝博betball网页空间数据
如果在进程的地址空间,禁止读其他进程
对读、写、执行设置相应的标记,进程不能绕过内存访问限制。
copy_to_user()和copy_from_user()实现了贝博betball网页和用户空间的互相拷贝数据
当包含用户数据的页被换出到硬盘而不是物理内存时,这两个函数都有可能引起阻塞。此时进程就会休眠,直到缺页处理程序将该页从硬盘重新换回物理内存。
权限检查
老版本的linux贝博betball网页中需要超级用户权限的调用通过suser()函数来进行检查用户是否为超级用户。
现在被一个更细粒度的“权能”机制代替,调用者使用capable()函数来检查是否有权能对指定的资源进行操作。
编写完一个系统调用后,需要将系统调用编译入贝博betball网页映像(放入kernel/下的一个相关文件中)
entry.s中包含了系统调用表,需要将新的系统调用加到该表的末尾(系统调用号依次分配)