【问题标题】:How are kernel space segfaults detected by the kernel?内核如何检测内核空间段错误?
【发布时间】:2013-10-31 22:04:25
【问题描述】:

在 C 语言中,如果您尝试写入不属于您的内存,则可能发生的一件事是段错误。 (从技术上讲,当您尝试写入不属于您的内存时,行为是未定义的,但操作系统可以处理这种情况的一种方式是抛出段错误)。对于尝试非法内存访问的用户空间代码,内核是检测非法内存访问并抛出段错误的代码。

现在,我正在编写一个 Linux 内核模块。我的代码在内核空间中运行。我有两个相关的问题:

  1. 如果我超出数组范围,我的代码会出现段错误。我想知道是什么检测到这个段错误?对于用户空间应用程序,内核会检测段错误。那么内核代码本身呢?什么负责检测内核代码中的越界内存访问?

  2. 我编写的内核模块和 insmod 是否作为单独的进程运行?如果是,为什么当我的模块出现段错误时整个内核段错误?为什么不只是我的模块段错误,而内核的其余部分继续运行?

我正在阅读本教程的第 3.1.5 节:http://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html

【问题讨论】:

    标签: c linux linux-kernel segmentation-fault


    【解决方案1】:

    与高级语言不同,内存访问直接与 C 中的硬件对话。加载变成了这条指令:mov %reg, [address]。一家商店变成了这样:mov [addr], value。由于操作系统不直接参与该指令的执行,因此处理器会捕获非法访问。以下是 x86 如何响应对只读映射的写入(来自Intel software developer manual):

    MOV—Move
    ...
    Protected Mode Exceptions
    ...
    #GP(0) If the destination operand is in a non-writable segment.
    ...
    

    对于检测非法访问的硬件,操作系统维护页表。与用户空间相同,内核模式也有其内存映射。任何不在映射范围内的访问都会产生异常,该异常会调用操作系统内的处理程序。

    有关详细信息,您可以查看这些手册中的Vol.2 Chapter 4: Paging

    【讨论】:

      【解决方案2】:
      1. 由于非法内存访问而发生分段错误。内核会跟踪已分配的内存,如果您尝试在该分配之外进行访问,它会像用户空间进程一样出现段错误。

      2. Linux 内核中没有“进程”的概念,就像在用户空间中一样(请参阅this answer 以获得很好的讨论)。内核可以产生线程来处理某些任务,但这不是一回事。实际上,您可以将内核视为一个大的“进程”,可以一起站立或倒下。

      【讨论】:

      • 谢谢!跟进您的第 1 部分答案 - 您说,“内核会跟踪已分配的内存......”。内核是否跟踪内核其他部分分配的内存?如果是,我很想知道内核的哪一部分是这样做的?
      • 您要查找的组件是page allocatorHere's 内核内存管理的另一个很好的讨论。
      猜你喜欢
      • 2012-05-12
      • 2012-02-12
      • 1970-01-01
      • 2013-01-21
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      相关资源
      最近更新 更多