0

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

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

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

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

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

4

2 回答 2

6

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

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

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

有关详细信息,您可以查看这些手册中的第 2 章第 4 章:分页

于 2015-06-05T18:45:40.163 回答
3
  1. 由于非法内存访问而发生分段错误。内核跟踪已分配的内存,如果您尝试在该分配之外进行访问,它会像用户空间进程一样出现段错误。

  2. Linux 内核中没有与用户空间中相同的“进程”概念(有关此问题的详细讨论,请参见此答案)。内核可以产生线程来处理某些任务,但这不是一回事。实际上,您可以将内核视为一个站立或倒下的大型“进程”。

于 2013-10-22T20:50:50.063 回答