在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系统调用分析的更多相关文章

  1. linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限制. 内核态:高执行级别,代码可移植性特权指令,访问任意物理地址 为什么划分级别:如果全部特权 ...

  2. linux内核分析——扒开系统调用的三层皮(下)

    20135125陈智威 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 实验 ...

  3. linux内核分析——扒开系统调用的三层皮(上)

    20135125陈智威 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 系统调用 ...

  4. Linux内核分析之扒开系统调用的三层皮(下)

    一.实验内容 1. 通过内核的方式使用系统调用 需要使用的命令 rm menu -rf //强制删除当前menugit clone http://github.com/mengning/menu.gi ...

  5. 《Linux内核分析》第四周 扒开系统调用的“三层皮”

    [刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK FOUR( ...

  6. 《Linux内核分析》第五周 扒开系统调用的三层皮(下)

    [刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK FIVE( ...

  7. linux内核分析——扒开系统调用的三层皮

    万子惠 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验部分 选择2 ...

  8. Linux内核分析第四周学习总结:扒开系统调用的三层皮(上)

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.用户态.内核 ...

  9. Linux内核分析第五周学习总结:扒开系统调用的三层皮(下)

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给MenuO ...

随机推荐

  1. java基础—Hashtable,HashMap,TreeMap的差别

    Hashtable : 此类实现一个哈希表,该哈希表将键映射到对应的值.不论什么非null  对象都能够作键值,是线程不同步的 HashMap : 基于哈希表的Map接口的实现.此实现提供全部可选的映 ...

  2. SQL语句中的Having子句与where子句

    一.介绍 聚合函数如SUM, COUNT, MAX, AVG等.这些函数和其它函数的根本区别就是它们一般作用在多条记录上.而通过使用GROUP BY 子句,可以让SUM 和 COUNT 这些函数对属于 ...

  3. SQLServer: 用 ApexSQLLog 恢复 SQL Server 数据

    https://blog.csdn.net/yenange/article/details/50512312

  4. 印象笔记windows端-快捷键大全

    作为印象笔记粉,当然要多掌握些快捷键,提高办公效率. 补: ctrl + shift + , 光标内字体变小 ctrl + shitf + . 光标内字体变大

  5. django基本安装

    一.web框架 1.什么是web框架? Web框架是一种开发框架,用来支持动态网站.网络应用程序及网络服务的开发.其类型有基于请求的和基于组件的两种框架. 本质上其实就是一个socket服务端,用户的 ...

  6. 剑指offer 面试13题

    面试13题: 题目:机器人的运动范围 题:地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子 ...

  7. Traverse the dict in Python

    We usually use the following 2 ways to traverse a dict: 1: for d in dic 2: for d in dic.keys() Which ...

  8. spring mvc 自动扫描注解失效原因

    关于spring自动扫描,在控制层,采用注解配置@Controller,项目能够成功启动,且无任何报错.但是 在进行页面跳转时,并未进行相应的拦截,整个界面只能在默认界面 ,跳转报404,由于楼主初次 ...

  9. PAT 天梯赛 L1-024. 后天 【取余】

    题目链接 https://www.patest.cn/contests/gplt/L1-024 题意 给出一个数,表示星期几,输出后天是星期几 思路 取余的时候要小心点 AC代码 #include & ...

  10. 每天一个Linux命令(60)ip命令

        ip命令是Linux下较新的功能强大的网络配置工具.     (1)用法:     用法:  ip  [OPTIONS]  OBJECT  [COMMAND [ARGUMENTS]]     ...