注: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的更多相关文章

  1. 2018-2019-1 20189218《Linux内核原理与分析》第七周作业

    task_struck数据结构 在Linux内核中,通过task_struct这个结构体对进程进行管理,我们可以叫他PCB或者进程描述符.这个结构体定义在include/linux/sched.h中. ...

  2. fork函数创建新进程过程分析

    gdb调试执行流程,首先设置断点b sys_clone,当在shell下输入fork命令后,系统执行至断点,接下来按步执行: 判断是否被跟踪 判断是否被创建为轻量级进程(vfork) 判断父进程是否被 ...

  3. fork、vfork、clone区别

    在Linux中主要提供了fork.vfork.clone三个进程创建方法. 问题 在linux源码中这三个调用的执行过程是执行fork(),vfork(),clone()时,通过一个系统调用表映射到s ...

  4. Linux下fork()、vfork()、clone()和exec()的区别

    转自Linux下fork().vfork().clone()和exec()的区别 前三个和最后一个是两个类型.前三个主要是Linux用来创建新的进程(线程)而设计的,exec()系列函数则是用来用指定 ...

  5. 《Linux内核分析》 week6作业-Linux内核fork()系统调用的创建过程

    一.进程控制块PCB-stack_struct 进程在操作系统中都有一个结构,用于表示这个进程.这就是进程控制块(PCB),在Linux中具体实现是task_struct数据结构,它主要记录了以下信息 ...

  6. 系统调用fork()在powerpc上的源码分析

    总结一句话:系统调用的本质,通过sc指令触发异常,完成用户态到内核的转换. 展开一些:应用程序调用fork(),fork()是一个glibc函数,该函数的最底层调用sc指令,触发cpu异常,从而完成从 ...

  7. linux 进程创建clone、fork与vfork

    目录: 1.clone.fork与vfork介绍 2.fork说明 3.vfork说明 4.clone说明5.fork,vfork,clone的区别 内容: 1.clone.fork与vfork介绍 ...

  8. fork()、vfork()、clone()的区别

    因为生活的复杂,这是一个并行的世界,在同一时刻,会发生很多奇妙的事情,北方下雪,南方下雨,这里在吃饭,那边在睡觉,有人在学习,有人在运动,所以这时一个多彩多姿的世界,每天都发生着很多事情,所以要想很好 ...

  9. 关于linux系统如何实现fork的研究(一)

    引言     fork函数是用于在linux系统中创建进程所使用,而最近看了看一个fork()调用是怎么从应用到glibc,最后到内核中实现的,这片文章就聊聊最近对这方面研究的收获吧.我们主要聊聊从g ...

随机推荐

  1. DB2安装过程中可能遇到的错误

    WARNING:DBT3534W  The db2prereqcheck utility determined that ASLR is set to ON and that this could c ...

  2. win8中的gridview和listview控件微软链接

    快速入门:添加 ListView 和 GridView 控件 http://msdn.microsoft.com/zh-cn/library/windows/apps/hh780650.aspx XA ...

  3. [转]SpringMVC单文件上传、多文件上传、文件列表显示、文件下载

    一.新建一个Web工程,导入相关的包 springmvc的包+commons-fileupload.jar+connom-io.jar+commons-logging,jar+jstl.jar+sta ...

  4. facebook工具xhprof的安装与使用-分析php执行性能

    下载源码包的网址 http://pecl.php.net/package/xhprof

  5. C#使用线程池创建线程

    using System; using System.Threading; public class Example { public static void Main() { // Queue th ...

  6. 腾讯云CentOS 安装 Hadoop 2.7.3

    1.安装 jdk yum install java 2.安装maven wget http://mirrors.hust.edu.cn/apache/maven/maven-3/3.5.0/binar ...

  7. Sublime Text 3中文乱码问题的解决(最有效)

    Sublime Text 3中文乱码问题的解决(最有效) Sublime Text 3是很好的代码编辑器,没有之一,因为她的性感高亮代码配色,更因为它的小巧,但是它默认不支持GBK的编码格式,因此打开 ...

  8. 在 Android studio 中 配置Gradle 进行 “动态编译期间,指定 远程服务器地址 ,生成多个安装包”

    需求: 在产品开发中,经常需要发布各个版本,每个版本的服务器地址有不同的服务器地址.比如 开发服务器使用 192.168.1.232服务器, 测试服务器使用 192.168.1.245服务器, 正式上 ...

  9. [hadoop读书笔记] 第五章 MapReduce工作机制

    P205 MapReduce的两种运行机制 第一种:经典的MR运行机制 - MR 1 可以通过一个简单的方法调用来运行MR作业:Job对象上的submit().也可以调用waitForCompleti ...

  10. Qt中如何根据类名来实例化对象

    对于Qt 来说,是可以做到运行时,根据对象的类名字(字符串)来获得对象的实例的,这点和一些语言的反射机制是一样的. 但是在Qt中,我们需要所额外的一步,就是注册.只要做到了注册,我们就可以 自由的创建 ...