异想天开

What's the true meaning of light, Could you tell me why

linux3.13系统调用形式

日期:2015-06-10 17:39:41
  
最后更新日期:2015-07-08 15:26:10
【技术】
培养查看内核源码的能力

该版本内核对系统调用定义形式用宏进行了一层封装。比如write调用,对应内核的sys_write函数,然后把该入口放入中断描述表指定的偏移处。
实际上内核的定义形式如下:fs/read_write.c#L514 [code lang="cpp"]
SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,size_t, count)
{
...
}
[/code]
SYSCALL_DEFINE3的3表示该系统调用3个参数,定义于include/linux/syscalls.h#L176 [code lang="cpp"]
#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 __PROTECT(...) asmlinkage_protect(__VA_ARGS__)
#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__))
[/code]
SYSCALL_DEFINE3扩展为SYSCALL_DEFINEx宏,继续扩展,其中__SYSCALL_DEFINEx宏,利用了gcc的扩展attribute特性-函数别名,意思是sys_write函数是SySwrite的别名,SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,size_t, count)下面的中括号代码是属于SYSCwrite函数。
注:
这样做,我看到的好处,就是可以方便在系统调用前和系统调用后执行内核定义的函数或定义某些结构体
也许你发现SYSCALL_DEFINE3宏的参数,很怪异,这些参数还需要转化下才能作为sys_write的参数,主要是__MAP宏:
c语言的##双#号表示连接的意思。
[code lang="cpp"]
#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__)

#define __SC_DECL(t, a) t a
[/code]
__MAP(x,__SC_DECL,__VA_ARGS__)也就是表示x个参数对,每遇到两个参数时,使用下__SC_DECL。
[code lang="cpp"]
__MAP(3,__SC_DECL,unsigned int, fd, const char __user *, buf,size_t, count)即变成unsigned int fd, const char __user * buf,size_t count。
[/code]
对c语言的宏熟悉code:
[code lang="cpp"]
#include<stdio.h>

#define __MAP(n,...) __MAP##n(__VA_ARGS__)
#define __MAP1(m,t,a) m(t,a)
#define __SC_DECL(t, a) t a
int test(__MAP(1,__SC_DECL,int,n))
{
return n;
}

int main()
{
#define _string_(A) #A
printf("%s\n",_string_(hello world));


printf("%d\n",test(6));
return 0;
}
[/code]
结果为:
hello world
6