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

定义

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

切换过程

  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等寄存器恢复为用户态
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 内核在创建进程时,会同时创建task_struct和进程相应堆栈。每个进程都会有两个堆栈,一个用户栈,存在于用户空...
    saviochen阅读 11,864评论 2 11
  • 为了区分程序的运行级别,有用户态和核心态之分,也叫目态和管态。硬件驱动、CPU和内存管理等底层操作和进程管理、诊断...
    小码弟阅读 6,671评论 0 0
  • intel的cpu分为四个运行级别ring0~ring3,内核创建进程,创建进程的同时创建进程控制块,创建进程自己...
    vbuer阅读 3,604评论 0 0
  • 在Linux系统中,每一个用户进程都有两个栈,一个用户栈,存在于用户空间,一个内核栈,存在于内核空间。当进程在用户...
    西元前__YP阅读 4,590评论 0 0
  • 1.1. 进程的堆栈 内核在创建进程的时候,在创建task_struct的同时,会为进程创建相应的堆栈。每个进程会...
    Hope_加贝阅读 1,342评论 0 0

友情链接更多精彩内容