fork 至 “sys_clone" SyS_clone
注:glibc-2.17中fork的相应系统调用是sys_clone及SyS_clone。有人说调用的是sys_fork,但是我持否定意见,如果我们向真的来发起系统调用可以使用syscall。
fork系统调用等价于直接调用的就是
do_fork(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHILD,
NULL, NULL, NULL, &THREAD_SELF->tid)。&THREAD_SELF->tid放在svc状态下的栈上,前四个参数在r0~r3中。
比较简单,sys_clone实际上是SyS_clone
__vectors_start:
#....
W(ldr) pc, .LCvswi + stubs_offset //将vector_swi的标号值给pc
#.... .LCvswi:
.word vector_swi
swi流程

sys_call_table:
CALL(sys_clone)
sys_clone与SyS_clone的关系
SYSCALL_ALIAS(sys##name, SyS##name); #define SYSCALL_ALIAS(alias, name) \
asm ( #alias " = " #name "\n\t.globl " #alias)
SyS_clone何时触发了do_fork()
#define __SYSCALL_DEFINEx(x, name, ...) \
asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
{ \
long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
__MAP(x,__SC_TEST,__VA_ARGS__); \
__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
return ret; \
} \
.......... static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))
{
return do_fork(clone_flags, newsp, , parent_tidptr, child_tidptr);
}
先参考http://www.cnblogs.com/openix/archive/2012/02/25/2367557.html
下面抽取了细节,有点繁琐,主要是一些宏的使用(可变“参数”的宏,宏的字符串转化,宏粘贴),方法倒是蛮好的:
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
int __user *, parent_tidptr,
int __user *, child_tidptr,
int, tls_val)
{
return do_fork(clone_flags, newsp, , parent_tidptr, child_tidptr);
}
#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) #define SYSCALL_DEFINEx(x, sname, ...) \
__SYSCALL_DEFINEx(x, sname, __VA_ARGS__) #define __SYSCALL_DEFINEx(x, name, ...) \
asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
{ \
long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
__MAP(x,__SC_TEST,__VA_ARGS__); \
__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
return ret; \
} \
SYSCALL_ALIAS(sys##name, SyS##name); \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)
如何__MAP的实现
#define __SC_STR_TDECL(t, a) #t
#define __SC_STR_TDECL(t, a) #a
#define __SC_DECL(t, a) t a
#define __SC_CAST(t, a) (t)a
#define __SC_LONG(t, a) \
__typeof(__builtin_choose_expr( __TYPE_IS_LL(t), 0LL, 0L)) a #define __same_type(a, b) \
__builtin_types_compatible_p(typeof(a), typeof(b))
#define __TYPE_IS_LL(t) \
(__same_type((t)0, 0LL) || __same_type((t)0, 0ULL)) #define __MAP0(m, ...)
#define __MAP1(m, t, a) m(t, a)
#define __MAP2(m, t, a, ...) m(t, a), __MAP1(m, __VA_ARGS__)
#define __MAP3(m, t, a, ...) m(t, a), __MAP2(m, __VA_ARGS__)
#define __MAP4(m, t, a, ...) m(t, a), __MAP3(m, __VA_ARGS__)
#define __MAP5(m, t, a, ...) m(t, a), __MAP4(m, __VA_ARGS__)
#define __MAP6(m, t, a, ...) m(t, a), __MAP5(m, __VA_ARGS__)
#define __MAP(n, ...) __MAP##n(__VA_ARGS__)
关于汇编中的宏,可以有默认参数,参考arm的kernel中 ct_user_exit 使用。
fork 至 “sys_clone" SyS_clone的更多相关文章
- 2018-2019-1 20189218《Linux内核原理与分析》第七周作业
task_struck数据结构 在Linux内核中,通过task_struct这个结构体对进程进行管理,我们可以叫他PCB或者进程描述符.这个结构体定义在include/linux/sched.h中. ...
- fork函数创建新进程过程分析
gdb调试执行流程,首先设置断点b sys_clone,当在shell下输入fork命令后,系统执行至断点,接下来按步执行: 判断是否被跟踪 判断是否被创建为轻量级进程(vfork) 判断父进程是否被 ...
- fork、vfork、clone区别
在Linux中主要提供了fork.vfork.clone三个进程创建方法. 问题 在linux源码中这三个调用的执行过程是执行fork(),vfork(),clone()时,通过一个系统调用表映射到s ...
- Linux下fork()、vfork()、clone()和exec()的区别
转自Linux下fork().vfork().clone()和exec()的区别 前三个和最后一个是两个类型.前三个主要是Linux用来创建新的进程(线程)而设计的,exec()系列函数则是用来用指定 ...
- 《Linux内核分析》 week6作业-Linux内核fork()系统调用的创建过程
一.进程控制块PCB-stack_struct 进程在操作系统中都有一个结构,用于表示这个进程.这就是进程控制块(PCB),在Linux中具体实现是task_struct数据结构,它主要记录了以下信息 ...
- 系统调用fork()在powerpc上的源码分析
总结一句话:系统调用的本质,通过sc指令触发异常,完成用户态到内核的转换. 展开一些:应用程序调用fork(),fork()是一个glibc函数,该函数的最底层调用sc指令,触发cpu异常,从而完成从 ...
- linux 进程创建clone、fork与vfork
目录: 1.clone.fork与vfork介绍 2.fork说明 3.vfork说明 4.clone说明5.fork,vfork,clone的区别 内容: 1.clone.fork与vfork介绍 ...
- fork()、vfork()、clone()的区别
因为生活的复杂,这是一个并行的世界,在同一时刻,会发生很多奇妙的事情,北方下雪,南方下雨,这里在吃饭,那边在睡觉,有人在学习,有人在运动,所以这时一个多彩多姿的世界,每天都发生着很多事情,所以要想很好 ...
- 关于linux系统如何实现fork的研究(一)
引言 fork函数是用于在linux系统中创建进程所使用,而最近看了看一个fork()调用是怎么从应用到glibc,最后到内核中实现的,这片文章就聊聊最近对这方面研究的收获吧.我们主要聊聊从g ...
随机推荐
- iOS全局变量的声明和使用
在一个项目中,我们可能需要定义几个全局变量,在我们程序的任何位置都可以进行访问,提高我们的开发效率.在iOS中我们如何来实现呢?我们主要使用的是AppDelegate类来实现.如下: (1)AppDe ...
- MySQL——SQL Mode详解
简介 MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式.这样,应用程序就能对服务器操作进行量身定制以满足自己的需求.这类模式定义了MySQL应支持的SQL语法 ...
- RavenDb学习(八)高级特性上半部分
.事务支持 别的关系型数据库和RavenDb一起使用 using (var transaction = new TransactionScope()) { BlogPost entity = sess ...
- lvreduce -L 1000M /dev/vg0/lv0 表示最后缩减至多大,不是减少了多大
resize2fs在前 lvextend 在后 将/dev/vg0/lv0缩减到1000M umount /lv/ 取消挂载 [root@desktop4 ~]# e2fsck -f /dev/vg0 ...
- Altium Designer 规则设置
设计规则设置 Designer Rules Check(DRC) Electrical 电气规则.安全间距,线网连接等 Routing 布线,线宽.过孔形状尺寸.布线拓扑.布线层.封装出线等 SMT ...
- 初探Asp.net请求机制原理 1
web原理 请求---响应 而一个 简单的请求 响应中包含太多知识,只有把 请求响应原理搞懂才能在web的世界里好好翱翔(注:自已的整理的知识参考博友们东西或自已所想,没有盗版权的意思,在此说明就不引 ...
- WinForm窗体继承
在Windows应用程序中,从现有的窗体继承,查看子窗体的设计视图时,会出现错误: 服务容器中已存在服务 System.Windows.Forms.Design.IEventHandlerServic ...
- yizhihx ubuntu config
install shadowsocks:http://www.cnblogs.com/huangshiyu13/p/8973967.html download: https://pan.baidu.c ...
- MySQL 数据库 varchar 到底可以存多少个汉字,多少个英文呢?我们来搞搞清楚
一.关于UTF-8 UTF-8 Unicode Transformation Format-8bit.是用以解决国际上字符的一种多字节编码. 它对英文使用8位(即一个字节) ,中文使用24位(三个字节 ...
- "android.uid.systemandroid.view.InflateException: Binary XML file line #7: Error inflating class android.webkit.WebView
在android源码中编译app通过,运行时出现错误: "android.uid.systemandroid.view.InflateException: Binary XML file l ...