Chinaunix首页 | 论坛 | 博客

oha

  • 博客访问: 177144
  • 博文数量: 187
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1645
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

xxx

文章分类

全部博文(187)

文章存档

2018年(18)

2017年(63)

2016年(83)

2015年(23)

我的朋友

分类: LINUX

2017-11-09 11:40:33

arch/arm/kernel/entry-common.S

 .type sys_call_table, #object
ENTRY(sys_call_table)
#include "calls.S"
#undef ABI
#undef OBSOLETE

/*============================================================================
 * Special system call wrappers
 */
@ r0 = syscall number
@ r8 = syscall table
sys_syscall:
  bic scno, r0, #__NR_OABI_SYSCALL_BASE
  cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
  cmpne scno, #NR_syscalls @ check range
  stmloia sp, {r5, r6}  @ shuffle args
  movlo r0, r1
  movlo r1, r2
  movlo r2, r3
  movlo r3, r4
  ldrlo pc, [tbl, scno, lsl #2]
  b sys_ni_syscall
ENDPROC(sys_syscall)
//////////////////////////////////////////////////////////////////////////////////////////////



open函数通过系统调用sys_open进入内核空间, sysopen又调用do_sys_open,
do_sys_open 通过get_unused_fd(),在当前进程空间内的struct file结构数组中,
找一个空的struct file{}结构,并返回一个数组的下标号,

之后do_sys_open又调用do_filp_open,do_filp_open调用nameidata_to_filp,
nameidata_to_filp调用__dentry_open,

 read调用顺序如下: read()->sys_read()->vfs_read()->{file->f_op->read}用户空间的read、write---linux系统调用---间接调用设备驱动程序中file_operations结构中的函数
整个调用过程是这样一个顺序的。



在__dentry_open,通过关键语句,f->f_op = fops_get(inode->i_fop);
得到了具有一个指向struct file_operations结构的指针的struct file结构指针,
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
分析应用命令行rmmod模块命令
busybox1.27.2
busybox1.27.2/modutils/rmmod.c
int rmmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int rmmod_main(int argc UNUSED_PARAM, char **argv)
------->bb_delete_module(modname, flags);
busybox1.27.2/modutils/modutils.c
int FAST_FUNC bb_delete_module(const char *module, unsigned int flags)
{
    errno = 0;
    delete_module(module, flags);
    return errno;
}
modutils/modutils.c   //busybox里面
#define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
////////////////////

/*描述了 kernel/module.c里面的功能 */
#define __NR_init_module 105
__SYSCALL(__NR_init_module, sys_init_module)
#define __NR_delete_module 106
__SYSCALL(__NR_delete_module, sys_delete_module)

其实下面可以看出
sys_delete_module就是
//这里的3代表3个参数
SYSCALL_DEFINE3(init_module, void __user *, umod,
        unsigned long, len, const char __user *, uargs)
 
///////
include/linux/syscalls.h

#define SYSCALL_DEFINE3(name, ...)  SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
#define SYSCALL_DEFINEx(x, sname, ...)                \
    __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
#define SYSCALL_DEFINE(name) asmlinkage long sys_##name
#define __SYSCALL_DEFINEx(x, name, ...)                    \
    asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))


include/linux/syscalls.h
asmlinkage long sys_init_module(void __user *umod, unsigned long len,
                const char __user *uargs);
asmlinkage long sys_delete_module(const char __user *name_user,
                unsigned int flags);
////////
kernel/module.c
//这里的2代表2个参数
SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
        unsigned int, flags)
/////////////////////////////////////////////////////////////
kernel/module.c
/* This is where the real work happens */
//此函数就是
sys_init_module
 
SYSCALL_DEFINE3(init_module, void __user *, umod,
        unsigned long, len, const char __user *, uargs)

{
    struct module *mod;
    int ret = 0;

    /* Must have permission */
    if (!capable(CAP_SYS_MODULE) || modules_disabled)
        return -EPERM;

    /* Do all the hard work */
    mod = load_module(umod, len, uargs);
省掉很多行

    return 0;
}

//此函数就是sys_delete_module
 
SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
        unsigned int, flags)

{
    struct module *mod;
    char name[MODULE_NAME_LEN];
    int ret, forced = 0;
    if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
        return -EFAULT;
    name[MODULE_NAME_LEN-1] = '\0';
    mod = find_module(name);

省掉很多行
 
}
/////////////////////////////////////////////////////////////////

