Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / 对entry-common.S和call.S的部分理解1 - 摩斯电码

对entry-common.S和call.S的部分理解1 - 摩斯电码内核版本: linux-2.6.30.4文件:linux-2.6.30.4/arch/arm/kernel/entry-common.Slinux-2.6.30.4/arch/arm/kernel/calls.Scalls.S:
 1: /*
    2:  *  linux/arch/arm/kernel/calls.S
    3:  *
    4:  *  Copyright (C) 1995-2005 Russell King
    5:  *
    6:  * This program is free software; you can redistribute it and/or modify
    7:  * it under the terms of the GNU General Public License version 2 as
    8:  * published by the Free Software Foundation.
    9:  *
 10:  *  This file is included thrice in entry-common.S
 11:  */
 12: /* 0 */        CALL(sys_restart_syscall)
 13:       CALL(sys_exit)
 14:       CALL(sys_fork_wrapper)
 15:       CALL(sys_read)
 16:       CALL(sys_write)
 17: /* 5 */        CALL(sys_open)
 18:       CALL(sys_close)
 19:       CALL(sys_ni_syscall)        /* was sys_waitpid */
 20:       CALL(sys_creat)
 21:       CALL(sys_link)
 22: /* 10 */    CALL(sys_unlink)
 23:       CALL(sys_execve_wrapper)
 24:       CALL(sys_chdir)
 25:       CALL(OBSOLETE(sys_time))    /* used by libc4 */
 26:       CALL(sys_mknod)
 27: /* 15 */    CALL(sys_chmod)
 28:       CALL(sys_lchown16)
 29:       CALL(sys_ni_syscall)        /* was sys_break */
 30:       CALL(sys_ni_syscall)        /* was sys_stat */
 31:       CALL(sys_lseek)
 32: /* 20 */    CALL(sys_getpid)
 33:       CALL(sys_mount)
 34:       CALL(OBSOLETE(sys_oldumount))    /* used by libc4 */
 35:       CALL(sys_setuid16)
 36:       CALL(sys_getuid16)
 37: /* 25 */    CALL(OBSOLETE(sys_stime))
 38:       CALL(sys_ptrace)
 39:       CALL(OBSOLETE(sys_alarm))    /* used by libc4 */
 40:       CALL(sys_ni_syscall)        /* was sys_fstat */
 41:       CALL(sys_pause)
 42: /* 30 */    CALL(OBSOLETE(sys_utime))    /* used by libc4 */
 43:       CALL(sys_ni_syscall)        /* was sys_stty */
 44:       CALL(sys_ni_syscall)        /* was sys_getty */
 45:       CALL(sys_access)
 46:       CALL(sys_nice)
 47: /* 35 */    CALL(sys_ni_syscall)        /* was sys_ftime */
 48:       CALL(sys_sync)
 49:       CALL(sys_kill)
 50:       CALL(sys_rename)
 51:       CALL(sys_mkdir)
 52: /* 40 */    CALL(sys_rmdir)
 53:       CALL(sys_dup)
 54:       CALL(sys_pipe)
 55:       CALL(sys_times)
 56:       CALL(sys_ni_syscall)        /* was sys_prof */
 57: /* 45 */    CALL(sys_brk)
 58:       CALL(sys_setgid16)
 59:       CALL(sys_getgid16)
 60:       CALL(sys_ni_syscall)        /* was sys_signal */
 61:       CALL(sys_geteuid16)
 62: /* 50 */    CALL(sys_getegid16)
 63:       CALL(sys_acct)
 64:       CALL(sys_umount)
 65:       CALL(sys_ni_syscall)        /* was sys_lock */
 66:       CALL(sys_ioctl)
 67: /* 55 */    CALL(sys_fcntl)
 68:       CALL(sys_ni_syscall)        /* was sys_mpx */
 69:       CALL(sys_setpgid)
 70:       CALL(sys_ni_syscall)        /* was sys_ulimit */
 71:       CALL(sys_ni_syscall)        /* was sys_olduname */
 72: /* 60 */    CALL(sys_umask)
 73:       CALL(sys_chroot)
 74:       CALL(sys_ustat)
 75:       CALL(sys_dup2)
 76:       CALL(sys_getppid)
 77: /* 65 */    CALL(sys_getpgrp)
 78:       CALL(sys_setsid)
 79:       CALL(sys_sigaction)
 80:       CALL(sys_ni_syscall)        /* was sys_sgetmask */
 81:       CALL(sys_ni_syscall)        /* was sys_ssetmask */
 82: /* 70 */    CALL(sys_setreuid16)
 83:       CALL(sys_setregid16)
 84:       CALL(sys_sigsuspend_wrapper)
 85:       CALL(sys_sigpending)
 86:       CALL(sys_sethostname)
 87: /* 75 */    CALL(sys_setrlimit)
 88:       CALL(OBSOLETE(sys_old_getrlimit)) /* used by libc4 */
 89:       CALL(sys_getrusage)
 90:       CALL(sys_gettimeofday)
 91:       CALL(sys_settimeofday)
 92: /* 80 */    CALL(sys_getgroups16)
 93:       CALL(sys_setgroups16)
 94:       CALL(OBSOLETE(old_select))    /* used by libc4 */
 95:       CALL(sys_symlink)
 96:       CALL(sys_ni_syscall)        /* was sys_lstat */
 97: /* 85 */    CALL(sys_readlink)
 98:       CALL(sys_uselib)
 99:       CALL(sys_swapon)
  100:       CALL(sys_reboot)
  101:       CALL(OBSOLETE(sys_old_readdir))    /* used by libc4 */
  102: /* 90 */    CALL(OBSOLETE(old_mmap))    /* used by libc4 */
  103:       CALL(sys_munmap)
  104:       CALL(sys_truncate)
  105:       CALL(sys_ftruncate)
  106:       CALL(sys_fchmod)
  107: /* 95 */    CALL(sys_fchown16)
  108:       CALL(sys_getpriority)
  109:       CALL(sys_setpriority)
  110:       CALL(sys_ni_syscall)        /* was sys_profil */
  111:       CALL(sys_statfs)
  112: /* 100 */    CALL(sys_fstatfs)
  113:       CALL(sys_ni_syscall)        /* sys_ioperm */
  114:       CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
  115:       CALL(sys_syslog)
  116:       CALL(sys_setitimer)
  117: /* 105 */    CALL(sys_getitimer)
  118:       CALL(sys_newstat)
  119:       CALL(sys_newlstat)
  120:       CALL(sys_newfstat)
  121:       CALL(sys_ni_syscall)        /* was sys_uname */
  122: /* 110 */    CALL(sys_ni_syscall)        /* was sys_iopl */
  123:       CALL(sys_vhangup)
  124:       CALL(sys_ni_syscall)
  125:       CALL(OBSOLETE(sys_syscall))    /* call a syscall */
  126:       CALL(sys_wait4)
  127: /* 115 */    CALL(sys_swapoff)
  128:       CALL(sys_sysinfo)
  129:       CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
  130:       CALL(sys_fsync)
  131:       CALL(sys_sigreturn_wrapper)
  132: /* 120 */    CALL(sys_clone_wrapper)
  133:       CALL(sys_setdomainname)
  134:       CALL(sys_newuname)
  135:       CALL(sys_ni_syscall)        /* modify_ldt */
  136:       CALL(sys_adjtimex)
  137: /* 125 */    CALL(sys_mprotect)
  138:       CALL(sys_sigprocmask)
  139:       CALL(sys_ni_syscall)        /* was sys_create_module */
  140:       CALL(sys_init_module)
  141:       CALL(sys_delete_module)
  142: /* 130 */    CALL(sys_ni_syscall)        /* was sys_get_kernel_syms */
  143:       CALL(sys_quotactl)
  144:       CALL(sys_getpgid)
  145:       CALL(sys_fchdir)
  146:       CALL(sys_bdflush)
  147: /* 135 */    CALL(sys_sysfs)
  148:       CALL(sys_personality)
  149:       CALL(sys_ni_syscall)        /* reserved for afs_syscall */
  150:       CALL(sys_setfsuid16)
  151:       CALL(sys_setfsgid16)
  152: /* 140 */    CALL(sys_llseek)
  153:       CALL(sys_getdents)
  154:       CALL(sys_select)
  155:       CALL(sys_flock)
  156:       CALL(sys_msync)
  157: /* 145 */    CALL(sys_readv)
  158:       CALL(sys_writev)
  159:       CALL(sys_getsid)
  160:       CALL(sys_fdatasync)
  161:       CALL(sys_sysctl)
  162: /* 150 */    CALL(sys_mlock)
  163:       CALL(sys_munlock)
  164:       CALL(sys_mlockall)
  165:       CALL(sys_munlockall)
  166:       CALL(sys_sched_setparam)
  167: /* 155 */    CALL(sys_sched_getparam)
  168:       CALL(sys_sched_setscheduler)
  169:       CALL(sys_sched_getscheduler)
  170:       CALL(sys_sched_yield)
  171:       CALL(sys_sched_get_priority_max)
  172: /* 160 */    CALL(sys_sched_get_priority_min)
  173:       CALL(sys_sched_rr_get_interval)
  174:       CALL(sys_nanosleep)
  175:       CALL(sys_arm_mremap)
  176:       CALL(sys_setresuid16)
  177: /* 165 */    CALL(sys_getresuid16)
  178:       CALL(sys_ni_syscall)        /* vm86 */
  179:       CALL(sys_ni_syscall)        /* was sys_query_module */
  180:       CALL(sys_poll)
  181:       CALL(sys_nfsservctl)
  182: /* 170 */    CALL(sys_setresgid16)
  183:       CALL(sys_getresgid16)
  184:       CALL(sys_prctl)
  185:       CALL(sys_rt_sigreturn_wrapper)
  186:       CALL(sys_rt_sigaction)
  187: /* 175 */    CALL(sys_rt_sigprocmask)
  188:       CALL(sys_rt_sigpending)
  189:       CALL(sys_rt_sigtimedwait)
  190:       CALL(sys_rt_sigqueueinfo)
  191:       CALL(sys_rt_sigsuspend_wrapper)
  192: /* 180 */    CALL(ABI(sys_pread64, sys_oabi_pread64))
  193:       CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
  194:       CALL(sys_chown16)
  195:       CALL(sys_getcwd)
  196:       CALL(sys_capget)
  197: /* 185 */    CALL(sys_capset)
  198:       CALL(sys_sigaltstack_wrapper)
  199:       CALL(sys_sendfile)
  200:       CALL(sys_ni_syscall)        /* getpmsg */
  201:       CALL(sys_ni_syscall)        /* putpmsg */
  202: /* 190 */    CALL(sys_vfork_wrapper)
  203:       CALL(sys_getrlimit)
  204:       CALL(sys_mmap2)
  205:       CALL(ABI(sys_truncate64, sys_oabi_truncate64))
  206:       CALL(ABI(sys_ftruncate64, sys_oabi_ftruncate64))
  207: /* 195 */    CALL(ABI(sys_stat64, sys_oabi_stat64))
  208:       CALL(ABI(sys_lstat64, sys_oabi_lstat64))
  209:       CALL(ABI(sys_fstat64, sys_oabi_fstat64))
  210:       CALL(sys_lchown)
  211:       CALL(sys_getuid)
  212: /* 200 */    CALL(sys_getgid)
  213:       CALL(sys_geteuid)
  214:       CALL(sys_getegid)
  215:       CALL(sys_setreuid)
  216:       CALL(sys_setregid)
  217: /* 205 */    CALL(sys_getgroups)
  218:       CALL(sys_setgroups)
  219:       CALL(sys_fchown)
  220:       CALL(sys_setresuid)
  221:       CALL(sys_getresuid)
  222: /* 210 */    CALL(sys_setresgid)
  223:       CALL(sys_getresgid)
  224:       CALL(sys_chown)
  225:       CALL(sys_setuid)
  226:       CALL(sys_setgid)
  227: /* 215 */    CALL(sys_setfsuid)
  228:       CALL(sys_setfsgid)
  229:       CALL(sys_getdents64)
  230:       CALL(sys_pivot_root)
  231:       CALL(sys_mincore)
  232: /* 220 */    CALL(sys_madvise)
  233:       CALL(ABI(sys_fcntl64, sys_oabi_fcntl64))
  234:       CALL(sys_ni_syscall) /* TUX */
  235:       CALL(sys_ni_syscall)
  236:       CALL(sys_gettid)
  237: /* 225 */    CALL(ABI(sys_readahead, sys_oabi_readahead))
  238:       CALL(sys_setxattr)
  239:       CALL(sys_lsetxattr)
  240:       CALL(sys_fsetxattr)
  241:       CALL(sys_getxattr)
  242: /* 230 */    CALL(sys_lgetxattr)
  243:       CALL(sys_fgetxattr)
  244:       CALL(sys_listxattr)
  245:       CALL(sys_llistxattr)
  246:       CALL(sys_flistxattr)
  247: /* 235 */    CALL(sys_removexattr)
  248:       CALL(sys_lremovexattr)
  249:       CALL(sys_fremovexattr)
  250:       CALL(sys_tkill)
  251:       CALL(sys_sendfile64)
  252: /* 240 */    CALL(sys_futex)
  253:       CALL(sys_sched_setaffinity)
  254:       CALL(sys_sched_getaffinity)
  255:       CALL(sys_io_setup)
  256:       CALL(sys_io_destroy)
  257: /* 245 */    CALL(sys_io_getevents)
  258:       CALL(sys_io_submit)
  259:       CALL(sys_io_cancel)
  260:       CALL(sys_exit_group)
  261:       CALL(sys_lookup_dcookie)
  262: /* 250 */    CALL(sys_epoll_create)
  263:       CALL(ABI(sys_epoll_ctl, sys_oabi_epoll_ctl))
  264:       CALL(ABI(sys_epoll_wait, sys_oabi_epoll_wait))
  265:       CALL(sys_remap_file_pages)
  266:       CALL(sys_ni_syscall)    /* sys_set_thread_area */
  267: /* 255 */    CALL(sys_ni_syscall)    /* sys_get_thread_area */
  268:       CALL(sys_set_tid_address)
  269:       CALL(sys_timer_create)
  270:       CALL(sys_timer_settime)
  271:       CALL(sys_timer_gettime)
  272: /* 260 */    CALL(sys_timer_getoverrun)
  273:       CALL(sys_timer_delete)
  274:       CALL(sys_clock_settime)
  275:       CALL(sys_clock_gettime)
  276:       CALL(sys_clock_getres)
  277: /* 265 */    CALL(sys_clock_nanosleep)
  278:       CALL(sys_statfs64_wrapper)
  279:       CALL(sys_fstatfs64_wrapper)
  280:       CALL(sys_tgkill)
  281:       CALL(sys_utimes)
  282: /* 270 */    CALL(sys_arm_fadvise64_64)
  283:       CALL(sys_pciconfig_iobase)
  284:       CALL(sys_pciconfig_read)
  285:       CALL(sys_pciconfig_write)
  286:       CALL(sys_mq_open)
  287: /* 275 */    CALL(sys_mq_unlink)
  288:       CALL(sys_mq_timedsend)
  289:       CALL(sys_mq_timedreceive)
  290:       CALL(sys_mq_notify)
  291:       CALL(sys_mq_getsetattr)
  292: /* 280 */    CALL(sys_waitid)
  293:       CALL(sys_socket)
  294:       CALL(ABI(sys_bind, sys_oabi_bind))
  295:       CALL(ABI(sys_connect, sys_oabi_connect))
  296:       CALL(sys_listen)
  297: /* 285 */    CALL(sys_accept)
  298:       CALL(sys_getsockname)
  299:       CALL(sys_getpeername)
  300:       CALL(sys_socketpair)
  301:       CALL(sys_send)
  302: /* 290 */    CALL(ABI(sys_sendto, sys_oabi_sendto))
  303:       CALL(sys_recv)
  304:       CALL(sys_recvfrom)
  305:       CALL(sys_shutdown)
  306:       CALL(sys_setsockopt)
  307: /* 295 */    CALL(sys_getsockopt)
  308:       CALL(ABI(sys_sendmsg, sys_oabi_sendmsg))
  309:       CALL(sys_recvmsg)
  310:       CALL(ABI(sys_semop, sys_oabi_semop))
  311:       CALL(sys_semget)
  312: /* 300 */    CALL(sys_semctl)
  313:       CALL(sys_msgsnd)
  314:       CALL(sys_msgrcv)
  315:       CALL(sys_msgget)
  316:       CALL(sys_msgctl)
  317: /* 305 */    CALL(sys_shmat)
  318:       CALL(sys_shmdt)
  319:       CALL(sys_shmget)
  320:       CALL(sys_shmctl)
  321:       CALL(sys_add_key)
  322: /* 310 */    CALL(sys_request_key)
  323:       CALL(sys_keyctl)
  324:       CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
  325: /* vserver */    CALL(sys_ni_syscall)
  326:       CALL(sys_ioprio_set)
  327: /* 315 */    CALL(sys_ioprio_get)
  328:       CALL(sys_inotify_init)
  329:       CALL(sys_inotify_add_watch)
  330:       CALL(sys_inotify_rm_watch)
  331:       CALL(sys_mbind)
  332: /* 320 */    CALL(sys_get_mempolicy)
  333:       CALL(sys_set_mempolicy)
  334:       CALL(sys_openat)
  335:       CALL(sys_mkdirat)
  336:       CALL(sys_mknodat)
  337: /* 325 */    CALL(sys_fchownat)
  338:       CALL(sys_futimesat)
  339:       CALL(ABI(sys_fstatat64,  sys_oabi_fstatat64))
  340:       CALL(sys_unlinkat)
  341:       CALL(sys_renameat)
  342: /* 330 */    CALL(sys_linkat)
  343:       CALL(sys_symlinkat)
  344:       CALL(sys_readlinkat)
  345:       CALL(sys_fchmodat)
  346:       CALL(sys_faccessat)
  347: /* 335 */    CALL(sys_ni_syscall)        /* eventually pselect6 */
  348:       CALL(sys_ni_syscall)        /* eventually ppoll */
  349:       CALL(sys_unshare)
  350:       CALL(sys_set_robust_list)
  351:       CALL(sys_get_robust_list)
  352: /* 340 */    CALL(sys_splice)
  353:       CALL(sys_sync_file_range2)
  354:       CALL(sys_tee)
  355:       CALL(sys_vmsplice)
  356:       CALL(sys_move_pages)
  357: /* 345 */    CALL(sys_getcpu)
  358:       CALL(sys_ni_syscall)        /* eventually epoll_pwait */
  359:       CALL(sys_kexec_load)
  360:       CALL(sys_utimensat)
  361:       CALL(sys_signalfd)
  362: /* 350 */    CALL(sys_timerfd_create)
  363:       CALL(sys_eventfd)
  364:       CALL(sys_fallocate)
  365:       CALL(sys_timerfd_settime)
  366:       CALL(sys_timerfd_gettime)
  367: /* 355 */    CALL(sys_signalfd4)
  368:       CALL(sys_eventfd2)
  369:       CALL(sys_epoll_create1)
  370:       CALL(sys_dup3)
  371:       CALL(sys_pipe2)
  372: /* 360 */    CALL(sys_inotify_init1)
  373:       CALL(sys_preadv)
  374:       CALL(sys_pwritev)
  375: #ifndef syscalls_counted
  376: .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
  377: #define syscalls_counted
  378: #endif
  379: .rept syscalls_padding
  380:       CALL(sys_ni_syscall)
  381: .endrentry-common.S
 1: /*
    2:  *  linux/arch/arm/kernel/entry-common.S
    3:  *
    4:  *  Copyright (C) 2000 Russell King
    5:  *
    6:  * This program is free software; you can redistribute it and/or modify
    7:  * it under the terms of the GNU General Public License version 2 as
    8:  * published by the Free Software Foundation.
    9:  */
 10: 
 11: #include <asm/unistd.h>
 12: #include <asm/ftrace.h>
 13: #include <mach/entry-macro.S>
 14: #include <asm/unwind.h>
 15: 
 16: #include "entry-header.S"
 17: 
 18: 
 19:   .align    5
 20: /*
 21:  * This is the fast syscall return path.  We do as little as
 22:  * possible here, and this includes saving r0 back into the SVC
 23:  * stack.
 24:  */
 25: ret_fast_syscall:
 26:  UNWIND(.fnstart    )
 27:  UNWIND(.cantunwind    )
 28:   disable_irq                @ disable interrupts
 29:   ldr    r1, [tsk, #TI_FLAGS]
 30:   tst    r1, #_TIF_WORK_MASK
 31:   bne    fast_work_pending
 32: 
 33:   /* perform architecture specific actions before user return */
 34:   arch_ret_to_user r1, lr
 35: 
 36:   @ fast_restore_user_regs
 37:   ldr    r1, [sp, #S_OFF + S_PSR]    @ get calling cpsr
 38:   ldr    lr, [sp, #S_OFF + S_PC]!    @ get pc
 39:   msr    spsr_cxsf, r1            @ save in spsr_svc
 40:   ldmdb    sp, {r1 - lr}^            @ get calling r1 - lr
 41:   mov    r0, r0
 42:   add    sp, sp, #S_FRAME_SIZE - S_PC
 43:   movs    pc, lr                @ return & move spsr_svc into cpsr
 44:  UNWIND(.fnend        )
 45: 
 46: /*
 47:  * Ok, we need to do extra processing, enter the slow path.
 48:  */
 49: fast_work_pending:
 50:   str    r0, [sp, #S_R0+S_OFF]!        @ returned r0
 51: work_pending:
 52:   tst    r1, #_TIF_NEED_RESCHED
 53:   bne    work_resched
 54:   tst    r1, #_TIF_SIGPENDING
 55:   beq    no_work_pending
 56:   mov    r0, sp                @ "regs"
 57:   mov    r2, why                @ "syscall"
 58:   bl    do_notify_resume
 59:   b    ret_slow_syscall        @ Check work again
 60: 
 61: work_resched:
 62:   bl    schedule
 63: /*
 64:  * "slow" syscall return path.  "why" tells us if this was a real syscall.
 65:  */
 66: ENTRY(ret_to_user)
 67: ret_slow_syscall:
 68:   disable_irq                @ disable interrupts
 69:   ldr    r1, [tsk, #TI_FLAGS]
 70:   tst    r1, #_TIF_WORK_MASK
 71:   bne    work_pending
 72: no_work_pending:
 73:   /* perform architecture specific actions before user return */
 74:   arch_ret_to_user r1, lr
 75: 
 76:   @ slow_restore_user_regs
 77:   ldr    r1, [sp, #S_PSR]        @ get calling cpsr
 78:   ldr    lr, [sp, #S_PC]!        @ get pc
 79:   msr    spsr_cxsf, r1            @ save in spsr_svc
 80:   ldmdb    sp, {r0 - lr}^            @ get calling r0 - lr
 81:   mov    r0, r0
 82:   add    sp, sp, #S_FRAME_SIZE - S_PC
 83:   movs    pc, lr                @ return & move spsr_svc into cpsr
 84: ENDPROC(ret_to_user)
 85: 
 86: /*
 87:  * This is how we return from a fork.
 88:  */
 89: ENTRY(ret_from_fork)
 90:   bl    schedule_tail
 91:   get_thread_info tsk
 92:   ldr    r1, [tsk, #TI_FLAGS]        @ check for syscall tracing
 93:   mov    why, #1
 94:   tst    r1, #_TIF_SYSCALL_TRACE        @ are we tracing syscalls?
 95:   beq    ret_slow_syscall
 96:   mov    r1, sp
 97:   mov    r0, #1                @ trace exit [IP = 1]
 98:   bl    syscall_trace
 99:   b    ret_slow_syscall
  100: ENDPROC(ret_from_fork)
  101: 
  102:   .equ NR_syscalls,0
  103: #define CALL(x) .equ NR_syscalls,NR_syscalls+1
  104: #include "calls.S"
  105: #undef CALL
  106: #define CALL(x) .long x
  107: 
  108: #ifdef CONFIG_FUNCTION_TRACER
  109: #ifdef CONFIG_DYNAMIC_FTRACE
  110: ENTRY(mcount)
  111:   stmdb sp!, {r0-r3, lr}
  112:   mov r0, lr
  113:   sub r0, r0, #MCOUNT_INSN_SIZE
  114: 
  115:   .globl mcount_call
  116: mcount_call:
  117:   bl ftrace_stub
  118:   ldr lr, [fp, #-4]            @ restore lr
  119:   ldmia sp!, {r0-r3, pc}
  120: 
  121: ENTRY(ftrace_caller)
  122:   stmdb sp!, {r0-r3, lr}
  123:   ldr r1, [fp, #-4]
  124:   mov r0, lr
  125:   sub r0, r0, #MCOUNT_INSN_SIZE
  126: 
  127:   .globl ftrace_call
  128: ftrace_call:
  129:   bl ftrace_stub
  130:   ldr lr, [fp, #-4]            @ restore lr
  131:   ldmia sp!, {r0-r3, pc}
  132: 
  133: #else
  134: 
  135: ENTRY(mcount)
  136:   stmdb sp!, {r0-r3, lr}
  137:   ldr r0, =ftrace_trace_function
  138:   ldr r2, [r0]
  139:   adr r0, ftrace_stub
  140:   cmp r0, r2
  141:   bne trace
  142:   ldr lr, [fp, #-4]            @ restore lr
  143:   ldmia sp!, {r0-r3, pc}
  144: 
  145: trace:
  146:   ldr r1, [fp, #-4]            @ lr of instrumented routine
  147:   mov r0, lr
  148:   sub r0, r0, #MCOUNT_INSN_SIZE
  149:   mov lr, pc
  150:   mov pc, r2
  151:   mov lr, r1                @ restore lr
  152:   ldmia sp!, {r0-r3, pc}
  153: 
  154: #endif /* CONFIG_DYNAMIC_FTRACE */
  155: 
  156:   .globl ftrace_stub
  157: ftrace_stub:
  158:   mov pc, lr
  159: 
  160: #endif /* CONFIG_FUNCTION_TRACER */
  161: 
  162: /*=============================================================================
  163:  * SWI handler
  164:  *-----------------------------------------------------------------------------
  165:  */
  166: 
  167:   /* If we"re optimising for StrongARM the resulting code won"t
  168:        run on an ARM7 and we can save a couple of instructions. 
  169:                               --pb */
  170: #ifdef CONFIG_CPU_ARM710
  171: #define A710(code...) code
  172: .Larm710bug:
  173:   ldmia    sp, {r0 - lr}^            @ Get calling r0 - lr
  174:   mov    r0, r0
  175:   add    sp, sp, #S_FRAME_SIZE
  176:   subs    pc, lr, #4
  177: #else
  178: #define A710(code...)
  179: #endif
  180: 
  181:   .align    5
  182: ENTRY(vector_swi)
  183:   sub    sp, sp, #S_FRAME_SIZE
  184:   stmia    sp, {r0 - r12}            @ Calling r0 - r12
  185:   add    r8, sp, #S_PC
  186:   stmdb    r8, {sp, lr}^            @ Calling sp, lr
  187:   mrs    r8, spsr            @ called from non-FIQ mode, so ok.
  188:   str    lr, [sp, #S_PC]            @ Save calling PC
  189:   str    r8, [sp, #S_PSR]        @ Save CPSR
  190:   str    r0, [sp, #S_OLD_R0]        @ Save OLD_R0
  191:   zero_fp
  192: 
  193:   /*
  194:      * Get the system call number.
  195:      */
  196: 
  197: #if defined(CONFIG_OABI_COMPAT)
  198: 
  199:   /*
  200:      * If we have CONFIG_OABI_COMPAT then we need to look at the swi
  201:      * value to determine if it is an EABI or an old ABI call.
  202:      */
  203: #ifdef CONFIG_ARM_THUMB
  204:   tst    r8, #PSR_T_BIT
  205:   movne    r10, #0                @ no thumb OABI emulation
  206:   ldreq    r10, [lr, #-4]            @ get SWI instruction
  207: #else
  208:   ldr    r10, [lr, #-4]            @ get SWI instruction
  209: A710(    and    ip, r10, #0x0f000000        @ check for SWI        )
  210: A710(    teq    ip, #0x0f000000                        )
  211: A710(    bne    .Larm710bug                        )
  212: #endif
  213: 
  214: #elif defined(CONFIG_AEABI)
  215: 
  216:   /*
  217:      * Pure EABI user space always put syscall number into scno (r7).
  218:      */
  219: A710(    ldr    ip, [lr, #-4]            @ get SWI instruction    )
  220: A710(    and    ip, ip, #0x0f000000        @ check for SWI        )
  221: A710(    teq    ip, #0x0f000000                        )
  222: A710(    bne    .Larm710bug                        )
  223: 
  224: #elif defined(CONFIG_ARM_THUMB)
  225: 
  226:   /* Legacy ABI only, possibly thumb mode. */
  227:   tst    r8, #PSR_T_BIT            @ this is SPSR from save_user_regs
  228:   addne    scno, r7, #__NR_SYSCALL_BASE    @ put OS number in
  229:   ldreq    scno, [lr, #-4]
  230: 
  231: #else
  232: 
  233:   /* Legacy ABI only. */
  234:   ldr    scno, [lr, #-4]            @ get SWI instruction
  235: A710(    and    ip, scno, #0x0f000000        @ check for SWI        )
  236: A710(    teq    ip, #0x0f000000                        )
  237: A710(    bne    .Larm710bug                        )
  238: 
  239: #endif
  240: 
  241: #ifdef CONFIG_ALIGNMENT_TRAP
  242:   ldr    ip, __cr_alignment
  243:   ldr    ip, [ip]
  244:   mcr    p15, 0, ip, c1, c0        @ update control register
  245: #endif
  246:   enable_irq
  247: 
  248:   get_thread_info tsk
  249:   adr    tbl, sys_call_table        @ load syscall table pointer
  250:   ldr    ip, [tsk, #TI_FLAGS]        @ check for syscall tracing
  251: 
  252: #if defined(CONFIG_OABI_COMPAT)
  253:   /*
  254:      * If the swi argument is zero, this is an EABI call and we do nothing.
  255:      *
  256:      * If this is an old ABI call, get the syscall number into scno and
  257:      * get the old ABI syscall table address.
  258:      */
  259:   bics    r10, r10, #0xff000000
  260:   eorne    scno, r10, #__NR_OABI_SYSCALL_BASE
  261:   ldrne    tbl, =sys_oabi_call_table
  262: #elif !defined(CONFIG_AEABI)
  263:   bic    scno, scno, #0xff000000        @ mask off SWI op-code
  264:   eor    scno, scno, #__NR_SYSCALL_BASE    @ check OS number
  265: #endif
  266: 
  267:   stmdb    sp!, {r4, r5}            @ push fifth and sixth args
  268:   tst    ip, #_TIF_SYSCALL_TRACE        @ are we tracing syscalls?
  269:   bne    __sys_trace
  270: 
  271:   cmp    scno, #NR_syscalls        @ check upper syscall limit
  272:   adr    lr, ret_fast_syscall        @ return address
  273:   ldrcc    pc, [tbl, scno, lsl #2]        @ call sys_* routine
  274: 
  275:   add    r1, sp, #S_OFF
  276: 2:    mov    why, #0                @ no longer a real syscall
  277:   cmp    scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
  278:   eor    r0, scno, #__NR_SYSCALL_BASE    @ put OS number back
  279:   bcs    arm_syscall   
  280:   b    sys_ni_syscall            @ not private func
  281: ENDPROC(vector_swi)
  282: 
  283:   /*
  284:      * This is the really slow path.  We"re going to be doing
  285:      * context switches, and waiting for our parent to respond.
  286:      */
  287: __sys_trace:
  288:   mov    r2, scno
  289:   add    r1, sp, #S_OFF
  290:   mov    r0, #0                @ trace entry [IP = 0]
  291:   bl    syscall_trace
  292: 
  293:   adr    lr, __sys_trace_return        @ return address
  294:   mov    scno, r0            @ syscall number (possibly new)
  295:   add    r1, sp, #S_R0 + S_OFF        @ pointer to regs
  296:   cmp    scno, #NR_syscalls        @ check upper syscall limit
  297:   ldmccia    r1, {r0 - r3}            @ have to reload r0 - r3
  298:   ldrcc    pc, [tbl, scno, lsl #2]        @ call sys_* routine
  299:   b    2b
  300: 
  301: __sys_trace_return:
  302:   str    r0, [sp, #S_R0 + S_OFF]!    @ save returned r0
  303:   mov    r2, scno
  304:   mov    r1, sp
  305:   mov    r0, #1                @ trace exit [IP = 1]
  306:   bl    syscall_trace
  307:   b    ret_slow_syscall
  308: 
  309:   .align    5
  310: #ifdef CONFIG_ALIGNMENT_TRAP
  311:   .type    __cr_alignment, #object
  312: __cr_alignment:
  313:   .word    cr_alignment
  314: #endif
  315:   .ltorg
  316: 
  317: /*
  318:  * This is the syscall table declaration for native ABI syscalls.
  319:  * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
  320:  */
  321: #define ABI(native, compat) native
  322: #ifdef CONFIG_AEABI
  323: #define OBSOLETE(syscall) sys_ni_syscall
  324: #else
  325: #define OBSOLETE(syscall) syscall
  326: #endif
  327: 
  328:   .type    sys_call_table, #object
  329: ENTRY(sys_call_table)
  330: #include "calls.S"
  331: #undef ABI
  332: #undef OBSOLETE
  333: 
  334: /*============================================================================
  335:  * Special system call wrappers
  336:  */
  337: @ r0 = syscall number
  338: @ r8 = syscall table
  339: sys_syscall:
  340:       bic    scno, r0, #__NR_OABI_SYSCALL_BASE
  341:       cmp    scno, #__NR_syscall - __NR_SYSCALL_BASE
  342:       cmpne    scno, #NR_syscalls    @ check range
  343:       stmloia    sp, {r5, r6}        @ shuffle args
  344:       movlo    r0, r1
  345:       movlo    r1, r2
  346:       movlo    r2, r3
  347:       movlo    r3, r4
  348:       ldrlo    pc, [tbl, scno, lsl #2]
  349:       b    sys_ni_syscall
  350: ENDPROC(sys_syscall)
  351: 
  352: sys_fork_wrapper:
  353:       add    r0, sp, #S_OFF
  354:       b    sys_fork
  355: ENDPROC(sys_fork_wrapper)
  356: 
  357: sys_vfork_wrapper:
  358:       add    r0, sp, #S_OFF
  359:       b    sys_vfork
  360: ENDPROC(sys_vfork_wrapper)
  361: 
  362: sys_execve_wrapper:
  363:       add    r3, sp, #S_OFF
  364:       b    sys_execve
  365: ENDPROC(sys_execve_wrapper)
  366: 
  367: sys_clone_wrapper:
  368:       add    ip, sp, #S_OFF
  369:       str    ip, [sp, #4]
  370:       b    sys_clone
  371: ENDPROC(sys_clone_wrapper)
  372: 
  373: sys_sigsuspend_wrapper:
  374:       add    r3, sp, #S_OFF
  375:       b    sys_sigsuspend
  376: ENDPROC(sys_sigsuspend_wrapper)
  377: 
  378: sys_rt_sigsuspend_wrapper:
  379:       add    r2, sp, #S_OFF
  380:       b    sys_rt_sigsuspend
  381: ENDPROC(sys_rt_sigsuspend_wrapper)
  382: 
  383: sys_sigreturn_wrapper:
  384:       add    r0, sp, #S_OFF
  385:       b    sys_sigreturn
  386: ENDPROC(sys_sigreturn_wrapper)
  387: 
  388: sys_rt_sigreturn_wrapper:
  389:       add    r0, sp, #S_OFF
  390:       b    sys_rt_sigreturn
  391: ENDPROC(sys_rt_sigreturn_wrapper)
  392: 
  393: sys_sigaltstack_wrapper:
  394:       ldr    r2, [sp, #S_OFF + S_SP]
  395:       b    do_sigaltstack
  396: ENDPROC(sys_sigaltstack_wrapper)
  397: 
  398: sys_statfs64_wrapper:
  399:       teq    r1, #88
  400:       moveq    r1, #84
  401:       b    sys_statfs64
  402: ENDPROC(sys_statfs64_wrapper)
  403: 
  404: sys_fstatfs64_wrapper:
  405:       teq    r1, #88
  406:       moveq    r1, #84
  407:       b    sys_fstatfs64
  408: ENDPROC(sys_fstatfs64_wrapper)
  409: 
  410: /*
  411:  * Note: off_4k (r5) is always units of 4K.  If we can"t do the requested
  412:  * offset, we return EINVAL.
  413:  */
  414: sys_mmap2:
  415: #if PAGE_SHIFT > 12
  416:       tst    r5, #PGOFF_MASK
  417:       moveq    r5, r5, lsr #PAGE_SHIFT - 12
  418:       streq    r5, [sp, #4]
  419:       beq    do_mmap2
  420:       mov    r0, #-EINVAL
  421:       mov    pc, lr
  422: #else
  423:       str    r5, [sp, #4]
  424:       b    do_mmap2
  425: #endif
  426: ENDPROC(sys_mmap2)
  427: 
  428: ENTRY(pabort_ifar)
  429:       mrc    p15, 0, r0, cr6, cr0, 2
  430: ENTRY(pabort_noifar)
  431:       mov    pc, lr
  432: ENDPROC(pabort_ifar)
  433: ENDPROC(pabort_noifar)
  434: 
  435: #ifdef CONFIG_OABI_COMPAT
  436: 
  437: /*
  438:  * These are syscalls with argument register differences
  439:  */
  440: 
  441: sys_oabi_pread64:
  442:       stmia    sp, {r3, r4}
  443:       b    sys_pread64
  444: ENDPROC(sys_oabi_pread64)
  445: 
  446: sys_oabi_pwrite64:
  447:       stmia    sp, {r3, r4}
  448:       b    sys_pwrite64
  449: ENDPROC(sys_oabi_pwrite64)
  450: 
  451: sys_oabi_truncate64:
  452:       mov    r3, r2
  453:       mov    r2, r1
  454:       b    sys_truncate64
  455: ENDPROC(sys_oabi_truncate64)
  456: 
  457: sys_oabi_ftruncate64:
  458:       mov    r3, r2
  459:       mov    r2, r1
  460:       b    sys_ftruncate64
  461: ENDPROC(sys_oabi_ftruncate64)
  462: 
  463: sys_oabi_readahead:
  464:       str    r3, [sp]
  465:       mov    r3, r2
  466:       mov    r2, r1
  467:       b    sys_readahead
  468: ENDPROC(sys_oabi_readahead)
  469: 
  470: /*
  471:  * Let"s declare a second syscall table for old ABI binaries
  472:  * using the compatibility syscall entries.
  473:  */
  474: #define ABI(native, compat) compat
  475: #define OBSOLETE(syscall) syscall
  476: 
  477:   .type    sys_oabi_call_table, #object
  478: ENTRY(sys_oabi_call_table)
  479: #include "calls.S"
  480: #undef ABI
  481: #undef OBSOLETE
  482: 
  483: #endif
  484: 在entry-common.S中包含了上次calls.S,这里简单分析前两次:第一次:在entry-common.S中:
 1: .equ NR_syscalls,0
    2: #define CALL(x) .equ NR_syscalls,NR_syscalls+1
    3: #include "calls.S"
    4: #undef CALL
    5: #define CALL(x) .long x在calls.S的结尾:
 1: CALL(sys_preadv)
    2: CALL(sys_pwritev)
    3: #ifndef syscalls_counted
    4: .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
    5: #define syscalls_counted
    6: #endif
    7: .rept syscalls_padding
    8: CALL(sys_ni_syscall)
    9: .endr分析:.equ NR_syscalls,0    中涉及到汇编指令.equ:
.equ/.set: 赋值语句, 格式如下:  .equ(.set) 变量名,表达式
  例如:
  .equ abc 3 @让abc=3
这里只是定义了一个变量NR_syscalls,并将其初始化为0。可以理解为: NR_syscalls = 0#define CALL(x) .equ NR_syscalls,NR_syscalls+1  即 将CALL(x) 定义为: NR_syscalls = NR_syscalls  + 1#include "calls.S"    将calls.S的内容包进来,因为上面对CALL(x)进行了定义所以相当于执行了多次NR_syscalls++,相当于统计了系统调用的个数,但是注意:在calls.S的结尾的对齐处理:#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
#endif
.rept syscalls_padding
        CALL(sys_ni_syscall)
.endr
由于是第一次包含,故syscalls_counted没有定义,
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls为了保证NR_syscalls是4的整数倍,上面的语句相当于:syscalls_padding = ((NR_syscalls + 3) & ~3) - NR_syscalls;即:假如NR_syscalls 是1,那么syscalls_padding 就是3
 .rept syscalls_padding
        CALL(sys_ni_syscall)
      .endr 这里涉及到汇编指令.rept的用法:
.rept:重复定义伪操作, 格式如下:
 .rept 重复次数
 数据定义
.endr @结束重复定义
 例如:
 .rept 3
 .byte 0x23
 .endr 
继续上面的例子:syscalls_padding 为3,那么上面的rept语句块相当于:CALL(sys_ni_syscall)CALL(sys_ni_syscall)CALL(sys_ni_syscall)即又执行了三次:NR_syscalls++,此时NR_syscalls就变成了4,对齐了。 第二次:
 1: .type    sys_call_table, #object
    2: ENTRY(sys_call_table)
    3: #include "calls.S"
    4: #undef ABI
    5: #undef OBSOLETE
    6: 
    7: 
    8: @r0 = syscall number
    9: @r8 = syscall table
 10: sys_syscall:
 11:   bic    scno, r0, #__NR_OABI_SYSCALL_BASE
 12:   cmp    scno, #__NR_syscall - __NR_SYSCALL_BASE
 13:   cmpne    scno, #NR_syscalls    @ check range
 14:   stmloia    sp, {r5, r6}        @ shuffle args
 15:   movlo    r0, r1
 16:   movlo    r1, r2
 17:   movlo    r2, r3
 18:   movlo    r3, r4
 19:   ldrlo    pc, [tbl, scno, lsl #2]
 20:   b    sys_ni_syscall
 21: ENDPROC(sys_syscall)第二次包含是建立在第一次包含的基础上,第一次包含的结果是:
•#undef CALL   
•#define CALL(x) .long x
•NR_syscalls 是系统调用的个数,并且进行了4的倍数对齐(最后几个系统调用可能只是为了凑数)
•syscalls_padding的数值保证了CALL(x)的个数可以4倍对齐,即.long x 的个数是4的倍数。目的是在下面的sys_syscall函数中的:
ldrlo    pc, [tbl, scno, lsl #2]即将“系统调用表基地址tbl+系统调用号scno*4”地址单元(上面的某个.long x)的数据(也就是某个系统调用处理函数的入口地址)放到PC寄存器中(因为有了对齐,所以不会产生访问越界的情况,又因为cmp    scno, #__NR_syscall - __NR_SYSCALL_BASE
      cmpne    scno, #NR_syscalls    @ check range以上两条语句保证了系统调用号scno的大小不会超出范围)。可以看到,在calls.S结尾的系统调用:sys_ni_syscall。它除了返回-ENOSYS之外啥也没干:
 1: /*
    2:  * Non-implemented system calls get redirected here.
    3:  */
    4: asmlinkage long sys_ni_syscall(void)
    5: {
    6:   return -ENOSYS;
    7: }本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-02/112909.htm