kernel/arch/arm/kernel/entry-common.S
get_thread_info tskadr tbl, sys_call_table @ load syscall table pointerldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
.type sys_call_table, #objectENTRY(sys_call_table)#include "calls.S"
kernel/arch/arm/kernel/calls.S
/* * linux/arch/arm/kernel/calls.S * * Copyright (C) 1995-2005 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This file is included thrice in entry-common.S *//* 0 */ CALL(sys_restart_syscall) CALL(sys_exit) CALL(sys_fork_wrapper) CALL(sys_read) CALL(sys_write)/* 5 */ CALL(sys_open) CALL(sys_close) CALL(sys_ni_syscall) /* was sys_waitpid */ CALL(sys_creat) CALL(sys_link) ....../* 365 */ CALL(sys_recvmmsg)#ifndef syscalls_counted.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls#define syscalls_counted#endif.rept syscalls_padding CALL(sys_ni_syscall).endr
kernel/arch/arm/include/asm/unistd.h
/* * This file contains the system call numbers. */ #define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)#define __NR_exit (__NR_SYSCALL_BASE+ 1)#define __NR_fork (__NR_SYSCALL_BASE+ 2)#define __NR_read (__NR_SYSCALL_BASE+ 3)#define __NR_write (__NR_SYSCALL_BASE+ 4)#define __NR_open (__NR_SYSCALL_BASE+ 5)#define __NR_close (__NR_SYSCALL_BASE+ 6) /* 7 was sys_waitpid */#define __NR_creat (__NR_SYSCALL_BASE+ 8)#define __NR_link (__NR_SYSCALL_BASE+ 9)#define __NR_unlink (__NR_SYSCALL_BASE+ 10)#define __NR_execve (__NR_SYSCALL_BASE+ 11)#define __NR_chdir (__NR_SYSCALL_BASE+ 12)#define __NR_time (__NR_SYSCALL_BASE+ 13)#define __NR_mknod (__NR_SYSCALL_BASE+ 14)#define __NR_chmod (__NR_SYSCALL_BASE+ 15)#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
kernel/ipc/syscall.c
kernel/include/linux/syscalls.h
asmlinkage long sys_lseek(unsigned int fd, off_t offset, unsigned int origin);asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t __user *result, unsigned int origin);asmlinkage long sys_read(unsigned int fd, char __user *buf, size_t count);asmlinkage long sys_readahead(int fd, loff_t offset, size_t count);asmlinkage long sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen);asmlinkage long sys_write(unsigned int fd, const char __user *buf, size_t count);
kernel/System.map
c02c2568 T sys_closec02c262c T fd_installc02c267c T do_sys_openc02c27d0 T sys_openatc02c27e4 T sys_openc02c280c T sys_creatc02c2828 t __dentry_openc02c2a7c T dentry_openc02c2b0c T nameidata_to_filpc02c2b6c T lookup_instantiate_filpc02c2c48 T sys_fallocatec02c2ca4 t chown_commonc02c2d34 T sys_fchownc02c2d94 T sys_fchmodc02c2e40 T sys_lchownc02c2ec0 T sys_fchownatc02c2f4c T sys_chownc02c2fcc T sys_fchmodatc02c3088 T sys_chmodc02c30a8 T sys_chrootc02c313c T sys_fchdirc02c31b4 T sys_chdir
kernel/fs/open.c:
/* * Install a file pointer in the fd array. * * The VFS is full of places where we drop the files lock between * setting the open_fds bitmap and installing the file in the file * array. At any such point, we are vulnerable to a dup2() race * installing a file in the array before us. We need to detect this and * fput() the struct file we are about to overwrite in this case. * * It should never happen - if we allow dup2() do it, _really_ bad things * will follow. */ void fd_install(unsigned int fd, struct file *file){ struct files_struct *files = current->files; struct fdtable *fdt; spin_lock(&files->file_lock); fdt = files_fdtable(files); BUG_ON(fdt->fd[fd] != NULL); rcu_assign_pointer(fdt->fd[fd], file); spin_unlock(&files->file_lock);} EXPORT_SYMBOL(fd_install); long do_sys_open(int dfd, const char __user *filename, int flags, int mode){ char *tmp = getname(filename); int fd = PTR_ERR(tmp); if (!IS_ERR(tmp)) { fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, flags, mode, 0); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); } else { fsnotify_open(f->f_path.dentry); fd_install(fd, f); } } putname(tmp); } return fd;} SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int, mode){ long ret; if (force_o_largefile()) flags |= O_LARGEFILE; ret = do_sys_open(AT_FDCWD, filename, flags, mode); /* avoid REGPARM breakage on x86: */ asmlinkage_protect(3, ret, filename, flags, mode); return ret;} SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, int, mode){ long ret; if (force_o_largefile()) flags |= O_LARGEFILE; ret = do_sys_open(dfd, filename, flags, mode); /* avoid REGPARM breakage on x86: */ asmlinkage_protect(4, ret, dfd, filename, flags, mode); return ret;}
访问字符驱动的系统调用流程:open,read , write , ioctl和close等系统调用通过输入的字符设备文件指向该设备文件驱动代码中的相应函数。
static struct file_operations query_fops ={ .owner = THIS_MODULE, .open = my_open, .release = my_close, .ioctl = my_ioctl, .read = my_read, .write = my_write};
http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-5.html
http://www.tldp.org/LDP/lkmpg/2.4/html/x939.html
Linux Kernel architecture for device drivers
API: open , close , read , write 例子