Linux内核模块-剖析内核模块(六)

本文介绍了Linux内核模块(LKM)的基本概念,包括其作为一种特殊ELF对象的特点,以及在用户空间通过insmod命令加载和rmmod命令卸载的生命周期管理过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 1.内核模块对象
  LKM 只不过是一个特殊的可执行可链接格式(Executable and Linkable Format,ELF)对象文件。通常,必须链接对象文件才能在可执行文件中解析它们的符号和结果。由于必须将 LKM 加载到内核后 LKM 才能解析符号,所以 LKM 仍然是一个 ELF 对象。您可以在 LKM 上使用标准对象工具(在 2.6 版本中,内核对象带有后缀  .ko, )。例如,如果在 LKM 上使用  objdump  实用工具,您将发现一些熟悉的区段(section),比如 .text (说明)、 .data (已初始化数据)和  .bss (块开始符号或未初始化数据)。
图 2. 具有各种 ELF 区段的 LKM 的示例
2.LKM的生命周期
  1. 在用户空间中,insmod(插入模块)启动模块加载过程。
  2. insmod 命令定义需要加载的模块,并调用 init_module 用户空间系统调用,开始加载过程。2.6 版本内核的 insmod 命令经过修改后变得非常简单(70 行代码),可以在内核中执行更多工作。insmod 并不进行所有必要的符号解析(处理 kerneld),它只是通过 init_module 函数将模块二进制文件复制到内核,然后由内核完成剩余的任务。
  3. init_module 函数通过系统调用层,进入内核到达内核函数 sys_init_module(参见图 3)。这是加载模块的主要函数,它利用许多其他函数完成困难的工作。
图 3. 加载和卸载模块时用到的主要命令和函数

类似地,rmmod 命令会使 delete_module 执行 system call 调用,而 delete_module 最终会进入内核,并调用sys_delete_module 将模块从内核删除。
  • 模块加载细节:
现在,我们看看加载模块时的内部函数(参见图 4)。
  1. 当调用内核函数 sys_init_module 时,会开始一个许可检查,查明调用者是否有权执行这个操作(通过 capable 函数完成)。
  2. 然后,调用 load_module 函数,这个函数负责将模块加载到内核并执行必要的调试(后面还会讨论这点)。load_module 函数返回一个指向最新加载模块的模块引用。这个模块加载到系统内具有双重链接的所有模块的列表上,并且通过 notifier 列表通知正在等待模块状态改变的线程。
  3. 最后,调用模块的 init() 函数,更新模块状态,表明模块已经加载并且可用。
图 4. 内部(简化的)模块加载过程

卸载模块细节省略,详情可查看以下链接:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值