如何从Linux内核模块代码(内核模式)中获取有关正在运行哪个内核版本的运行时信息?
按惯例,Linux内核模块加载机制不允许加载未针对正在运行的内核编译的模块,因此你所提到的"正在运行的内核"很可能在内核模块编译时已经被知晓了。
要检索版本字符串常量,旧版本需要包括 <linux/version.h>
,其他版本需要包括<linux/utsrelease.h>
,而较新的版本需要包括<generated/utsrelease.h>
。如果你真的想在运行时获得更多信息,那么来自linux/utsname.h
的utsname()
函数是最标准的运行时接口。
虚拟/proc/version
procfs节点的实现使用utsname()->release
。
如果你想根据内核版本在编译时条件化代码,可以使用预处理器块,例如:
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)
...
#else
...
#endif
它允许您与主/次要版本进行比较。
您只能一次安全地为任何一个内核版本构建模块。这意味着在运行时请求模块是冗余的。
您可以在构建时找到此信息,通过查看UTS_RELEASE
的值。在最近的内核中,这个值在<generated/utsrelease.h>
中,还有其他方法可以实现。
为什么我无法为任何版本构建内核模块?
因为内核模块 API 是故意不稳定的,如内核树中所解释的那样:Documentation/stable_api_nonsense.txt
。摘要如下:
Executive Summary
-----------------
You think you want a stable kernel interface, but you really do not, and
you don't even know it. What you want is a stable running driver, and
you get that only if your driver is in the main kernel tree. You also
get lots of other good benefits if your driver is in the main kernel
tree, all of which has made Linux into such a strong, stable, and mature
operating system which is the reason you are using it in the first
place.