1、目的
本文介绍linux3.10通过宏SYSCALL_DEFINE生成系统调用函数的方法。
2、系统调用
用户程序通过系统调用来使用操作系统提供的各种功能。
linux在syscalls.h中声明了所有的系统调用函数,例如:sys_rmdir()等。但是,我们却无法直接找到sys_rmdir()的定义。这是因为linux没有直接定义sys_rmdir(),而是使用了SYSCALL_DEFINE宏间接定义了系统调用函数。
3、SYSCALL_DEFINE宏的使用
下面我们通过分析sys_rmdir(const char __usr * pathname)的定义来掌握SYSCALL_DEFINE宏的使用方法。
在fs/namei.c中有如下代码,linux使用SYSCALL_DEFINE1宏定义了sys_rmdir()系统调用。
SYSCALL_DEFINE1宏在syscalls.h中定义如下,其中宏后面的数字含义为:系统调用函数行参的个数,例如,sys_rmdir()的行参只有一个,const char __usr * pathname。
SYSCALL_DEFINE1定义为SYSCALL_DEFINEx;SYSCALL_DEFINEx定义SYSCALL_METADATA和__SYSCALL_DEFINEx,SYSCALL_METADATA用来实现ptrace功能,暂时不关注;重点分析__SYSCALL_DEFINEx,定义如下:
__SYSCALL_DEFINEx定义的有点小复杂,嵌套的宏也有点多,简单分析可以看出:声明了两个函数,定义了两个函数。
由于该宏比较复杂,所以我们使用gcc的-E功能展开SYSCALL_DEFINE1宏得到如下代码,从图中看出,该宏声明了sys_rmdir(),并且sys_rmdir()等同于SyS_rmdir(),而Sys_rmdir()最终调用了do_rmdir()。
4、总结
通过以上分析,我们知道SYSCALL_DEFINE1(rmdir, const char __user *, pathname){return do_rmdir(pathname)}宏的功能是:
1、将rmdir加上"sys_"前缀后声明sys_rmdir(const char __usr * pathname);
2、定义SyS_rmdir(const char __user * pathname){return do_rmdir(pathname)};
3、最终sys_rmdir()等同于SyS_rmdir()。
所以,我们可以根据系统调用行参的个数调用相应的SYSCALL_DEFINEx来声明系统调用。