seL4 源码分析之系统调用函数seL4_Send

1. 中断向量表

下面是arm 64位的中断向量表。

BEGIN_FUNC(arm_vector_table)
	...
    ventry  lower_el_sync                  // Synchronous 64-bit EL0/EL1
	...
END_FUNC(arm_vector_table)

2. 中断服务程序的实现

下面是系统调用程序的入口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)

3. 系统调用中断服务程序的实现

下面是系统调用程序入口,然后调用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;
}

你可能感兴趣的:(sel4)