关于Linux系统如何实现fork的研究(4)

1 /* CALL(x)宏展开 */
 2 #define CALL(x) .equ NR_syscalls,NR_syscalls+1
 3 #include "calls.S"
 4
 5 .ifne NR_syscalls - __NR_syscalls
 6 .error "__NR_syscalls is not equal to the size of the syscall table"
 7 .endif
 8
 9 /* 主要是后面这一段,
10  * 上面一段主要用于统计系统调用数量,并将数量保存到NR_syscalls中,具体实现说明可以参考
11  */
12
13 #undef CALL
14 /* 其实就是生成一个数为x,相当于.long sys_clone,因为sys_clone是函数名,所以.long生成的是sys_clone函数名对应的地址 */
15 #define CALL(x) .long x
16
17 #ifdef CONFIG_FUNCTION_TRACER
18
19
20 /* 配合ldrcc一起看,原来ldrcc是这样 */
21 ldrcc    pc, [tbl, scno, lsl #2]   
22
23 /* 把CALL(x)代入ldrcc,最后是这样 */
24 ldrcc    pc, sys_clone(函数地址) 

清楚的看出来,ldrcc最后是将sys_clone的函数地址存入了pc寄存器,而sys_clone函数内核是怎么定义的呢,如下

1 /* 文件地址: linux内核目录/kernel/Fork.c */
 2
 3 /* 以下代码根据不同的内核配置定义了不同的clone函数
 4  * 其最终都调用的do_fork函数,我们先看看SYSCALL_DEFINE是怎么实现的吧,实现在此代码片段后面
 5  */
 6 #ifdef __ARCH_WANT_SYS_CLONE
 7 #ifdef CONFIG_CLONE_BACKWARDS
 8 SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
 9          int __user *, parent_tidptr,
10          int, tls_val,
11          int __user *, child_tidptr)
12 #elif defined(CONFIG_CLONE_BACKWARDS2)
13 SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags,
14          int __user *, parent_tidptr,
15          int __user *, child_tidptr,
16          int, tls_val)
17 #elif defined(CONFIG_CLONE_BACKWARDS3)
18 SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp,
19        int, stack_size,
20        int __user *, parent_tidptr,
21        int __user *, child_tidptr,
22        int, tls_val)
23 #else
24 SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
25          int __user *, parent_tidptr,
26          int __user *, child_tidptr,
27          int, tls_val)
28 #endif
29 {
30    return do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);
31 }
32
33
34  /************************************************
35  * 我是代码分界线
36  ************************************************/
37
38 /* 文件地址: linux内核目录/include/linux.h */
39
40 #define SYSCALL_DEFINE0(sname) \
41    SYSCALL_METADATA(_##sname, 0); \
42    asmlinkage long sys_##sname(void)
43
44 #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
45 #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
46 #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
47 #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)
48 #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)
49 #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)
50
51 #define SYSCALL_DEFINEx(x, sname, ...) \
52    SYSCALL_METADATA(sname, x, __VA_ARGS__) \
53    __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
54
55 #define __PROTECT(...) asmlinkage_protect(__VA_ARGS__)
56 #define __SYSCALL_DEFINEx

可以看出系统调用是使用SYSCALL_DEFINEx进行定义的,以我们的例子,实际上最后clone函数被定义为

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b33989c2b19c44d30b132667ae89ee74.html