更多概述问题而不是技术问题。我可以看到Linux内核开发人员的位置,我想知道你想成为一个内核模块是什么?与使用系统调用和执行操作相比,作为内核模块最好完成哪些任务?
我的系统上的 less /proc/modules
显示了dm_log,它是device-mapper的记录器。为什么要从内核完成日志记录,而不是用户空间呢?
答案 0 :(得分:3)
你想成为一个内核模块?
虽然大多数人将内核模块(仅)与设备驱动程序相关联,但其他内核服务(如文件系统和网络协议处理程序)也可以构建为模块。 内核模块与静态链接(即内置在内核中)的主要原理是用于运行时可配置性(这反过来提高了内存效率)。可选功能,服务和驱动程序可以从引导的内核中删除,但仍可在以后需要时加载 加载模块的开销,模块所需的存储空间(内核通常以压缩形式存储而模块未被压缩)和每个模块浪费的存储页面片段通常被认为是可接受的权衡。
与使用系统调用和执行操作相比,作为内核模块最好完成哪些任务?
这个单独的问题与之前的问题并不完全相关。您应该实际比较用户模式与内核模式。内核模式是使用模块(必须加载)还是静态链接代码(始终可用)不是实际问题的重要方面。 (另一个答案提到"由于虚拟内存开销而导致模块代码的性能损失很小" 不正确。)
用户模式服务或驱动程序具有以下优点:
通常更容易和更快地实现(无需构建和安装内核)。大多数C程序员(只)学习C运行时库,因此内核环境而不是用户模式可能是一种学习体验。
更容易控制专有源代码。可以免除GNU GPL。
受限制的权限不太可能无意中删除系统或创建安全漏洞。
内核模式服务或驱动程序具有以下优点:
系统中多个程序的可用性,没有凌乱的排除锁。
可以通过文件权限控制设备可访问性。
只要系统正在运行,设备或服务的状态就是连续可用的。每次程序启动时,用户模式驱动程序都必须将设备重置为已知的静止状态。
更一致/准确的计时器和减少的事件延迟。
用户模式与内核模式的一个示例是在版本2.6.30中添加到Linux内核的Reliable Datagram Sockets。以前,RDS是一种基于UDP的用户模式协议,但通过" acking / windowing / fragmenting / re-ordering等进行了增强" 。在重负载下,用户模式协议的定时器不准确,因此额外的重传和丢弃的消息导致稳定性和性能问题。切换到内核模式网络协议旨在改善/解决此类问题。
然而,内核模式存在缺陷(或责任)。内核代码负责确保系统的完整性和安全性。发现RDS在内核中引入了security hole。
为什么要从内核完成日志记录,而不是用户空间呢?
可能有几个原因,但对于此示例,日志请求者可能处于内核模式而不是用户模式,因此这将避免笨拙的模式切换。
答案 1 :(得分:1)
系统调用,设备驱动程序,/sys
以及/proc
和mmap
用户API只允许用户空间程序对符号和数据进行有限的,高度可控的界面。核心。这些接口不允许访问您希望使用dm_log
等驱动程序记录的大部分数据和事件。要将此数据导出到用户空间,您需要一个内核模式驱动程序,无论是已编译的还是可加载的内核模块。
在中断处理,系统调用,设备文件,/proc
和/sys
文件系统,即用户空间API方面,内核代码和模块代码之间没有区别。
以下是使用Linux内核模块技术的一些原因:
vmalloc
将模块代码加载到内核空间虚拟内存中,因此可以更有效地使用内核空间内存,因为如果卸载模块则释放已分配的内存,而未使用的驱动程序的内存则编译为内核无法释放使用模块的缺点是:
vmalloc
内存中执行,其基址在当时是不可知的。 OTOH您可以编写FIQ模式代码并在常规内核构建期间将其编译到内核中,并且该代码可以在FIQ模式下运行时访问内核符号,因为基本内核中的虚拟和实际地址是相同的。关于用户空间驱动程序,如果这确实是OP的意图 - 用户空间驱动程序就是这样,那些仅在用户空间中运行的程序。因此,他们没有比任何其他用户空间应用程序更多的内核符号或内存访问权限,也就是说,并不多。
答案 2 :(得分:0)
内核模块通常用于您平台上可能没有的外围设备驱动程序。这样,如果平台上没有外围设备,则不会消耗内存和CPU时间来添加未使用的代码。