linux-2.6.30.4/arch/arm/kernel/calls.S 存储了所有sys_func 函数的入口地址。
linux/arch/arm/kernel/calls.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)
/* 10 */ CALL(sys_unlink)
  CALL(sys_execve_wrapper)
  CALL(sys_chdir)
  CALL(OBSOLETE(sys_time)) /* used by libc4 */
  CALL(sys_mknod)
/* 15 */ CALL(sys_chmod)
  CALL(sys_lchown16)
  CALL(sys_ni_syscall)  /* was sys_break */
  CALL(sys_ni_syscall)  /* was sys_stat */
  CALL(sys_lseek)
/* 20 */ CALL(sys_getpid)
  CALL(sys_mount)
  CALL(OBSOLETE(sys_oldumount)) /* used by libc4 */
  CALL(sys_setuid16)
  CALL(sys_getuid16)
/* 25 */ CALL(OBSOLETE(sys_stime))
  CALL(sys_ptrace)
  CALL(OBSOLETE(sys_alarm)) /* used by libc4 */
  CALL(sys_ni_syscall)  /* was sys_fstat */
  CALL(sys_pause)
/* 30 */ CALL(OBSOLETE(sys_utime)) /* used by libc4 */
  CALL(sys_ni_syscall)  /* was sys_stty */
  CALL(sys_ni_syscall)  /* was sys_getty */
  CALL(sys_access)
  CALL(sys_nice)
/* 35 */ CALL(sys_ni_syscall)  /* was sys_ftime */
  CALL(sys_sync)
  CALL(sys_kill)
  CALL(sys_rename)
  CALL(sys_mkdir)
/* 40 */ CALL(sys_rmdir)
  CALL(sys_dup)
  CALL(sys_pipe)
  CALL(sys_times)
  CALL(sys_ni_syscall)  /* was sys_prof */
/* 45 */ CALL(sys_brk)
  CALL(sys_setgid16)
  CALL(sys_getgid16)
  CALL(sys_ni_syscall)  /* was sys_signal */
  CALL(sys_geteuid16)
/* 50 */ CALL(sys_getegid16)
  CALL(sys_acct)
  CALL(sys_umount)
  CALL(sys_ni_syscall)  /* was sys_lock */
  CALL(sys_ioctl)
/* 55 */ CALL(sys_fcntl)
  CALL(sys_ni_syscall)  /* was sys_mpx */
  CALL(sys_setpgid)
  CALL(sys_ni_syscall)  /* was sys_ulimit */
  CALL(sys_ni_syscall)  /* was sys_olduname */
/* 60 */ CALL(sys_umask)
  CALL(sys_chroot)
  CALL(sys_ustat)
  CALL(sys_dup2)
  CALL(sys_getppid)
/* 65 */ CALL(sys_getpgrp)
  CALL(sys_setsid)
  CALL(sys_sigaction)
  CALL(sys_ni_syscall)  /* was sys_sgetmask */
  CALL(sys_ni_syscall)  /* was sys_ssetmask */
/* 70 */ CALL(sys_setreuid16)
  CALL(sys_setregid16)
  CALL(sys_sigsuspend_wrapper)
  CALL(sys_sigpending)
  CALL(sys_sethostname)
/* 75 */ CALL(sys_setrlimit)
  CALL(OBSOLETE(sys_old_getrlimit)) /* used by libc4 */
  CALL(sys_getrusage)
  CALL(sys_gettimeofday)
  CALL(sys_settimeofday)
/* 80 */ CALL(sys_getgroups16)
  CALL(sys_setgroups16)
  CALL(OBSOLETE(old_select)) /* used by libc4 */
  CALL(sys_symlink)
  CALL(sys_ni_syscall)  /* was sys_lstat */
/* 85 */ CALL(sys_readlink)
  CALL(sys_uselib)
  CALL(sys_swapon)
  CALL(sys_reboot)
  CALL(OBSOLETE(sys_old_readdir)) /* used by libc4 */
/* 90 */ CALL(OBSOLETE(old_mmap)) /* used by libc4 */
  CALL(sys_munmap)
  CALL(sys_truncate)
  CALL(sys_ftruncate)
  CALL(sys_fchmod)
/* 95 */ CALL(sys_fchown16)
  CALL(sys_getpriority)
  CALL(sys_setpriority)
  CALL(sys_ni_syscall)  /* was sys_profil */
  CALL(sys_statfs)
