更多概述问题比技术。我可以看到Linux内核开发人员的位置,我不知道你想成为一个内核模块?与使用系统调用和执行相比,哪种类型的任务最适合作为内核模块完成?你会为内核模块写什么?
less /proc/modules
在我的系统上显示dm_log,device-mapper的记录器。为什么要从内核完成日志记录,而不是用户空间呢?
更多概述问题比技术。我可以看到Linux内核开发人员的位置,我不知道你想成为一个内核模块?与使用系统调用和执行相比,哪种类型的任务最适合作为内核模块完成?你会为内核模块写什么?
less /proc/modules
在我的系统上显示dm_log,device-mapper的记录器。为什么要从内核完成日志记录,而不是用户空间呢?
你想成为一个内核模块?
尽管大多数人将内核模块(仅)与设备驱动程序关联,但是其他内核服务(如文件系统和网络协议处理程序)也可以构建为模块。
内核模块与静态链接(即构建在内核中)的主要基本原理是运行时可配置性(这反过来提高了内存效率)。可选特性,服务和驱动程序可以不在启动的内核之外,但仍可以在需要时加载。
加载模块的开销,模块所需的存储空间(内核通常以压缩形式存储,而模块未压缩)以及每个模块浪费的内存页的片段通常被认为是可接受的折衷。
与使用系统调用和做某些事情相比,哪种类型的任务最适合作为内核模块完成?
这是一个单独的问题,没有真正涉及到以前。实际上你应该比较用户模式和内核模式。内核模式是使用一个模块(它必须被加载)还是静态链接的代码(它总是可用的)并不是实际问题的重要方面。 (其他回答说:“运行模块代码当一个小的性能损失是由于虚拟内存开销”提到了是不正确。)
用户模式服务或驱动器具有的优点是:
通常更容易和更快实现(不需要构建和安装内核)。大多数C程序员只能学习C运行时库,所以内核环境而不是用户模式可能是一种学习体验。
更容易控制专有的源代码。可免除GNU GPL。
受限制的权限不太可能会无意中取消系统或创建安全漏洞。
内核模式服务或驱动程序具有以下优点:
状况多于一个程序系统中的不杂乱的排斥锁。
设备可访问性可以通过文件权限进行控制。
只要系统正在运行,设备或服务的状态就是连续且可用的。每次程序启动时,用户模式驱动程序都必须将设备重置为已知的静态状态。
更一致/准确的定时器和减少的事件延迟。
的用户模式与内核模式的一个例子是加入到Linux内核中2.6.30版Reliable Datagram Sockets。之前的RDS是一种基于UDP的用户模式协议,但通过“acking/windowing/fragmenting/re-ordering等”进行了增强。在重负载下,用户模式协议的定时器不准确,因此额外的重传和丢弃的消息导致稳定性和性能问题。切换到内核模式网络协议旨在改进/解决这些问题。
但是内核模式存在缺陷(或责任)。内核代码负责确保系统的完整性和安全性。 RDS被发现在内核中引入了一个security hole。
为什么要从内核进行日志记录,而不是做用户空间?
可能有几个原因,但是对于这个例子,日志请求者可能会处于内核模式而不是用户模式,所以这样可以避免模式切换的尴尬。
内核模块通常用于您平台上可能没有的外设驱动程序。这样,如果外设在平台上不可用,则不会消耗内存和CPU时间来添加未使用的代码。
这个问题不涉及内置驱动程序与模块,它关注内核模块与用户空间。 – 2014-10-09 16:49:00
系统调用设备驱动程序/sys
和/proc
和mmap
用户API允许用户空间程序只对内核中的符号和数据提供有限的高度受控的接口。这些接口不允许访问您想要使用驱动程序(如dm_log
)登录的大部分数据和事件。要将这些数据导出到用户空间,您需要一个内核模式驱动程序,可以是编译的或者是可加载的内核模块。
对于中断处理,系统调用,设备文件,/proc
和/sys
文件系统,即用户空间API,内核代码和模块代码没有区别。
这里有一些理由使用Linux内核模块技术:
vmalloc
加载到内核空间虚拟存储器,并因此更有效地利用内核空间内存在的是,如果所分配的内存被释放模块被卸载,而内存为编译进内核的未使用的驱动程序不能被释放缺点使用模块是:
关于用户空间的驱动程序运行模块的代码时,如果是这样的OP的真正意图是一个小的性能损失 - 用户空间的驱动程序是正义的,在用户空间运行的程序只要。因此,他们没有比任何其他用户空间应用程序更多的内核符号或内存访问权限,也就是说没有太多。
这解决了使用模块vs静态链接到内核的原因,但我认为最初的问题是要求使用模块vs用户空间设备驱动程序的原因(“系统调用和执行的东西”) – 2014-10-08 13:32:07
@AdrianCox:原始的措辞的OP没有向我表明对用户空间驱动程序概念的认识。无论如何,我添加了关于'dm_log'的OP问题的最后部分的具体参考。 – 2014-10-08 13:39:10
*“3.模块代码加载到虚拟内存中”* - 整个内核位于虚拟内存中。你在写什么? – sawdust 2014-10-08 19:00:20
只是你知道,device-mapper是一个内核组件。所以如果我们要从中导出日志消息,我们必须在内核中执行它(因为内核是产生日志消息的东西) – 2014-10-08 13:58:41