X86_64处理器系统调用机制在linux上的实现

本文详细介绍了X86_64处理器在Linux上的系统调用机制,包括硬件层面的syscall和sysret指令,以及Linux内核如何处理系统调用,如初始化、入口函数和系统调用栈帧结构。重点关注了MSR寄存器的作用和系统调用状态的切换过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

X86_64处理器系统调用机制在linux上的实现

硬件机制

X86 64位flat模式提供了快速系统调用硬件机制。使用syscall指令触发系统调用,CPU从用户态(Ring3)切换到特权态(Ring0),使用sysret指令,CPU从内核态切换到用户态。

注意:sysret指令和iret指令是CPU从内核态切换到用户态的两种方式

  • syscall 指令

执行syscall指令,发生系统调用时,CPU硬件执行以下动作:

  1. 把MSR_LSTAR寄存器中的值加载到RIP寄存器,并把当前程序运行的下一条指令(即syscall指令的下一条指令)保存在RCX寄存器中
  2. 把当前的RFLAGS寄存器的值保存在R11寄存器,并使用MSR_FMASK寄存器的值mask当前RFLAGS的值。一般通过这种方式关闭中断,保证进入系统调用后,CPU的中断时关闭的
  3. 把MSR_STAR寄存器的SYSCALL CS and SS分别加载到CPU的CS和SS段寄存器,同时更新CS和SS的不可见部分。

注意:syscall指令不会更新RSP寄存器的值,由OS去负责切换程序栈。

  • sysret 指令

执行sysret指令,CPU从内核特权态(Ring0)返回到用户态(Ring3),从syscall的指令的下一条指令处继续执行。CPU硬件执行以下动作:

  1. 把RCX寄存器中的值加载到RIP寄存器
  2. 把R11寄存器中的值加载到rflags寄存器
  3. 把MSR_STAR寄存器中的SYSRET CS and SS分别加载到CS和SS段寄存器。

注意:sysret指令不修改RSP寄存器的值,OS负责切换程序栈。

  • MSR 寄存器
    在这里插入图片描述

linux kernel中syscall的处理

linux kernel里面系统调用的入口函数是entry_SYSCALL_64,在arch/x86/entry/entry_64.S中实现。该函数被保存在MSR_LSTAR寄存器中。

系统调用初始化

在系统调用初始化函数里面:

  • 将系统调用入口函数entry_SYSCALL_64写入MSR_LSTAR寄存器中
  • 初始化MSR_STAR寄存器中的SYSCALL CS and SS
  • 初始化MSR_SFMASK中的SYSCALL Flag Mask,系统调用发生时,RFLAGS中的这些位将被清零
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值