第二章:模块的编译与运行-12 Initialization and Shutdown

In continuation of the previous text:第二章:模块的编译与运行-11 Preliminaries, let's GO ahead.

Initialization and Shutdown

As already mentioned, the module initialization function registers any facility offered by the module. By facility, we mean a new functionality, be it a whole driver or a new software abstraction, that can be accessed by an application. The actual definition of the initialization function always looks like:

正如前文所述,模块初始化函数负责注册模块提供的所有 “功能实体”(facility)。这里的 “功能实体” 指的是模块提供的新功能,无论是完整的驱动程序还是新的软件抽象,应用程序都可通过它来访问模块功能。初始化函数的实际定义格式固定,如下所示:

static int __init initialization_function(void)
{
/* Initialization code here */
}

module_init(initialization_function);

Initialization functions should be declared static, since they are not meant to be visible outside the specific file; there is no hard rule about this, though, as no function is exported to the rest of the kernel unless explicitly requested. The __init token in the definition may look a little strange; it is a hint to the kernel that the given function is used only at initialization time. The module loader drops the initialization function after the module is loaded, making its memory available for other uses. There is a similar tag (__initdata) for data used only during initialization. Use of __init and
__initdata is optional, but it is worth the trouble. Just be sure not to use them for any function (or data structure) you will be using after initialization completes. You may also encounter __devinit and __devinitdata in the kernel source; these translate to __init and __initdata only if the kernel has not been configured for hotpluggable devices. We will look at hotplug support in Chapter 14.

初始化函数应声明为 static(静态),因为它们无需在当前文件之外可见;不过这并非强制规则 —— 毕竟,除非显式导出,否则任何函数都不会对内核其他部分可见。定义中的 __init 标记可能看起来有些特殊,它是给内核的一个 “提示”,表明该函数仅在初始化阶段使用。模块加载完成后,模块加载器会丢弃这个初始化函数,释放其占用的内存以供其他用途。

对于仅在初始化阶段使用的数据,内核也提供了类似的标记 __initdata__init 和 __initdata 的使用是可选的,但花时间添加它们很有必要。只需注意,不要将它们用于初始化完成后仍需使用的函数(或数据结构)即可。在内核源码中,你可能还会遇到 __devinit 和 __devinitdata,只有当内核未配置为支持热插拔设备时,它们才会分别等同于 __init 和 __initdata。我们会在第 14 章介绍热插拔支持相关内容。

The use of module_init is mandatory. This macro adds a special section to the module’s object code stating where the module’s initialization function is to be found. Without this definition, your initialization function is never called.

module_init 的使用是强制要求。这个宏会在模块的目标代码中添加一个特殊段,用于告知内核模块初始化函数的位置。如果没有这个定义,你的初始化函数永远不会被调用。

补充说明:

  1. static 修饰的核心作用

    • 限制函数作用域:static 确保初始化函数仅在当前 .c 文件内可见,避免与其他模块或内核代码中的函数重名,减少命名空间污染。

    • 无导出需求:初始化函数仅在模块加载时被内核调用一次,无需通过 EXPORT_SYMBOL 导出,用 static 修饰符合 “最小权限” 原则。

  2. __init 与 __initdata 的内存优化逻辑

    • 内存释放机制:内核会将标记为 __init 的函数和 __initdata 的数据,编译到专门的 ELF 段(如 .init.text 和 .init.data)。模块加载完成后,内核会释放这些段的内存(对于内置内核模块,系统启动完成后释放),节省内存资源。

    • 使用禁忌:若函数 / 数据在初始化后仍需使用(如驱动的 read/write 函数、设备状态变量),绝对不能用这两个标记,否则会导致内存被释放后访问无效地址,引发内核崩溃。

  3. module_init 宏的本质

    • 并非函数调用:module_init(foo) 不会直接调用 foo,而是通过宏定义,将 foo 的地址记录到模块的 “初始化函数入口” 段(.modinfo 或 .initcall 相关段)。

    • 内核调用时机:模块加载时,内核会从该段读取初始化函数地址,自动调用它;若返回非 0 值(表示初始化失败),内核会立即卸载模块,释放已分配的资源。

  4. 常见的注册功能与对应函数模块通过调用内核的 “注册函数” 向系统提供功能,不同功能对应不同的注册接口,例如:

    • 字符设备注册:register_chrdev() 或 cdev_add()

    • 中断处理函数注册:request_irq()

    • /proc 文件创建:proc_create()

    • 内核定时器注册:add_timer()。这些注册函数的核心是 “将模块的功能接入内核框架”,让内核知道如何通过统一接口(如系统调用、中断)触发模块的具体逻辑。

  5. 初始化函数的返回值规则

    • 成功:返回 0,表示功能注册完成,模块加载成功。

    • 失败:返回负的错误码(如 -ENOMEM 表示内存分配失败、-EBUSY 表示设备已被占用),内核会根据错误码在日志中输出原因,同时拒绝加载模块。