/* 100 */ CALL(sys_fstatfs)
  CALL(sys_ni_syscall)  /* sys_ioperm */
  CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
  CALL(sys_syslog)
  CALL(sys_setitimer)
/* 105 */ CALL(sys_getitimer)
  CALL(sys_newstat)
  CALL(sys_newlstat)
  CALL(sys_newfstat)
  CALL(sys_ni_syscall)  /* was sys_uname */
/* 110 */ CALL(sys_ni_syscall)  /* was sys_iopl */
  CALL(sys_vhangup)
  CALL(sys_ni_syscall)
  CALL(OBSOLETE(sys_syscall)) /* call a syscall */
  CALL(sys_wait4)
/* 115 */ CALL(sys_swapoff)
  CALL(sys_sysinfo)
  CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
  CALL(sys_fsync)
  CALL(sys_sigreturn_wrapper)
/* 120 */ CALL(sys_clone_wrapper)
  CALL(sys_setdomainname)
  CALL(sys_newuname)
  CALL(sys_ni_syscall)  /* modify_ldt */
  CALL(sys_adjtimex)
/* 125 */ CALL(sys_mprotect)
  CALL(sys_sigprocmask)
  CALL(sys_ni_syscall)  /* was sys_create_module */
  CALL(sys_init_module)
  CALL(sys_delete_module)

/* 130 */ CALL(sys_ni_syscall)  /* was sys_get_kernel_syms */
  CALL(sys_quotactl)
  CALL(sys_getpgid)
  CALL(sys_fchdir)
  CALL(sys_bdflush)
/* 135 */ CALL(sys_sysfs)
  CALL(sys_personality)
  CALL(sys_ni_syscall)  /* reserved for afs_syscall */
  CALL(sys_setfsuid16)
  CALL(sys_setfsgid16)
/* 140 */ CALL(sys_llseek)
  CALL(sys_getdents)
  CALL(sys_select)
  CALL(sys_flock)
  CALL(sys_msync)
/* 145 */ CALL(sys_readv)
  CALL(sys_writev)
  CALL(sys_getsid)
  CALL(sys_fdatasync)
  CALL(sys_sysctl)
/* 150 */ CALL(sys_mlock)
  CALL(sys_munlock)
  CALL(sys_mlockall)
  CALL(sys_munlockall)
  CALL(sys_sched_setparam)
/* 155 */ CALL(sys_sched_getparam)
  CALL(sys_sched_setscheduler)
  CALL(sys_sched_getscheduler)
  CALL(sys_sched_yield)
  CALL(sys_sched_get_priority_max)
/* 160 */ CALL(sys_sched_get_priority_min)
  CALL(sys_sched_rr_get_interval)
  CALL(sys_nanosleep)
  CALL(sys_arm_mremap)
  CALL(sys_setresuid16)
/* 165 */ CALL(sys_getresuid16)
  CALL(sys_ni_syscall)  /* vm86 */
  CALL(sys_ni_syscall)  /* was sys_query_module */
  CALL(sys_poll)
  CALL(sys_nfsservctl)
/* 170 */ CALL(sys_setresgid16)
  CALL(sys_getresgid16)
  CALL(sys_prctl)
  CALL(sys_rt_sigreturn_wrapper)
  CALL(sys_rt_sigaction)
/* 175 */ CALL(sys_rt_sigprocmask)
  CALL(sys_rt_sigpending)
  CALL(sys_rt_sigtimedwait)
  CALL(sys_rt_sigqueueinfo)
  CALL(sys_rt_sigsuspend_wrapper)
/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64))
  CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
  CALL(sys_chown16)
  CALL(sys_getcwd)
  CALL(sys_capget)
/* 185 */ CALL(sys_capset)
  CALL(sys_sigaltstack_wrapper)
  CALL(sys_sendfile)
  CALL(sys_ni_syscall)  /* getpmsg */
  CALL(sys_ni_syscall)  /* putpmsg */
/* 190 */ CALL(sys_vfork_wrapper)
  CALL(sys_getrlimit)
  CALL(sys_mmap2)
  CALL(ABI(sys_truncate64, sys_oabi_truncate64))
  CALL(ABI(sys_ftruncate64, sys_oabi_ftruncate64))
