📄 entry.s
字号:
* this allows them to save the stack-pointer and use that register to do an * indirect jump). */G_ENTRY(nmi): SAVE_STATE (NMI, r0, NMI_ENTRY_SP); /* Save registers. */ stsr SR_ECR, r6; /* Find out which nmi it was. */ shr 20, r6; /* Extract NMI code in bits 20-24. */ movea PTO, sp, r7; /* User regs are arg2. */ /* Non-maskable interrupts always lie right after maskable interrupts. Call the generic IRQ handler, with two arguments, the IRQ number, and a pointer to the user registers, to handle the specifics. (we subtract one because the first NMI has code 1). */ addi FIRST_NMI - 1, r6, r6 jarl CSYM(handle_irq), lp RETURN(NMI)END(nmi)/* * Trap with no handler */L_ENTRY(bad_trap_wrapper): mov r19, r6 // Arg 0: trap number movea PTO, sp, r7 // Arg 1: user regs jr CSYM(bad_trap) // tail call handlerEND(bad_trap_wrapper)/* * Invoke the scheduler, called from the trap/irq kernel exit path. * * This basically just calls `schedule', but also arranges for extra * registers to be saved for ptrace'd processes, so ptrace can modify them. */L_ENTRY(call_scheduler): ld.w TASK_PTRACE[CURRENT_TASK], r19 // See if task is ptrace'd cmp r19, r0 bnz 1f // ... yes, do special stuff jr CSYM(schedule) // ... no, just tail-call scheduler // Save extra regs for ptrace'd task. We want to save anything // that would otherwise only be `implicitly' saved by the normal // compiler calling-convention.1: mov sp, ep // Setup EP for SAVE_CALL_SAVED_REGS SAVE_CALL_SAVED_REGS // Save call-saved registers to stack mov lp, r20 // Save LP in a callee-saved register jarl CSYM(schedule), lp // Call scheduler mov r20, lp mov sp, ep // We can't rely on EP after return RESTORE_CALL_SAVED_REGS // Restore (possibly modified) regs jmp [lp] // Return to the return pathEND(call_scheduler)/* * This is an out-of-line handler for two special cases during the kernel * trap/irq exit sequence: * * (1) If r18 is non-zero then a signal needs to be handled, which is * done, and then the caller returned to. * * (2) If r18 is non-zero then we're returning to a ptraced process, which * has several special cases -- single-stepping and trap tracing, both * of which require using the `dbret' instruction to exit the kernel * instead of the normal `reti' (this is because the CPU not correctly * single-step after a reti). In this case, of course, this handler * never returns to the caller. * * In either case, all registers should have been saved to the current * state-save-frame on the stack, except for callee-saved registers. * * [These two different cases are combined merely to avoid bloating the * macro-inlined code, not because they really make much sense together!] */L_ENTRY(handle_signal_or_ptrace_return): cmp r18, r0 // See if handling a signal bz 1f // ... nope, go do ptrace return // Handle a signal mov lp, r20 // Save link-pointer mov r10, r21 // Save return-values (for trap) mov r11, r22 movea PTO, sp, r6 // Arg 1: struct pt_regs *regs mov r0, r7 // Arg 2: sigset_t *oldset jarl CSYM(do_signal), lp // Handle the signal di // sig handling enables interrupts mov r20, lp // Restore link-pointer mov r21, r10 // Restore return-values (for trap) mov r22, r11 ld.w TASK_PTRACE[CURRENT_TASK], r19 // check ptrace flags too cmp r19, r0 bnz 1f // ... some set, so look more2: jmp [lp] // ... none set, so return normally // ptrace return1: ld.w PTO+PT_PSW[sp], r19 // Look at user-processes's flags andi 0x0800, r19, r19 // See if single-step flag is set bz 2b // ... nope, return normally // Return as if from a dbtrap insn st.b r0, KM // Now officially in user state. POP_STATE(DBTRAP) // Restore regs st.w sp, KSP // Save the kernel stack pointer. ld.w PT_GPR(GPR_SP)-PT_SIZE[sp], sp // Restore user stack pointer. DBTRAP_RET // Return from the trap/interrupt.END(handle_signal_or_ptrace_return)/* * This is where we switch between two threads. The arguments are: * r6 -- pointer to the struct thread for the `current' process * r7 -- pointer to the struct thread for the `new' process. * when this function returns, it will return to the new thread. */C_ENTRY(switch_thread): // Return the previous task (r10 is not clobbered by restore below) mov CURRENT_TASK, r10 // First, push the current processor state on the stack PUSH_STATE(SWITCH) // Now save the location of the kernel stack pointer for this thread; // since we've pushed all other state on the stack, this is enough to // restore it all later. st.w sp, THREAD_KSP[r6] // Now restore the stack pointer from the new process ld.w THREAD_KSP[r7], sp // ... and restore all state from that POP_STATE(SWITCH) // Update the current task pointer GET_CURRENT_TASK(CURRENT_TASK) // Now return into the new thread jmp [lp]C_END(switch_thread) .data .align 4C_DATA(trap_table): .long bad_trap_wrapper // trap 0, doesn't use trap table. .long syscall_long // trap 1, `long' syscall. .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapper .long bad_trap_wrapperC_END(trap_table) .section .rodata .align 4C_DATA(sys_call_table): .long CSYM(sys_restart_syscall) // 0 .long CSYM(sys_exit) .long sys_fork_wrapper .long CSYM(sys_read) .long CSYM(sys_write) .long CSYM(sys_open) // 5 .long CSYM(sys_close) .long CSYM(sys_waitpid) .long CSYM(sys_creat) .long CSYM(sys_link) .long CSYM(sys_unlink) // 10 .long sys_execve_wrapper .long CSYM(sys_chdir) .long CSYM(sys_time) .long CSYM(sys_mknod) .long CSYM(sys_chmod) // 15 .long CSYM(sys_chown) .long CSYM(sys_ni_syscall) // was: break .long CSYM(sys_ni_syscall) // was: oldstat (aka stat) .long CSYM(sys_lseek) .long CSYM(sys_getpid) // 20 .long CSYM(sys_mount) .long CSYM(sys_oldumount) .long CSYM(sys_setuid) .long CSYM(sys_getuid) .long CSYM(sys_stime) // 25 .long CSYM(sys_ptrace) .long CSYM(sys_alarm) .long CSYM(sys_ni_syscall) // was: oldfstat (aka fstat) .long CSYM(sys_pause) .long CSYM(sys_utime) // 30 .long CSYM(sys_ni_syscall) // was: stty .long CSYM(sys_ni_syscall) // was: gtty .long CSYM(sys_access) .long CSYM(sys_nice) .long CSYM(sys_ni_syscall) // 35, was: ftime .long CSYM(sys_sync) .long CSYM(sys_kill) .long CSYM(sys_rename) .long CSYM(sys_mkdir) .long CSYM(sys_rmdir) // 40 .long CSYM(sys_dup) .long CSYM(sys_pipe) .long CSYM(sys_times) .long CSYM(sys_ni_syscall) // was: prof .long CSYM(sys_brk) // 45 .long CSYM(sys_setgid) .long CSYM(sys_getgid) .long CSYM(sys_signal) .long CSYM(sys_geteuid) .long CSYM(sys_getegid) // 50 .long CSYM(sys_acct) .long CSYM(sys_umount) // recycled never used phys() .long CSYM(sys_ni_syscall) // was: lock .long CSYM(sys_ioctl) .long CSYM(sys_fcntl) // 55 .long CSYM(sys_ni_syscall) // was: mpx .long CSYM(sys_setpgid) .long CSYM(sys_ni_syscall) // was: ulimit .long CSYM(sys_ni_syscall) .long CSYM(sys_umask) // 60 .long CSYM(sys_chroot) .long CSYM(sys_ustat) .long CSYM(sys_dup2) .long CSYM(sys_getppid) .long CSYM(sys_getpgrp) // 65 .long CSYM(sys_setsid) .long CSYM(sys_sigaction) .long CSYM(sys_sgetmask) .long CSYM(sys_ssetmask) .long CSYM(sys_setreuid) // 70 .long CSYM(sys_setregid) .long sys_sigsuspend_wrapper .long CSYM(sys_sigpending) .long CSYM(sys_sethostname) .long CSYM(sys_setrlimit) // 75 .long CSYM(sys_getrlimit) .long CSYM(sys_getrusage) .long CSYM(sys_gettimeofday) .long CSYM(sys_settimeofday) .long CSYM(sys_getgroups) // 80 .long CSYM(sys_setgroups) .long CSYM(sys_select) .long CSYM(sys_symlink) .long CSYM(sys_ni_syscall) // was: oldlstat (aka lstat) .long CSYM(sys_readlink) // 85 .long CSYM(sys_uselib) .long CSYM(sys_swapon) .long CSYM(sys_reboot) .long CSYM(old_readdir) .long CSYM(sys_mmap) // 90 .long CSYM(sys_munmap) .long CSYM(sys_truncate) .long CSYM(sys_ftruncate) .long CSYM(sys_fchmod) .long CSYM(sys_fchown) // 95 .long CSYM(sys_getpriority) .long CSYM(sys_setpriority) .long CSYM(sys_ni_syscall) // was: profil .long CSYM(sys_statfs) .long CSYM(sys_fstatfs) // 100 .long CSYM(sys_ni_syscall) // i386: ioperm .long CSYM(sys_socketcall) .long CSYM(sys_syslog) .long CSYM(sys_setitimer) .long CSYM(sys_getitimer) // 105 .long CSYM(sys_newstat) .long CSYM(sys_newlstat) .long CSYM(sys_newfstat) .long CSYM(sys_ni_syscall) // was: olduname (aka uname) .long CSYM(sys_ni_syscall) // 110, i386: iopl .long CSYM(sys_vhangup) .long CSYM(sys_ni_syscall) // was: idle .long CSYM(sys_ni_syscall) // i386: vm86old .long CSYM(sys_wait4) .long CSYM(sys_swapoff) // 115 .long CSYM(sys_sysinfo) .long CSYM(sys_ipc) .long CSYM(sys_fsync) .long sys_sigreturn_wrapper .long sys_clone_wrapper // 120 .long CSYM(sys_setdomainname) .long CSYM(sys_newuname) .long CSYM(sys_ni_syscall) // i386: modify_ldt, m68k: cacheflush .long CSYM(sys_adjtimex) .long CSYM(sys_ni_syscall) // 125 - sys_mprotect .long CSYM(sys_sigprocmask) .long CSYM(sys_ni_syscall) // sys_create_module .long CSYM(sys_init_module) .long CSYM(sys_delete_module) .long CSYM(sys_ni_syscall) // 130 - sys_get_kernel_syms .long CSYM(sys_quotactl) .long CSYM(sys_getpgid) .long CSYM(sys_fchdir) .long CSYM(sys_bdflush) .long CSYM(sys_sysfs) // 135 .long CSYM(sys_personality) .long CSYM(sys_ni_syscall) // for afs_syscall .long CSYM(sys_setfsuid) .long CSYM(sys_setfsgid) .long CSYM(sys_llseek) // 140 .long CSYM(sys_getdents) .long CSYM(sys_select) // for backward compat; remove someday .long CSYM(sys_flock) .long CSYM(sys_ni_syscall) // sys_msync .long CSYM(sys_readv) // 145 .long CSYM(sys_writev) .long CSYM(sys_getsid) .long CSYM(sys_fdatasync) .long CSYM(sys_sysctl) .long CSYM(sys_ni_syscall) // 150 - sys_mlock .long CSYM(sys_ni_syscall) // sys_munlock .long CSYM(sys_ni_syscall) // sys_mlockall .long CSYM(sys_ni_syscall) // sys_munlockall .long CSYM(sys_sched_setparam) .long CSYM(sys_sched_getparam) // 155 .long CSYM(sys_sched_setscheduler) .long CSYM(sys_sched_getscheduler) .long CSYM(sys_sched_yield) .long CSYM(sys_sched_get_priority_max) .long CSYM(sys_sched_get_priority_min) // 160 .long CSYM(sys_sched_rr_get_interval) .long CSYM(sys_nanosleep) .long CSYM(sys_ni_syscall) // sys_mremap .long CSYM(sys_setresuid) .long CSYM(sys_getresuid) // 165 .long CSYM(sys_ni_syscall) // for vm86 .long CSYM(sys_ni_syscall) // sys_query_module .long CSYM(sys_poll) .long CSYM(sys_nfsservctl) .long CSYM(sys_setresgid) // 170 .long CSYM(sys_getresgid) .long CSYM(sys_prctl) .long sys_rt_sigreturn_wrapper .long CSYM(sys_rt_sigaction) .long CSYM(sys_rt_sigprocmask) // 175 .long CSYM(sys_rt_sigpending) .long CSYM(sys_rt_sigtimedwait) .long CSYM(sys_rt_sigqueueinfo) .long sys_rt_sigsuspend_wrapper .long CSYM(sys_pread64) // 180 .long CSYM(sys_pwrite64) .long CSYM(sys_lchown) .long CSYM(sys_getcwd) .long CSYM(sys_capget) .long CSYM(sys_capset) // 185 .long CSYM(sys_sigaltstack) .long CSYM(sys_sendfile) .long CSYM(sys_ni_syscall) // streams1 .long CSYM(sys_ni_syscall) // streams2 .long sys_vfork_wrapper // 190 .long CSYM(sys_ni_syscall) .long CSYM(sys_mmap2) .long CSYM(sys_truncate64) .long CSYM(sys_ftruncate64) .long CSYM(sys_stat64) // 195 .long CSYM(sys_lstat64) .long CSYM(sys_fstat64) .long CSYM(sys_fcntl64) .long CSYM(sys_getdents64) .long CSYM(sys_pivot_root) // 200 .long CSYM(sys_gettid) .long CSYM(sys_tkill)sys_call_table_end:C_END(sys_call_table)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -