下面是arm 64位的中断向量表。
BEGIN_FUNC(arm_vector_table)
...
ventry lower_el_sync // Synchronous 64-bit EL0/EL1
...
END_FUNC(arm_vector_table)
下面是系统调用程序的入口c_handle_syscall
BEGIN_FUNC(lower_el_sync)
kernel_enter
...
lel_syscall:
mrs x20, ELR
sub x20, x20, #4
str x20, [sp, #PT_FaultInstruction]
lsp_i x19
mov x2, x7
b c_handle_syscall
...
END_FUNC(lower_el_sync)
下面是系统调用程序入口,然后调用slowpath,然后slowpath调用handleSyscall。handleSyscall根据不同的中断号来执行不同的函数。
void VISIBLE
c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall)
{
NODE_LOCK_SYS;
...
if (unlikely(syscall < SYSCALL_MIN || syscall > SYSCALL_MAX)) {
#ifdef TRACK_KERNEL_ENTRIES
ksKernelEntry.path = Entry_UnknownSyscall;
/* ksKernelEntry.word word is already set to syscall */
#endif /* TRACK_KERNEL_ENTRIES */
handleUnknownSyscall(syscall);
restore_user_context();
UNREACHABLE();
} else {
slowpath(syscall);
UNREACHABLE();
}
}
void NORETURN
slowpath(syscall_t syscall)
{
#ifdef TRACK_KERNEL_ENTRIES
ksKernelEntry.is_fastpath = 0;
#endif /* TRACK KERNEL ENTRIES */
handleSyscall(syscall);
restore_user_context();
UNREACHABLE();
}
exception_t
handleSyscall(syscall_t syscall)
{
...
switch (syscall) {
case SysSend:
ret = handleInvocation(false, true);
if (unlikely(ret != EXCEPTION_NONE)) {
irq = getActiveIRQ();
if (irq != irqInvalid) {
handleInterrupt(irq);
Arch_finaliseInterrupt();
}
}
break;
...
return EXCEPTION_NONE;
}