/* 195 */ CALL(ABI(sys_stat64, sys_oabi_stat64))
  CALL(ABI(sys_lstat64, sys_oabi_lstat64))
  CALL(ABI(sys_fstat64, sys_oabi_fstat64))
  CALL(sys_lchown)
  CALL(sys_getuid)
/* 200 */ CALL(sys_getgid)
  CALL(sys_geteuid)
  CALL(sys_getegid)
  CALL(sys_setreuid)
  CALL(sys_setregid)
/* 205 */ CALL(sys_getgroups)
  CALL(sys_setgroups)
  CALL(sys_fchown)
  CALL(sys_setresuid)
  CALL(sys_getresuid)
/* 210 */ CALL(sys_setresgid)
  CALL(sys_getresgid)
  CALL(sys_chown)
  CALL(sys_setuid)
  CALL(sys_setgid)
/* 215 */ CALL(sys_setfsuid)
  CALL(sys_setfsgid)
  CALL(sys_getdents64)
  CALL(sys_pivot_root)
  CALL(sys_mincore)
/* 220 */ CALL(sys_madvise)
  CALL(ABI(sys_fcntl64, sys_oabi_fcntl64))
  CALL(sys_ni_syscall) /* TUX */
  CALL(sys_ni_syscall)
  CALL(sys_gettid)
/* 225 */ CALL(ABI(sys_readahead, sys_oabi_readahead))
  CALL(sys_setxattr)
  CALL(sys_lsetxattr)
  CALL(sys_fsetxattr)
  CALL(sys_getxattr)
/* 230 */ CALL(sys_lgetxattr)
  CALL(sys_fgetxattr)
  CALL(sys_listxattr)
  CALL(sys_llistxattr)
  CALL(sys_flistxattr)
/* 235 */ CALL(sys_removexattr)
  CALL(sys_lremovexattr)
  CALL(sys_fremovexattr)
  CALL(sys_tkill)
  CALL(sys_sendfile64)
/* 240 */ CALL(sys_futex)
  CALL(sys_sched_setaffinity)
  CALL(sys_sched_getaffinity)
  CALL(sys_io_setup)
  CALL(sys_io_destroy)
/* 245 */ CALL(sys_io_getevents)
  CALL(sys_io_submit)
  CALL(sys_io_cancel)
  CALL(sys_exit_group)
  CALL(sys_lookup_dcookie)
/* 250 */ CALL(sys_epoll_create)
  CALL(ABI(sys_epoll_ctl, sys_oabi_epoll_ctl))
  CALL(ABI(sys_epoll_wait, sys_oabi_epoll_wait))
  CALL(sys_remap_file_pages)
  CALL(sys_ni_syscall) /* sys_set_thread_area */
/* 255 */ CALL(sys_ni_syscall) /* sys_get_thread_area */
  CALL(sys_set_tid_address)
  CALL(sys_timer_create)
  CALL(sys_timer_settime)
  CALL(sys_timer_gettime)
/* 260 */ CALL(sys_timer_getoverrun)
  CALL(sys_timer_delete)
  CALL(sys_clock_settime)
  CALL(sys_clock_gettime)
  CALL(sys_clock_getres)
/* 265 */ CALL(sys_clock_nanosleep)
  CALL(sys_statfs64_wrapper)
  CALL(sys_fstatfs64_wrapper)
  CALL(sys_tgkill)
  CALL(sys_utimes)
/* 270 */ CALL(sys_arm_fadvise64_64)
  CALL(sys_pciconfig_iobase)
  CALL(sys_pciconfig_read)
  CALL(sys_pciconfig_write)
  CALL(sys_mq_open)
/* 275 */ CALL(sys_mq_unlink)
  CALL(sys_mq_timedsend)
  CALL(sys_mq_timedreceive)
  CALL(sys_mq_notify)
  CALL(sys_mq_getsetattr)
/* 280 */ CALL(sys_waitid)
  CALL(sys_socket)
  CALL(ABI(sys_bind, sys_oabi_bind))
  CALL(ABI(sys_connect, sys_oabi_connect))
  CALL(sys_listen)
/* 285 */ CALL(sys_accept)
  CALL(sys_getsockname)
  CALL(sys_getpeername)
  CALL(sys_socketpair)
  CALL(sys_send)
/* 290 */ CALL(ABI(sys_sendto, sys_oabi_sendto))
  CALL(sys_recv)
  CALL(sys_recvfrom)
  CALL(sys_shutdown)
  CALL(sys_setsockopt)
