• 对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: }
  • 相关阅读:
    .NET Core 服务调用 RPC
    从Docker 到 Kubernatetes 的跃迁之路
    同步异步-多线程梳理
    Net的微服务选型之路
    Visual Studio 2019安装SSIS
    HL7协议的基本语法
    vue学习笔记
    开发常用的部分sql语句总结
    VSPD虚拟串口来调试通信接口程序
    SSRS报表工具之合并行数据
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/3714981.html
Copyright © 2020-2023  润新知