用户态的read、write等系统调用,陷入内核态,会首先调用到 SyS_read、SyS_write函数
1、write
用户态的系统调用:write
SyS_write
vfs_write
__vfs_write
fops->write
先看看 SyS_write 的定义
// fs/read_write.c577 SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,578 size_t, count)579 {580 struct fd f = fdget_pos(fd);581 ssize_t ret = -EBADF;582583 if (f.file) {584 loff_t pos = file_pos_read(f.file);585 ret = vfs_write(f.file, buf, count, &pos);586 if (ret >= 0)587 file_pos_write(f.file, pos);588 fdput_pos(f);589 }590591 return ret;592 }
SYSCALL_DEFINE3 的定义
// include/linux/syscalls.h
184 #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)189 #define SYSCALL_DEFINEx(x, sname, ...) \
190 SYSCALL_METADATA(sname, x, __VA_ARGS__) \
191 __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)194 #define __SYSCALL_DEFINEx(x, name, ...) \
195 asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
196 __attribute__((alias(__stringify(SyS##name)))); \
197 static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
198 asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \// 此处产生 SyS_xx 函数的定义
199 asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
200 { \
201 long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
202 __MAP(x,__SC_TEST,__VA_ARGS__); \
203 __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
204 return ret; \
205 } \
206 static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))// 注意,上面的这个 SYSC##name 内联函数正好接上第一个函数块中的函数实现,形成完整的内联函数定义
从用户态的 write 到 内核态的 SyS_write 这一步是通过 compat_sys_call_table 这个函数数组 和 宏__SYSCALL实现的,详见博客
ARM64系统中兼容系统调用表compat_sys_call_table的定义和初始化
最终 compat_sys_call_table 对应一个个函数指针元素
通过c库函数 syscall(int a) syscall.h 执行数组的a元素
2、read
SyS_read
vfs_read
__vfs_read
fops->read
3、io_submit
SyS_io_submit
do_io_submit
aio_write / aio_write
fops->write_iter / fops->read_iter