对entry-common.S和call.S的部分理解1

 

内核版本: linux-2.6.30.4

文件:

linux-2.6.30.4/arch/arm/kernel/entry-common.S

linux-2.6.30.4/arch/arm/kernel/calls.S

calls.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: .endr

entry-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: }
posted @ 2014-05-07 23:01  摩斯电码  阅读(1535)  评论(0编辑  收藏  举报