Linux系统调用分析
在HelloWorld程序中,我们可以调用libc中的getpid函数获取当前进程的进程号。HelloWorld是运行在用户空间,那么它是如何通过系统调用切换到内核空间来获取PID的呢?原来,在unistd.h中声明了函数原型,正是由于这个声明,我们才能在HelloWorld中调用getpid函数。
extern pid_t getpid(void);
很多Linux下C语言写的程序都需要包含 <unistd.h>这个文件,正是这个原因:它声明了大量的系统调用函数。所以说这个文件并不是C语言自己的,而是Linux系统的!
在libc中,getpid是用汇编语言写的,将系统调用号__NR_getpid写入寄存器R7(对于其它系统调用,如果有参数,则保存在其它的寄存器中),然后执行ARM的SWI软中断指令进入内核模式,开始执行内核空间的代码。
ENTRY(getpid)
mov ip, r7
ldr r7, =__NR_getpid
swi #
mov r7, ip
cmn r0, #(MAX_ERRNO + )
bxls lr
neg r0, r0
b __set_errno
END(getpid)
系统调用号__NR_getpid的定义如下:
#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
SWI的中断处理函数内部,会根据中断号去调用真正的sys_getpid函数,其定义在kernel/sys.c中:
/**
* sys_getpid - return the thread group id of the current process
*
* Note, despite the name, this returns the tgid not the pid. The tgid and
* the pid are identical unless CLONE_THREAD was specified on clone() in
* which case the tgid is the same in all threads of the same group.
*
* This is SMP safe as current->tgid does not change.
*/
SYSCALL_DEFINE0(getpid)
{
return task_tgid_vnr(current);
}
至此,完整的调用链条浮出水面: HelloWorld(user space) --> getpid(libc) --> ISR(SWI) --> sys_getpid(kernel)。其实是libc帮我们封装好了系统调用的接口,如果我们不用libc,而是直接用汇编操作系统调用的接口,也是可以进行系统调用的。
这里再讲一下系统调用的上下文,仍然属于进程上下文,不要因为软中断的概念而理解为中断上下文。其实可以这样理解:把swi看作一个函数调用,swi返回后,程序继续执行而返回getpid。只不过这个swi对应的函数调用具有特权权限,因此可以调用内核中的代码。
Linux系统调用分析的更多相关文章
- linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限制. 内核态:高执行级别,代码可移植性特权指令,访问任意物理地址 为什么划分级别:如果全部特权 ...
- linux内核分析——扒开系统调用的三层皮(下)
20135125陈智威 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 实验 ...
- linux内核分析——扒开系统调用的三层皮(上)
20135125陈智威 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 系统调用 ...
- Linux内核分析之扒开系统调用的三层皮(下)
一.实验内容 1. 通过内核的方式使用系统调用 需要使用的命令 rm menu -rf //强制删除当前menugit clone http://github.com/mengning/menu.gi ...
- 《Linux内核分析》第四周 扒开系统调用的“三层皮”
[刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK FOUR( ...
- 《Linux内核分析》第五周 扒开系统调用的三层皮(下)
[刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK FIVE( ...
- linux内核分析——扒开系统调用的三层皮
万子惠 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验部分 选择2 ...
- Linux内核分析第四周学习总结:扒开系统调用的三层皮(上)
韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.用户态.内核 ...
- Linux内核分析第五周学习总结:扒开系统调用的三层皮(下)
韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给MenuO ...
随机推荐
- Redis作者谈Redis应用场景(转)
add by zhj : 这是Redis的作者antirez在他的技术博客中写的一篇文章 英文原文:take-advantage-of-redis-adding-it-to-your-stack 译文 ...
- Linux CentOS使用yum安装Docker
Docker支持以下的CentOS版本: 目前,CentOS仅发行版本中的内核支持Docker. Docker运行在CentOS7上,要求系统为64位.系统内核版本为3.10以上. Docker运行在 ...
- TLS and SSL
SSL:(Secure Socket Layer,安全套接字层),位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层.SSL通过互相认证.使用数字签名确保完整性.使用加密确保私密性,以实现客户 ...
- 前端基础之jquery练习
实例练习 左侧菜单 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- android 对话框中的进度条 (ProgressDialog)
from:http://byandby.iteye.com/blog/817214 显然要定义对话框进度条就要用ProgressDialog,首先我们需要创建ProgressDialog对象,当然这里 ...
- LeetCode:二进制求和【67】
LeetCode:二进制求和[67] 题目描述 给定两个二进制字符串,返回他们的和(用二进制表示). 输入为非空字符串且只包含数字 1 和 0. 示例 1: 输入: a = "11" ...
- Loadrunder之脚本篇——参数类型
Internal data Date/Time,Group Name,Iteration Number,Load Generator Name,Ramdom Number,Table,Unique N ...
- ES集群性能调优链接汇总
1. 集群稳定性的一些问题(一定量数据后集群变得迟钝) https://elasticsearch.cn/question/84 2. ELK 性能(2) — 如何在大业务量下保持 Elasticse ...
- CentOS 5下freeswitch中集成使用ekho实现TTS功能三
四:在freeswitch中调用ekho 注:在测试过程中该语音包好像没用 FreeSWITCH 中文语音包测试版fssounds.zip 在/usr/local/freeswitch/sounds/ ...
- jQuery计算器插件
在线演示 本地下载