对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: }

上一篇:用CSS3实现文字描边


下一篇:Infopath 2010 接收SQL Server数据