linux/arch/arm/kernel/call.S
…
CALLsys_read)
CALLsys_write)
CALLsys_open)
CALLsys_close)
…
以read,write接口举栗子:
linux/fs/read_write.c
SYSCALL_DEFINE3read, unsigned int, fd, char __user *, buf, size_t, count)
{
struct file *file;
ssize_t ret = -EBADF;
int fput_needed;
file = fget_lightfd, &fput_needed); // 获取到 struct file
if file) {
loff_t pos = file_pos_readfile); //获取文件指针的position
ret = vfs_readfile, buf, count, &pos); // read file
file_pos_writefile, pos); //保存文件指针的position
fput_lightfile, fput_needed); // 写回 struct file
}
return ret;
}
SYSCALL_DEFINE3read, unsigned int, fd, char __user *, buf, size_t, count)
#define SYSCALL_DEFINE3name, …) SYSCALL_DEFINEx3, _##name, __VA_ARGS__)
#ifdef CONFIG_FTRACE_SYSCALLS
…
#else
#define SYSCALL_DEFINExx, sname, …)
__SYSCALL_DEFINExx, sname, __VA_ARGS__)
#endif
===SYSCALL_DEFINEx3, _read, unsigned int, fd, char __user *, buf, size_t, count)
===__SYSCALL_DEFINEx3,_read, unsigned int, fd, char __user *, buf, size_t, count)
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
……
#else /* CONFIG_HAVE_SYSCALL_WRAPPERS */
#define SYSCALL_DEFINEname) asmlinkage long sys_##name
#define __SYSCALL_DEFINExx, name, …)
asmlinkage long sys##name__SC_DECL##x__VA_ARGS__))
#endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */
===asmlinkage long sys_read__SC_DECL3unsigned int, fd, char __user *, buf, size_t, count))
#define __SC_DECL1t1, a1) t1 a1
#define __SC_DECL2t2, a2, …) t2 a2, __SC_DECL1__VA_ARGS__)
#define __SC_DECL3t3, a3, …) t3 a3, __SC_DECL2__VA_ARGS__)
#define __SC_DECL4t4, a4, …) t4 a4, __SC_DECL3__VA_ARGS__)
#define __SC_DECL5t5, a5, …) t5 a5, __SC_DECL4__VA_ARGS__)
#define __SC_DECL6t6, a6, …) t6 a6, __SC_DECL5__VA_ARGS__)
===__SC_DECL3unsigned int, fd, char __user *, buf, size_t, count)
===>unsigned int fd, __SC_DECL2char __user *, buf, size_t, count)
===>unsigned int fd, char __user * buf, __SC_DECL1size_t, count)
===>unsigned int fd, char __user * buf, size_t count
===asmlinkage long sys_read__SC_DECL3unsigned int, fd, char __user *, buf, size_t, count))
===>asmlinkage long sys_readunsigned int fd, char __user * buf, size_t count)
===============
ssize_t vfs_readstruct file *file, char __user *buf, size_t count, loff_t *pos)
{
ssize_t ret;
if !file->f_mode & FMODE_READ)) //权限检测
return -EBADF;
if !file->f_op || !file->f_op->read && !file->f_op->aio_read)) //检测fop是否存在,驱动read接口是否实现
return -EINVAL;
if unlikely!access_okVERIFY_WRITE, buf, count))) //检测用户空间的buf是否可写
return -EFAULT;
ret = rw_verify_areaREAD, file, pos, count); //检测file文件,pos开始的count个字节的区域是否可读
if ret >= 0) {
count = ret;
if file->f_op->read)
ret = file->f_op->readfile, buf, count, pos); //调用相应驱动注册的read接口
else
ret = do_sync_readfile, buf, count, pos);
if ret > 0) {
fsnotify_accessfile);
add_rcharcurrent, ret);
}
inc_syscrcurrent);
}
return ret;
}