linux syscall详细介绍.doc
《linux syscall详细介绍.doc》由会员分享,可在线阅读,更多相关《linux syscall详细介绍.doc(9页珍藏版)》请在三一文库上搜索。
1、linux syscall详细介绍一、Syscall意义内核提供用户空间程序与内核空间进行交互的一套标准接口,这些接口让用户态程序能受限访问硬件设备,比如申请系统资源,操作设备读写,创建新进程等。用户空间发生请求,内核空间负责执行,这些接口便是用户空间和内核空间共同识别的桥梁,这里提到两个字“受限”,是由于为了保证内核稳定性,而不能让用户空间程序随意更改系统,必须是内核对外开放的且满足权限的程序才能调用相应接口。在用户空间和内核空间之间,有一个叫做Syscall(系统调用, system call)的中间层,是连接用户态和内核态的桥梁。这样即提高了内核的安全型,也便于移植,只需实现同一套接口即
2、可。Linux系统,用户空间通过向内核空间发出Syscall,产生软中断,从而让程序陷入内核态,执行相应的操作。对于每个系统调用都会有一个对应的系统调用号,比很多操作系统要少很多。安全性与稳定性:内核驻留在受保护的地址空间,用户空间程序无法直接执行内核代码,也无法访问内核数据,通过系统调用性能:Linux上下文切换时间很短,以及系统调用处理过程非常精简,内核优化得好,所以性能上往往比很多其他操作系统执行要好。二、Syscall查找方式这里以文章理解杀进程的实现原理中的kill()方法为例子,来找一找kill()方法系统调用的过程。Tips 1:用户空间的方法xxx,对应系统调用层方法则是sys
3、_xxx;TIps 2:unistd.h文件记录着系统调用中断号的信息。故用户空间kill方法则对应系统调用层便是sys_kill,这个方法去哪里找呢?从/kernel/include/uapi/asm-generic/unistd.h等还有很多unistd.h去慢慢查看,查看关键字sys_kill,便能看到下面几行:/* kernel/signal.c */_SYSCALL(_NR_kill, sys_kill)根据这个能得到一丝线索,那就是kill对应的方法sys_kill位于/kernel/signal.c文件。TIps 3:宏定义SYSCALL_DEFINEx(xxx,),展开后对应的
4、方法则是sys_xxx;TIps 4:方法参数的个数x,对应于SYSCALL_DEFINEx。kill(int pid, int sig)方法共两个参数,则对应方法于SYSCALL_DEFINE2(kill,.),进入signal.c文件,再次搜索关键字,便能看到方法:SYSCALL_DEFINE2(kill, pid_t, pid,int, sig)struct siginfo info;info.si_signo = sig;info.si_errno =0;info.si_code = SI_USER;info.si_pid = task_tgid_vnr(current);info.s
5、i_uid = from_kuid_munged(current_user_ns(), current_uid();return kill_something_info(sig, SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)基本等价于asmlinkage long sys_kill(int pid, int sig),这里用的是基本等价,往下看会解释原因。回到顶部实用技巧比如kill命令, 有两个参数. 则可以直接在kernel目录下搜索 “SYSCALL_DEFINE2(kill”,即可直接找到,所有对应的Syscall方法位于signal.c三、S
6、yscall流程Syscall是通过中断方式实现的,ARM平台上通过swi中断来实现系统调用,实现从用户态切换到内核态,发送软中断swi时,从中断向量表中查看跳转代码,其中异常向量表定义在文件/kernelarch/arm/kernel/entry-armv.S(汇编语言文件)。当执行系统调用时会根据系统调用号从系统调用表中来查看目标函数的入口地址,在calls.S文件中声明了入口地址信息。总体流程:kill() - kill.S - swi陷入内核态 - 从sys_call_table查看到sys_kill - ret_fast_syscall - 回到用户态执行kill()下一行代码。 下
7、面介绍部分核心流程:3.1:用户程序通过软中断swi指令切入内核态,执行vector_swi处的指令。vector_swi在文件/kenel/arch/arm/kernel/entry-common.S中定义,此处省略。像每一个异常处理程序一样,要做的第一件事当然就是保护现场了。紧接着是获得系统调用的系统调用号3.2:仍以kill()函数为例,来详细说说Syscall调用流程,用户空间kill()定义位于文件kill.S。#includeENTRY(kill)mov ip, r7ldr r7, =_NR_killswi#0mov r7, ipcmn r0,#(MAX_ERRNO + 1)bxl
8、s lrneg r0, r0b _set_errno_internalEND(kill)当调用kill时, 系统先保存r7内容, 然后将_NR_kill值放入r7, 再执行swi软中断指令切换进内核态。3.3:Linux内核中,每个Syscall都有唯一的系统调用号对应,kill的系统调用号为_NR_kill,用户空间的系统调用号定义于/bionic/libc/kernel/uapi/asm-generic/unistd.h,如下:#define _NR_kill (_NR_SYSCALL_BASE + 37)其中_NR_SYSCALL_BASE=0,也就是_NR_kill系统调用号=37。3
9、.4:在内核中有与系统调用号对应的系统调用表,定义在文件/kernel/arch/arm/kernel/calls.S,如下:/* 35 */CALL(sys_ni_syscall)/* was sys_fTIme */CALL(sys_sync)CALL(sys_kill)/此处为37号CALL(sys_rename)CALL(sys_mkdir)到这里可知37号系统调用对应sys_kill(),该方法所对应的函数声明在syscalls.h文件3.5:文件/kernel/include/linux/syscalls.h中有如下声明:asmlinkagelongsys_kill(int pid
10、,int sig);asmlinkage是gcc标签,代表函数读取的参数来自于栈中,而非寄存器。回到顶部3.1 SYSCALL_DEFINEsys_kill()定义在内核源码找不到直接定义,而是通过syscalls.h文件中的SYSCALL_DEFINE宏定义。前面已经讲过sys_kill是通过语句SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)来定义,下面来一层层剖开,这条宏定义的真面目:等价 1:syscalls.h中有大量如下宏定义:#define SYSCALL_DEFINE0(sname) SYSCALL_METADATA(_#sname, 0)
11、; asmlinkagelong sys_#sname(void)#define SYSCALL_DEFINE1(name, .) SYSCALL_DEFINEx(1, _#name, _VA_ARGS_)#define SYSCALL_DEFINE2(name, .) SYSCALL_DEFINEx(2, _#name, _VA_ARGS_)#define SYSCALL_DEFINE3(name, .) SYSCALL_DEFINEx(3, _#name, _VA_ARGS_)#define SYSCALL_DEFINE4(name, .) SYSCALL_DEFINEx(4, _#nam
12、e, _VA_ARGS_)#define SYSCALL_DEFINE5(name, .) SYSCALL_DEFINEx(5, _#name, _VA_ARGS_)#define SYSCALL_DEFINE6(name, .) SYSCALL_DEFINEx(6, _#name, _VA_ARGS_)可得出原语句等价:SYSCALL_DEFINEx(2, _kill, pid_t, pid,int, sig)等价 2:syscalls.h中有如下宏定义:#define SYSCALL_DEFINEx(x, sname, .) SYSCALL_METADATA(sname, x, _VA_A
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux syscall详细介绍 syscall 详细 介绍
链接地址:https://www.31doc.com/p-3255196.html