内核模块的加载如何在 linux 中工作?

Posted

技术标签:

【中文标题】内核模块的加载如何在 linux 中工作?【英文标题】:How does loading of kernel module work in linux? 【发布时间】:2021-10-31 11:57:02 【问题描述】:

试图了解内核模块的内部结构。

加载内核模块时会发生什么?模块是作为不同的进程运行还是作为内核代码的一部分运行? IE。为加载的模块分配的文本段和数据段在哪里?

【问题讨论】:

【参考方案1】:

模块本身不会运行,它会被加载,当您调用模块的打开/读/写函数时代码将运行,这些函数将作为文件呈现给用户模式。

对于 x86-64,内核加载在 0xffff_ffff_8000_0000 以上。因此,内核模块将在附近的某个地方分配内存。

您可以查看 /boot 目录下引导分区上的 System.map 文件,以了解不同的内核功能在哪里。

当您从 C++ 对内核模块的文件调用 open 时,您会调用 libstdc++ 中的一个瘦包装器,该包装器会在内核中进行系统调用。系统调用将调用模块的 open 函数,然后返回给调用者。因此它将在内核中进行一个小的上下文切换。代码位于规范虚拟地址空间的最后 2GB。

内核模块是可重定位的可执行文件。它们将被重新定位在内核区域(上 2GB)的虚拟地址空间中的某个位置。它们可以降落在物理地址空间的任何位置。

内核模块由 insmod 程序使用 System.map 文件重新定位。 insmod 程序将调用模块的 init 函数作为 sudo。加载模块后,除非您从涉及系统调用的用户模式进程调用模块文件的 open 函数,否则不会运行任何内容。该模块只是存在于内存中的某个地方并准备好被调用。您从模块调用的所有函数都使用 System.map 文件与内核动态链接。

【讨论】:

1/ 第一段描述的现有模块可能不到一半。 2/ 内核模块不是可执行文件,而是动态链接对象。

以上是关于内核模块的加载如何在 linux 中工作?的主要内容,如果未能解决你的问题,请参考以下文章

Linux入门之CentOS7内核编译三部曲

OpenWrt教程-如何在OpenWrt系统中添加一个Linux内核模块

内核模块编译

内核模块编译实验

linux内核模块中调用shell脚本

linux安装内核模块问题