我应该什么时候写一个Linux内核模块?

有些人因为某种原因想要将代码从用户空间移到Linux的内核空间。 很多时候,原因似乎是代码应该具有特别高的优先级,或者只是“内核空间更快”。

这对我来说似乎很陌生。 我应该什么时候考虑编写一个内核模块? 有一套标准吗?

我怎么能激励保持代码(我相信)属于那里的用户空间?

经验法则: 所能将代码保留在用户空间中。 如果你不这么认为,那么花时间研究内核代码的替代品,就像编写代码一样(比如:很长一段时间),然后再次尝试在用户空间中实现它。 如果你仍然不能,研究更多,以确保你做出正确的选择,然后非常谨慎地进入内核。 正如其他人所说,写内核模块和调试内核代码的情况非常少 ,所以不惜一切代价避免。

就具体条件而言,在考虑编写内核模式代码时应该检查一下,这里有几个:是否需要访问极低级别的资源,如中断? 您的代码是否定义了一个新的无法在当前导出的功能之上构建的硬件接口/驱动程序? 你的代码是否需要访问不能从内核空间导出的数据结构或原语? 你是否正在编写其他内核子系统(例如调度程序或虚拟机系统)主要使用的东西(甚至在这里子系统并不是完全必须是内核模式:Mach对用户模式虚拟内存寻呼机有很强的支持,所以一定可以做到)?

将东西放入内核的原因非常有限。 如果你正在写设备驱动程序,那就没关系。 任何标准应用程序:从不。

缺点是巨大的。 调试越来越困难,错误变得越来越频繁和难以找到。 您可能会危及安全性和稳定性。 您可能需要更频繁地适应内核更改。 无法移植到其他UNIX操作系统。

最接近内核的是自定义文件系统(在后台使用mysql),甚至我们使用了FUSE(其中U代表用户空间)。

我不确定这个问题是否正确。 应该有一个很好的理由把东西移到内核空间。 如果没有任何理由,不要这样做。

首先,调试变得更加困难,并且bug的效果更差(崩溃/恐慌,而不是简单的coredump)。

在内核中运行的代码以不同于用户空间代码的方式访问存储器,外围设备,系统功能,从而具有更高效的能力。 更不用说降低内核代码的安全限制了。 然而,所有这些通常都是以牺牲成本为代价的,比如增加了内核开启安全威胁的可能性,锁定操作系统,调试复杂等等。

基本上我同意rpj。 代码必须在用户空间中,除非它是非常必要的。

但是,要强调你的问题,哪个条件?

有些人声称,驱动程序必须在内核,这是不正确的。 有些车手对时间不敏感,事实上很多车手都是这样的。

例如,成帧器,RTC定时器,i2c设备等。这些驱动器可以很容易地移动到用户空间。 甚至有一些用户空间的文件系统。

你应该转移到内核空间的开销,例如。 用户内核交换,变得不可接受您的代码正常工作。

但是有很多方法可以解决这个问题。 例如,/ dev / mem提供了一种访问物理内存的好方法,就像从内核空间执行一样。

当人们谈论去实时操作系统时,我通常会持怀疑态度。 这些日子,处理器是如此强大,大多数时候,实时的方面变得可以忽略不计。

但即使如此,假设您正在处理SONET,并且您需要在50ms内进行保护切换(实际上甚至更少,因为50ms限制适用于整个环路),您仍然可以非常快速地进行切换,如果您的硬件支持它。

现在许多成帧器都可以为您提供硬件支持,从而减少您需要执行的写入操作。 你的工作基本上是尽可能快地响应中断。 而Linux并不糟糕。 我得到的中断延迟小于1ms,即使我有大量的其他中断正在运行(例如,IDE,以太网等)。

如果这还不够,那么也许你的硬件设计是错误的。 有些东西最好留在硬件上。 而当我说硬件时,我的意思是ASIC,FPGA,网络处理器或其他先进的逻辑。

如果您的员工需要真正的高优先级,确定性,低延迟等,正确的方法是使用一些实时版本的Linux(或其他操作系统)。

也可以看看可抢占的内核选项等。究竟你应该做什么取决于需求,但是把代码放在内核模块中可能不是正确的解决方案,除非你直接连接一些硬件。

作为一般规则。 想想你想知道什么,如果这是你在操作系统开发书或类中看到的东西,那么它有一个很好的机会属于内核。 如果没有,请将其保留在内核之外。 如果你有一个很好的理由来打破这个规则,那么一定要有足够的知识来自己去认识它,否则你将会和有知识的人一起工作。

是的,可能听起来很刺耳,但这正是我的意思,如果你不知道,那么几乎可以肯定答案是否定的,不要在内核中这样做。 将你的开发转移到内核空间将会打开一大堆你必须确定能够处理的蠕虫。

不把代码移入内核空间的另一个原因是,当你在生产或商业环境中使用代码时,你必须根据GPL协议发布代码。 许多软件公司不想进入的情况。 🙂

如果您只需要更低的延迟,更高的吞吐量等,购买速度更快的计算机可能比开发内核代码便宜

内核模块可能会更快(由于更少的上下文切换,更少的系统调用开销和更少的中断),并且确实以非常高的优先级运行。 如果你想将少量相当简单的代码导出到内核空间,这可能是好的。 也就是说,如果发现一小段代码对于性能至关重要, 而且是能够从内核模式中获益的那种代码,那么将其放置在那里可能是合理的。

但是,除非所有其他选项完全耗尽,否则应该避免将大部分程序移入内核空间。 除了这样做的困难之外,性能优势不可能是非常大的。

如果你问这样的问题,那么你不应该去内核层。 基本上只是想知道意味着你不需要。 上下文切换的时间是微不足道的,无论如何这些天无关紧要。