内核模块的加载如何在 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 中工作?的主要内容,如果未能解决你的问题,请参考以下文章