模块加载与生命周期
这页讲的是:一个模块不是“编出来就算存在”,它还要被装入、初始化、参与系统运行,并在合适时机被卸载或保持常驻。学这页的重点,是理解模块是系统装配方式的一部分,也有自己的进入、存在和退出过程。
这块是什么
模块加载与生命周期,讲的是内核某些能力怎样以模块形式被带进系统、怎样完成初始化接管、怎样与别的模块或核心能力建立依赖关系,以及为什么有些模块能卸载、有些几乎会一直留在系统里。它比“构建系统与模块加载”那页更强调模块进入运行期之后的生命过程。
可以把模块理解成“可插拔部件”,但它不是随便插上就能用、拔掉就没事的 USB 小配件,而是会进入系统核心运行秩序的一类部件。
它负责什么
让能力在运行期接入
- 把某些功能按需装入系统
- 避免所有能力都必须在开机前内建
- 支持更灵活的硬件与功能组合
- 让系统装配更贴近实际场景
组织初始化与退出
- 模块装入后要完成自我登记和准备
- 退出前要清理自己建立的痕迹
- 让系统知道它何时真正可用
- 降低“进来容易出去乱”的风险
处理依赖与存在关系
- 模块不是孤立能力,常与别的接口和对象相连
- 加载顺序和依赖关系会影响能否正常工作
- 卸载时还要考虑是否仍被引用
- 让“可插拔”不会演变成系统失序
模块的生命过程大致怎么看
| 阶段 | 你现在怎么理解 | 为什么关键 |
|---|
| 被选择和装入 | 某个能力作为模块被放进当前运行系统。 | 这决定它不是一开始就常驻,而是按需接入。 |
| 初始化与登记 | 模块要把自己挂进驱动框架、文件系统、网络栈等对应世界里。 | 不登记就只是代码存在,不算系统能力真正生效。 |
| 运行期存在 | 模块会持有对象、资源和回调关系,持续参与系统工作。 | 这说明它进入的是一个长期关系,不是一次函数调用。 |
| 退出与卸载 | 如果允许退出,就要先确保资源、引用和依赖都处理干净。 | 退出比进入更容易出问题,因为系统里已经留下很多关联。 |
关键概念
| 概念 | 现在怎么理解 |
|---|
| 模块 | 可在运行期接入内核的一类功能部件。 |
| 加载 | 把模块带进当前系统,使它开始参与运行。 |
| 初始化 | 模块把自己登记为真正可用能力的那一步。 |
| 依赖 | 模块可能需要别的符号、能力或框架先就位才能正常工作。 |
| 卸载 | 模块退出系统前需要收回资源、解除绑定并确认没人再依赖它。 |
为什么重要
- 它帮助你理解“模块化”不只是编译形式,而是运行期系统组织方式。
- 很多驱动之所以显得复杂,不只是因为它会和硬件对话,还因为它要经历装入、接管、存在、退出这些阶段。
- 理解生命周期后,你会更容易明白为什么引用计数、对象模型、异步清理会反复出现。
- 它让你把“功能存在”改理解成“功能如何被系统接住并持续管理”。
常见误解
- 误解一:模块就是一个可选文件。实际上它进入系统后会建立很多运行期关系。
- 误解二:能加载就说明生命周期问题不重要。实际上退出、清理、依赖和引用往往更难。
- 误解三:模块只和驱动有关。实际上很多非驱动能力也会以模块方式组织。
它不负责什么
- 它不替代构建系统;那一页更偏“怎么装出来”,这一页更偏“装进来以后怎么活”。
- 它不等于设备发现,但很多驱动模块装入后会立刻参与设备匹配与接管。
- 它不自动解决资源管理问题,恰恰会暴露更多生命周期和引用关系问题。
和其他模块的关系
| 相关模块 | 关系 |
|---|
| 构建系统与模块加载 | 那页讲构建与装配,这页细看模块进入运行期后的生命过程。 |
| Core API | 对象模型、引用计数、日志和异步工作常被用来支撑模块生命周期。 |
| 驱动模型 | 很多驱动模块一旦装入,就会进入总线匹配、probe 和资源管理路径。 |
| workqueue / 并发 | 模块退出时常常要面对异步工作尚未结束、对象仍被引用等问题。 |
读完这页后,你应该能回答
- 为什么模块不是“装上就完事”,而是有完整生命周期?
- 为什么模块退出往往比模块进入更难处理?
- 为什么模块生命周期会和引用计数、异步执行、驱动接管绑在一起?
后面适合继续问:为什么某些模块几乎不适合随便卸载?模块装入后到底如何变成设备或系统能力的一部分?生命周期问题为什么经常和异步清理纠缠在一起?