Modules can register many different types of facilities, including different kinds of devices, filesystems, cryptographic transforms, and more. For each facility, there is a specific kernel function that accomplishes this registration. The arguments passed to the kernel registration functions are usually pointers to data structures describing the new facility and the name of the facility being registered. The data structure usually contains pointers to module functions, which is how functions in the module body get called.

模块可以注册多种不同类型的功能实体,包括各类设备、文件系统、加密转换等。对于每种功能实体,内核都提供了专门的函数来完成注册操作。

传递给内核注册函数的参数,通常包含两个核心部分:一是指向 “描述新功能实体的数据结构” 的指针,二是待注册功能实体的名称。而这个数据结构中,通常会包含指向模块函数的指针 —— 模块主体中的函数正是通过这种方式被内核调用的。

The items that can be registered go beyond the list of device types mentioned in Chapter 1. They include, among others, serial ports, miscellaneous devices, sysfs entries, /proc files, executable domains, and line disciplines. Many of those registrable items support functions that aren’t directly related to hardware but remain in the “software abstractions” field. Those items can be registered, because they are integrated into the driver’s functionality anyway (like /proc files and line disciplines for example).

可注册的功能实体远不止第 1 章提到的设备类型。除设备外,还包括(但不限于)串行端口、杂项设备、sysfs 条目、/proc 文件、可执行域和线路规程。这些可注册的功能实体中,有很多支持的函数与硬件无直接关联,而是属于 “软件抽象” 范畴。它们之所以能被注册,是因为无论如何,这些功能都会集成到驱动程序的功能中(例如 /proc 文件和线路规程就是典型例子)。

There are other facilities that can be registered as add-ons for certain drivers, but their use is so specific that it’s not worth talking about them; they use the stacking technique, as described in the section “The Kernel Symbol Table.” If you want to probe further, you can grep for EXPORT_SYMBOL in the kernel sources, and find the entry points offered by different drivers. Most registration functions are prefixed with register_, so another possible way to find them is to grep for register_ in the kernel source.

还有一些功能实体可作为特定驱动程序的附加组件进行注册,但它们的用途非常特殊,在此不值得展开讨论;这类功能实体采用的是 “模块堆叠” 技术,正如 “内核符号表” 一节中所述。如果想进一步探索,可以在内核源码中搜索 EXPORT_SYMBOL,找到不同驱动程序提供的入口点。大多数注册函数都以 register_ 为前缀,因此另一种查找方式是在内核源码中搜索 register_

补充说明:

  1. 注册函数的 “参数规律”​​​​​​​​​​​​​​

    内核注册函数的参数设计遵循统一逻辑,核心是 “用数据结构描述功能,用名称标识功能”:

    • 数据结构:例如注册字符设备时用 struct cdev,注册 /proc 文件时用 struct proc_ops,这些结构中会包含功能的核心配置(如设备号、函数指针);

    • 名称:通常是字符串(如 /proc/hello、“my_serial”),用于内核标识和管理该功能实体,避免冲突。

  2. 软件抽象类功能实体的作用​​​​​​​

    这类功能实体(如 sysfs 条目、/proc 文件)的核心价值是 “提供用户态与内核态的交互接口”:

    • /proc 文件:用户可通过 cat/echo 读写文件,间接调用模块函数(如查看设备状态、配置参数);

    • sysfs 条目:在 /sys 目录下生成文件,用于暴露设备属性(如温度、电压),遵循内核统一的设备模型规范,便于工具(如 lsusb)识别。

  3. “register_” 前缀的搜索意义

    以 register_ 为前缀是内核注册函数的约定(对应卸载函数通常以 unregister_ 为前缀),例如:

    • 注册中断:register_irq() → 卸载:unregister_irq()

    • 注册文件系统:register_filesystem() → 卸载:unregister_filesystem()。在内核源码中搜索该前缀,能快速定位某类功能的注册接口,是驱动开发中常用的 “查源码” 技巧。

  4. 附加组件注册与模块堆叠的关联

    附加组件(如某驱动的扩展功能)需依赖主驱动导出的符号(通过 EXPORT_SYMBOL),注册时需先加载主驱动,再加载附加组件 —— 这正是模块堆叠的典型场景。例如,USB 无线网卡驱动(附加组件)需依赖 usbcore 驱动(主驱动)导出的 USB 核心函数,注册时需先确保 usbcore 已加载。

 

