美文网首页
Linux内核——用户堆栈和内核堆栈

Linux内核——用户堆栈和内核堆栈

作者: 懒无趣 | 来源:发表于2020-12-24 23:01 被阅读0次

    定义

    每个进程都有用户堆栈和内核堆栈两个堆栈。进程在用户态时使用用户堆栈,陷入到内核态时便使用内核堆栈。

    切换过程

    1. 用户进程X正常运行时,堆栈寄存器ESP指向的的用户堆栈地址。
    2. 当进程X调用某系统调用时(int 0x80),CPU会首先将用户堆栈地址保存到内核堆栈内(还有EIP,FLAG等寄存器),然后将ESP指针指向内核堆栈地址(还有将内态的EIP,FLAG等也一并存入相应的寄存器中,切换到用户态进程),这时便切换到来内核堆栈中。
    3. 当系统调用完成后,再将用户堆栈地址从内核堆栈中出栈存储ESP寄存器中,此时便切换到了用户堆栈。

    中断过程

    1. X函数调用syscall_x (用户态)
    2. int 0x80 (保存部分寄存器,内核态)
    3. syscall_call (SAVE_ALL保存全部现场,内核态)
    4. iret后(用户态)

    中断代码(简易)

    ENTRY(system_call)
        RING0_INT_FRAME
        ASM_CLAC
        push_cfi %eax #保存系统调用号
        SAVE_ALL #保存现场⚠️
        GET_THREAD_INFO(%ebp)
        testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%epb) 
        jnz syscall_trace_entry
      cmpl $(nr_syscalls), %eax #检查传入到系统调用号是否合法
        jae syscall_badsys
      syscall_call:
        call *sys_call_table(,%eas,4) #执行相应的系统调用函数
        movl %eax,PT_EAX(%ebp) #保存结果到eax寄存器
      syscall_exit:
        testl $_TIF_ALLWORK_MASK,%ecx #检查是否有其他任务处理
        jne syscall_exit_work #进行进程调度
      restore_all
        TRACE_IRQS_IRET #恢复现场
      irq_return:
        INTERRUPT_RETURN #iret 将ESP,EIP,FLAG等寄存器恢复为用户态
    

    相关文章

      网友评论

          本文标题:Linux内核——用户堆栈和内核堆栈

          本文链接:https://www.haomeiwen.com/subject/uwgunktx.html