用户空间
bionic/libc/kernel/uapi/asm-generic/unistd.h 系统调用号的宏定义
#define __NR_sysinfo 179
bionic/libc/arch-arm64/syscalls/sysinfo.S 汇编定义相关函数的中断调用过程
#include <private/bionic_asm.h>
ENTRY(sysinfo)
mov x8, __NR_sysinfo
svc #0
cmn x0, #(MAX_ERRNO + 1)
cneg x0, x0, hi
b.hi __set_errno_internal
ret
END(sysinfo)
将调用号__NR_sysinfo传给寄存器r8,最终内核将收到这个调用号
内核空间
内核中调用号的定义在include/uapi/asm-generic/unistd.h中
#define __NR_sysinfo 179
__SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
系统调用的申明在include/linux/syscalls.h中
asmlinkage long sys_sysinfo(struct sysinfo __user *info);
arch/arm/kernel/calls.S 在内核中有与系统调用号对应的系统调用表
CALL(sys_sysinfo)
SYSCALL_DEFINE
sys_sysinfo()定义在内核源码找不到直接定义,而是通过syscalls.h文件中的SYSCALL_DEFINE宏定义。这些宏的展开参考Linux系统调用(syscall)原理
#define SYSCALL_DEFINE0(sname) \
SYSCALL_METADATA(_##sname, 0); \
asmlinkage long sys_##sname(void)
#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__)
kernel/sys.c最终函数
SYSCALL_DEFINE1(sysinfo, struct sysinfo __user *, info)
{
struct sysinfo val;
do_sysinfo(&val);
if (copy_to_user(info, &val, sizeof(struct sysinfo)))
return -EFAULT;
return 0;
}
技巧
如果你要查找系统调用的最终函数,只要记住SYSCALL_DEFINEx(x, sname, ...)
比如kill函数原型是int kill(pid_t pid, int sig)
, 因此只需要grep -rn 'SYSCALL_DEFINE2(kill'
就可以查找到, 其中2是函数原型的参数个数,kill是函数名
sysinfo函数原型int sysinfo(struct sysinfo *info)
,则是grep -rn 'SYSCALL_DEFINE1(sysinfo'
就可以查找到,最终结果
$ grep -rn 'SYSCALL_DEFINE1(sysinfo'
kernel/sys.c:2567:SYSCALL_DEFINE1(sysinfo, struct sysinfo __user *, info)
kernel/sys.c:2597:COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info)
$ grep -rn 'SYSCALL_DEFINE2(kill'
kernel/signal.c:2970:SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
标签:__,调用,name,SYSCALL,流程,SystemCall,DEFINEx,sysinfo,define
From: https://www.cnblogs.com/tangshunhui/p/16739605.html