/* 295 */ CALL(sys_getsockopt)
  CALL(ABI(sys_sendmsg, sys_oabi_sendmsg))
  CALL(sys_recvmsg)
  CALL(ABI(sys_semop, sys_oabi_semop))
  CALL(sys_semget)
/* 300 */ CALL(sys_semctl)
  CALL(sys_msgsnd)
  CALL(sys_msgrcv)
  CALL(sys_msgget)
  CALL(sys_msgctl)
/* 305 */ CALL(sys_shmat)
  CALL(sys_shmdt)
  CALL(sys_shmget)
  CALL(sys_shmctl)
  CALL(sys_add_key)
/* 310 */ CALL(sys_request_key)
  CALL(sys_keyctl)
  CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
/* vserver */ CALL(sys_ni_syscall)
  CALL(sys_ioprio_set)
/* 315 */ CALL(sys_ioprio_get)
  CALL(sys_inotify_init)
  CALL(sys_inotify_add_watch)
  CALL(sys_inotify_rm_watch)
  CALL(sys_mbind)
/* 320 */ CALL(sys_get_mempolicy)
  CALL(sys_set_mempolicy)
  CALL(sys_openat)
  CALL(sys_mkdirat)
  CALL(sys_mknodat)
/* 325 */ CALL(sys_fchownat)
  CALL(sys_futimesat)
  CALL(ABI(sys_fstatat64,  sys_oabi_fstatat64))
  CALL(sys_unlinkat)
  CALL(sys_renameat)
/* 330 */ CALL(sys_linkat)
  CALL(sys_symlinkat)
  CALL(sys_readlinkat)
  CALL(sys_fchmodat)
  CALL(sys_faccessat)
/* 335 */ CALL(sys_ni_syscall)  /* eventually pselect6 */
  CALL(sys_ni_syscall)  /* eventually ppoll */
  CALL(sys_unshare)
  CALL(sys_set_robust_list)
  CALL(sys_get_robust_list)
/* 340 */ CALL(sys_splice)
  CALL(sys_sync_file_range2)
  CALL(sys_tee)
  CALL(sys_vmsplice)
  CALL(sys_move_pages)
/* 345 */ CALL(sys_getcpu)
  CALL(sys_ni_syscall)  /* eventually epoll_pwait */
  CALL(sys_kexec_load)
  CALL(sys_utimensat)
  CALL(sys_signalfd)
/* 350 */ CALL(sys_timerfd_create)
  CALL(sys_eventfd)
  CALL(sys_fallocate)
  CALL(sys_timerfd_settime)
  CALL(sys_timerfd_gettime)
/* 355 */ CALL(sys_signalfd4)
  CALL(sys_eventfd2)
  CALL(sys_epoll_create1)
  CALL(sys_dup3)
  CALL(sys_pipe2)
/* 360 */ CALL(sys_inotify_init1)
CALL(sys_ni_syscall) 



/////////////////////////////////////////////////////////////////////////////////////////
摘录自http://blog.csdn.net/liduxun/article/details/48119849

添加自己的系统调用

    开始之前必须说明一下,实际上,是没有任何必要也不应该自己添加一个系统调用,这只是便于理解系统调用的一种方式

     1)内核中增加一个新的函数

       vi arch/arm/kernel/sys_arm.c

  1. asmlinkage int sys_add(int x, int y)  
  2. {  
  3.      printk("enter %s\n", __func__);  
  4.      return x+y;  
  5. }   
//asmlinkage long sys_check_system_type(int *sys_type);等同下
SYSCALL_DEFINE1(check_system_type, int __user *, sys_type)

       注意:该函数必须是全局的,内核编程不能进行浮点数运算 float double

     2)更新unistd.h

       vi arch/arm/include/asm/unistd.h

  1. #define __NR_add   (__NR_SYSCALL_BASE+366)  

     注意:只能添加在所有系统调用号的最后面

     3)更新系统调用表

       vi arch/arm/kernel/calls.S

  1. CALL(sys_add)  

     注意:只能添加在所有CALL的最后面,并且与(2)的调用号相对应。否则一定使系统调用表混乱。

     4)重新编译内核,加载新的内核

     5)编写一个测试程序

  1. #include   
  2. #include   
  3. int main (void)  
  4. {  
  5.     syscall(366, x, y);  
  6.     return 0;  
  7. }
//////////////////////////////////////////////////////////












阅读(69) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册