tag 标签: syscall

相关博文
  • 热度 15
    2015-2-13 20:53
    1160 次阅读|
    0 个评论
    do_vfs_ioctl函数是一个非常重要的函数,如果在它里面加入打印信息,会发现系统启动时它被执行了很多次,系统运行时也在不断的执行它。它被下面这个函数调用: SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) {         int error;         struct fd f = fdget(fd);         if (!f.file)                 return -EBADF;         error = security_file_ioctl(f.file, cmd, arg);         if (!error)                 error = do_vfs_ioctl(f.file, fd, cmd, arg);         fdput(f);         return error; } 在include/linux/syscalls.h中有SYSCALL_DEFINE3的定义: #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)   #define SYSCALL_DEFINEx(x, sname, ...)                          \         SYSCALL_METADATA(sname, x, __VA_ARGS__)                 \         __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)          #define SYSCALL_METADATA(sname, nb, ...) #define __SYSCALL_DEFINEx(x, name, ...)                                 \         asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))       \                 __attribute__((alias(__stringify(SyS##name))));         \          static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));  \         asmlinkage long SyS##name(__MAP(x,__SC_LONG,__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__))         原始的语句是这样的,可以发现参数的类型定义和值都是要使用“,”的: SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)      按照宏展开,得到下面的语句(注意“##”的作用是字符串连接,而__VA_ARGS__则是代表变参): SYSCALL_DEFINEx(3, _ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)          由于没有定义CONFIG_FTRACE_SYSCALLS,因此SYSCALL_METADATA(sname, nb, ...)的宏展开为空,那么就剩下了下面的__SYSCALL_DEFINEx(x, name, ...),将_ioctl语句按照这个宏再展开: asmlinkage long sys_ioctl(__MAP(3,__SC_DECL,unsigned int, fd, unsigned int, cmd, unsigned long, arg)) \         __attribute__((alias(__stringify(SyS_ioctl)))); \ static inline long SYSC_ioctl(__MAP(3,__SC_DECL,unsigned int, fd, unsigned int, cmd, unsigned long, arg)); \ asmlinkage long SyS_ioctl(__MAP(3,__SC_LONG,unsigned int, fd, unsigned int, cmd, unsigned long, arg)); \ asmlinkage long SyS_ioctl(__MAP(3,__SC_LONG,unsigned int, fd, unsigned int, cmd, unsigned long, arg)) \   { \        long ret = SYSC_ioctl(__MAP(3,__SC_CAST,unsigned int, fd, unsigned int, cmd, unsigned long, arg)); \        __MAP(3,__SC_TEST,unsigned int, fd, unsigned int, cmd, unsigned long, arg); \        __PROTECT(3,ret,__MAP(3,__SC_ARGS,unsigned int, fd, unsigned int, cmd, unsigned long, arg)); \        return ret; \ } \ static inline long SYSC_ioctl(__MAP(3,__SC_DECL,unsigned int, fd, unsigned int, cmd, unsigned long, arg))       再来看看__MAP的作用,它是用来组合参数的(现在知道为什么这个是3了吧,因为有3对形参): __MAP(n, m, t1, a1, t2, a2, ..., tn, an) will expand to         m(t1, a1), m(t2, a2), ..., m(tn, an)         接下来按照__MAP的含义再来展开: asklingage long sys_ioctl(__SC_DECL(unsigned int, fd), __SC_DECL(unsigned int, cmd), __SC_DECL(unsigned long, arg)) \         __attribute__((alias(__stringify(SyS_ioctl)))); \ static inline long SYSC_ioctl(__SC_DECL(unsigned int, fd), __SC_DECL(unsigned int, cmd), __SC_DECL(unsigned long, arg)); \ asmlingkage long SyS_ioctl(__SC_LONG(unsigned int, fd), __SC_LONG(unsigned int, cmd), __SC_LONG(unsigned long, arg)); \ asmlingkage long SyS_ioctl(__SC_LONG(unsigned int, fd), __SC_LONG(unsigned int, cmd), __SC_LONG(unsigned long, arg)) \ { \         long ret = SYSC_ioctl(__SC_CAST(unsigned int, fd), __SC_CAST(unsigned int, cmd), __SC_CAST(unsigned long, arg)); \         __SC_TEST(unsigned int, fd), __SC_TEST(unsigned int, cmd), __SC_TEST(unsigned long, arg); \         __PROTECT(3,ret, __SC_ARGS(unsigned int, fd), __SC_ARGS(unsigned int, cmd), __SC_ARGS(unsigned long, arg)); \         return ret; \ } \ static inline long SYSC_ioctl(__SC_DECL(unsigned int, fd), __SC_DECL(unsigned int, cmd), __SC_DECL(unsigned long, arg))        现在再按照__SC_*的宏定义展开(暂时忽略类型转换的部分,另外__stringify是字符串化的意思): asklingage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) \         __attribute__((alias("SyS_ioctl"))); \ static inline long SYSC_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); \ asmlingkage long SyS_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)); \ asmlingkage long SyS_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)) \ { \         long ret = SYSC_ioctl((unsigned int)fd, (unsigned int)cmd, (unsigned long)arg)); \         __SC_TEST(unsigned int, fd), __SC_TEST(unsigned int, cmd), __SC_TEST(unsigned long, arg); \         asmlinkage_protect(3,ret, fd, cmd, arg); \         return ret; \ } \ static inline long SYSC_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)         写到这里我已经在深深的。。。深深的。。。深深的怀疑自己的智商了。。。 中间还是有很多代码不明白啊~~~ 不管怎样,这段代码的功能是,定义了sys_ioctl,为了进行Ethernet,需要多次调用它。          http://www.360doc.com/content/09/0517/11/26398_3536647.shtml        =========================================================== 这篇文档里面是非常有价值的关于sys_ioctl - inet_ioctl的说明。