Microsoft Windows [版本 10.0.22631.2861] (c) Microsoft Corporation。保留所有权利。 C:\Users\Administrator>cd /d E:\AI_System\web_ui E:\AI_System\web_ui>cd /d E:\AI_System\web_ui E:\AI_System\web_ui>python server.py 2025-08-12 04:54:19 - CoreConfig - INFO - 加载环境变量... 2025-08-12 04:54:19 - CoreConfig - WARNING - 配置文件不存在: E:\AI_System\config\system_config.yaml 2025-08-12 04:54:19 - CoreConfig - INFO - 合并默认配置... 2025-08-12 04:54:19 - CoreConfig - INFO - 创建必要目录... 2025-08-12 04:54:19 - CoreConfig - INFO - 配置加载完成 | 条目数: 11 2025-08-12 04:54:19 - CoreConfig - INFO - [OK] 配置管理器初始化完成 | 环境前缀: AI_SYSTEM_ | 基础目录: E:\AI_System 2025-08-12 04:54:19,649 - CoreInit - INFO - Core module initialization started 2025-08-12 04:54:19,649 - EnvironmentManager - INFO - 环境管理器初始化完成 (基础目录: E:\AI_System\data\environment) 2025-08-12 04:54:19,649 - CoreInit - INFO - Environment manager created: DefaultEnvironment 2025-08-12 04:54:19,649 - CoreInit - INFO - Core module initialized successfully 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 日志系统初始化完成 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 日志系统初始化完成 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 日志级别: INFO 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 日志级别: INFO 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 日志文件: logs/web_server.log 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 日志文件: logs/web_server.log 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 系统初始化器创建, 基础目录: E:\AI_System 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 系统初始化器创建, 基础目录: E:\AI_System 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - ================================================== 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - ================================================== 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 开始初始化AI系统 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 开始初始化AI系统 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - ================================================== 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - ================================================== 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\agent 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\agent 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\core 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\core 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\utils 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\utils 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\config 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\config 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\cognitive_arch 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\cognitive_arch 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\environment 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 添加路径: E:\AI_System\environment 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - AI核心初始化 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - AI核心初始化 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 硬件管理器初始化 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 硬件管理器初始化 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 生活调度器初始化 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 生活调度器初始化 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 开始初始化AI智能体 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 开始初始化AI智能体 2025-08-12 04:54:19 - WebServer - ERROR - 6396 - 6872 - 导入 AutonomousAgent 失败: No module named 'core.subsystem_registry' 2025-08-12 04:54:19 - WebServer - ERROR - 6396 - 6872 - 导入 AutonomousAgent 失败: No module named 'core.subsystem_registry' 2025-08-12 04:54:19 - WebServer - ERROR - 6396 - 6872 - Traceback (most recent call last): File "E:\AI_System\web_ui\server.py", line 460, in initialize_ai_agent from agent.autonomous_agent import AutonomousAgent File "E:\AI_System\agent\__init__.py", line 14, in <module> from .autonomous_agent import AutonomousAgent File "E:\AI_System\agent\autonomous_agent.py", line 24, in <module> from core.subsystem_registry import SubsystemRegistry ModuleNotFoundError: No module named 'core.subsystem_registry' 2025-08-12 04:54:19 - WebServer - ERROR - 6396 - 6872 - Traceback (most recent call last): File "E:\AI_System\web_ui\server.py", line 460, in initialize_ai_agent from agent.autonomous_agent import AutonomousAgent File "E:\AI_System\agent\__init__.py", line 14, in <module> from .autonomous_agent import AutonomousAgent File "E:\AI_System\agent\autonomous_agent.py", line 24, in <module> from core.subsystem_registry import SubsystemRegistry ModuleNotFoundError: No module named 'core.subsystem_registry' 2025-08-12 04:54:19 - WebServer - WARNING - 6396 - 6872 - 无法导入AutonomousAgent,使用模拟智能体 2025-08-12 04:54:19 - WebServer - WARNING - 6396 - 6872 - 无法导入AutonomousAgent,使用模拟智能体 2025-08-12 04:54:19 - WebServer - WARNING - 6396 - 6872 - 使用模拟智能体作为回退方案 2025-08-12 04:54:19 - WebServer - WARNING - 6396 - 6872 - 使用模拟智能体作为回退方案 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 环境管理器初始化成功 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 环境管理器初始化成功 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 环境管理器已启动 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 环境管理器已启动 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 环境管理器初始化成功 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 环境管理器初始化成功 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 进化监视器启动 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 进化监视器启动 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 所有系统组件初始化完成 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 所有系统组件初始化完成 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 开发服务器启动: http://0.0.0.0:5000 2025-08-12 04:54:19 - WebServer - INFO - 6396 - 6872 - 开发服务器启动: http://0.0.0.0:5000 * Serving Flask app 'server' * Debug mode: off
08-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeeplyMind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值