转载请注明出处:jiq?钦‘s
technical Blog
什么是系统调用?
系统调用——内核和用户应用程序的桥梁,中间人。
系统调用就是内核实现的一系列函数,这些函数提供了一套固定的接口,通过这套接口,用户程序可以访问系统硬件和操作系统的资源,即内核提供的服务。
为什么提供系统调用?
用户空间只能通过系统调用来访问内核提供的服务的根本原因是为了对系统进行“保护”,因为我们知道Linux的运行空间分为内核空间与用户空间,它们各自运行在不同的级别中,逻辑上相互隔离。用户进程在通常情况下不允许随意访问内核资源。
(1) 系统调用和POSIX:
虽然系统调用是内核和用户应用程序之间的桥梁,是用户程序访问内核的入口点,但是通常用户应用程序却是通过“操作系统提供的应用程序编程接口(API)”而不是直接通过系统调用来编程的。
而Unix系统里面的这个所谓的操作系统提供的API就是POSIX,即是Portable
Operating SystemInterface of Unix,可移植操作系统接口。
(2) 系统调用与C库:
操作系统API就是以C库形式提供的,或者说C库提供了POSIX大部分的API。而C库主要是调用内核提供的系统调用实现的。所以可以说POSIX主要是通过调用内核提供的系统调用实现的。
POSIX IN UNIX C库构建在内核之上,由内核实现,但是也有其他一些C库是平台无关的。
(1)Linux中的系统调用是如何工作的呢?要知道在用户空间里面可不能直接执行内核代码!!!
答案是使用软中断:通过软中断引发一个异常,促使系统切换到内核态执行异常处理程序。这个异常处理程序被指定为“系统调用处理程序”,此时在“系统调用处理程序”中便可以执行系统调用了(此时已经陷到内核空间中)。
(2)但是调用哪个系统调用呢?
答案是Linux中每一个系统调用都对应一个唯一的“系统调用号”:陷入内核之前用户空间就把这个号放在寄存器中了,执行“系统调用处理程序”的时候只需要调用这个号码对应的系统调用即可。
(3)系统调用上下文:
不同于中断上下文,内核在执行系统调用的时候是处于“进程上下文”,也就是说(1)可以休眠;(2)可以被抢占;
此时current指向当前任务,也就是引发系统调用那个任务。
(4)有哪些系统调用?
系统调用宏定义文件:
http://lxr.linux.no/linux+v2.6.30/arch/arm/include/asm/unistd.h
这些系统调用按照功能逻辑大致可分为“进程控制”、“文件系统控制”、“系统控制”、“存储管理”、“网络管理”、“socket控制”、“用户管理”、“进程间通信”等几类
源文档 <http://www.kerneltravel.net/journal/iv/syscall.htm>
系统调用列表:
http://www.ibm.com/developerworks/cn/linux/kernel/syscall/part1/appendix.html
这里大概列出一些主要的:
一、进程控制:
fork |
创建一个新进程 |
clone |
按指定条件创建子进程 |
execve |
运行可执行文件 |
exit |
中止进程 |
pause |
挂起进程,等待信号 |
sched_yield |
进程主动让出处理器,并将自己等候调度队列队尾 |
vfork |
创建一个子进程,以供执行新程序,常与execve等同时使用 |
wait |
等待子进程终止 |
二、文件系统控制
1、文件读写操作
fcntl |
文件控制 |
open |
打开文件 |
creat |
创建新文件 |
close |
关闭文件描述字 |
read |
读文件 |
write |
写文件 |
umask |
设置文件权限掩码 |
2、文件系统操作
access |
确定文件的可存取性 |
chdir |
改变当前工作目录 |
chmod |
改变文件方式 |
chown |
改变文件的属主或用户组 |
mkdir |
创建目录 |
mknod |
创建索引节点 |
rmdir |
删除目录 |
rename |
文件改名 |
三、系统控制
ioctl |
I/O总控制函数 |
uname |
获取当前UNIX系统的名称、版本和主机等信息 |
create_module |
创建可装载的模块项 |
delete_module |
删除可装载的模块项 |
init_module |
初始化模块 |
四、内存管理
brk |
改变数据段空间的分配 |
mmap |
映射虚拟内存页 |
五、网络管理
getdomainname |
取域名 |
setdomainname |
设置域名 |
gethostname |
获取本主机名称 |
sethostname |
设置主机名称 |
六、socket控制
socketcall |
socket系统调用 |
socket |
建立socket |
bind |
绑定socket到端口 |
connect |
连接远程主机 |
accept |
响应socket连接请求 |
send |
通过socket发送信息 |
sendto |
发送UDP信息 |
recv |
通过socket接收信息 |
recvfrom |
接收UDP信息 |
listen |
监听socket端口 |
select |
对多路同步I/O进行轮询 |
七、用户管理
getuid |
获取用户标识号 |
setuid |
设置用户标志号 |
getgid |
获取组标识号 |
setgid |
设置组标志号 |
八、进程间通信
ipc |
进程间通信总控制调用 |
1、信号
sigaction |
设置对指定信号的处理方法 |
sigprocmask |
根据参数对信号集中的信号执行阻塞/解除阻塞等操作 |
sigpending |
为指定的被阻塞信号设置队列 |
sigsuspend |
挂起进程等待特定信号 |
signal |
参见signal |
kill |
向进程或进程组发信号 |
2、消息
msgctl |
消息控制操作 |
msgget |
获取消息队列 |
msgsnd |
发消息 |
msgrcv |
取消息 |
3、管道
pipe |
创建管道 |
4、信号量
semctl |
信号量控制 |
semget |
获取一组信号量 |
semop |
信号量操作 |
5、共享内存
shmctl |
控制共享内存 |
shmget |
获取共享内存 |