gpt4 book ai didi

linux - 我在哪里可以找到 linux 内核中的指令地址(PC 值)?

转载 作者:太空宇宙 更新时间:2023-11-04 09:45:39 26 4
gpt4 key购买 nike

全部。

当我分配一个新的物理页面时,我试图打印当前的 PC 值。在linux内核源码中,mm/memory.c负责分配页,但它没有关于 PC 值的信息......有谁知道我在哪里可以找到这个 PC 值并在 memory.c 文件中使用它?

最佳答案

将我的评论变成答案。

您要查找的不是当前 PC(一直在变化),而是触发页面错误的指令的 PC。要了解它的存储位置以及如何检索它,让我们深入挖掘一下。

当 x86 中发生异常(陷阱或中断)时,CPU 将执行以下操作:

  • 使用向量(陷阱编号/中断编号 - 这是硬件隐含的和/或可通过编程中断 Controller 进行配置 - 是的,您可以进行网络中断触发页面错误,技术上...)作为中断描述符表(IDT)的索引
  • 它验证存储在那里的数据结构(所谓的门描述符)
  • 如果无效...引发#GP错误(一般保护[错误]);因为这本身就是一个异常(exception)......如果那个门也是无效的......#DF(双重故障)......冲洗重复......如果无效 - 三重故障(哪个硬重置 CPU)。
  • 如果有效,门将指定目标上下文(通过代码段)和其中的处理程序地址。用外行的话来说,这表示“进入以下特权级别并调用此处理程序”(通过使目标 %cs 成为内核,并使处理程序成为一些低级中断入口函数)。<
  • 如果此操作涉及特权切换,则 CPU 更改为目标特权级别,并且堆栈指针被切换。
  • CPU 将中断返回信息写入该堆栈(请注意此处的下一个#DF机会...如果由于内核堆栈指针损坏而失败,则会发生这种情况,或堆栈溢出到未映射的内存中)。写入的信息包含:
    1. 故障发生时的代码段(源自“上下文”)
    2. 堆栈指针在故障发生时处于事件状态(即用户堆栈),堆栈已切换
    3. flags 注册
    4. 错误地址/PC(不是所有类型的陷阱,但肯定是页面错误)
  • 只有所有这些都发生之后,才会调用实际的中断向量处理函数。从这里开始,软件 - 内核代码接管:
    1. 在汇编代码中,通用寄存器的其余部分和其他必要的“上下文”信息被保存到异常帧中,然后构造一个适合调用 C 代码的堆栈。
    2. C 函数以 struct ptregs* 作为参数调用 - 这是异常帧,由陷阱条目保存的寄存器状态(部分由 HW/CPU 本身,部分由入口 stub 代码)。这是实际用于处理陷阱/异常/中断的内容。

当从陷阱/中断返回时,x86 iret 指令用于展开由 CPU 压入内核堆栈的四/五个字以恢复/返回。

这样,内核中的每个异常入口都被赋予了相同的数据结构,struct ptregs * - 如前所述,对于大多数陷阱/中断,除其他信息外,它包含程序计数器/说明故障发生位置的指令指针。 struct pt_regs.ip 是您需要查看的字段。

特别是页面错误,参见do_page_fault()并检查在哪里/如何使用它。

关于linux - 我在哪里可以找到 linux 内核中的指令地址(PC 值)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16617624/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com