
Linux设备驱动模块加载机制深度解析1. 内核模块加载概述1.1 模块加载基本流程在Linux内核开发中模块加载是将编译好的内核模块(.ko文件)动态集成到运行中的内核的关键过程。用户空间通过insmod命令触发模块加载流程insmod xx.ko # 加载xx模块该操作需要root权限执行过程主要分为两个阶段用户空间将模块文件数据读取到内存通过sys_init_module系统调用进入内核处理流程1.2 系统调用接口sys_init_module是模块加载的核心系统调用其函数原型为long sys_init_module(void __user *umod, unsigned long len, const char __user *uargs);参数说明umod用户空间模块文件数据的内存地址len模块文件数据大小uargs传递给模块的参数内存地址2. 关键数据结构分析2.1 load_info结构体load_info结构体在模块加载过程中临时记录关键参数struct load_info { const char *name; struct module *mod; Elf_Ehdr *hdr; // 模块文件内容指针 unsigned long len; // 模块文件大小 Elf_Shdr *sechdrs; char *secstrings, *strtab; // ...其他成员省略... };2.2 module结构体struct module代表内核中加载的模块实体struct module { enum module_state state; // 模块状态 struct list_head list; // 内核模块链表节点 char name[MODULE_NAME_LEN]; // 模块名 const struct kernel_symbol *syms; // 导出符号表 int (*init)(void); // 初始化函数指针 void (*exit)(void); // 退出函数指针 // ...其他成员省略... };模块状态定义enum module_state { MODULE_STATE_LIVE, // 加载成功 MODULE_STATE_COMING, // 正在加载 MODULE_STATE_GOING, // 加载失败 MODULE_STATE_UNFORMED // 配置中 };3. 模块加载核心流程3.1 权限检查与数据复制sys_init_module首先执行权限检查err may_init_module(); if (err) return err;然后通过copy_module_from_user将模块数据从用户空间复制到内核空间err copy_module_from_user(umod, len, info); if (err) return err;3.2 load_module函数解析load_module是实际完成模块加载的核心函数主要分为两部分3.2.1 第一部分模块准备ELF内存视图构造在内核空间建立模块的ELF静态视图字符串表创建设置.shstrtab节区名称字符串表关键节区查找定位.modinfo、__versions等特殊节区HDR视图改写调整节区头表中的地址指针模块内存分配通过layout_and_allocate分配最终内存空间3.2.2 符号处理与重定位导出符号处理处理模块向外部导出的符号未解决引用处理解析模块中的未定义符号重定位操作修正静态链接与动态加载的地址差异3.3 模块初始化通过do_init_module完成模块初始化调用模块构造函数(do_mod_ctors)执行模块初始化函数(init)释放临时内存空间(HDR视图和INIT节区)4. 高级加载特性4.1 模块参数传递内核模块可通过module_param宏声明参数加载时通过uargs传递module_param(name, type, perm);4.2 模块依赖管理内核维护模块间的依赖关系在加载过程中建立source_list记录本模块依赖的其他模块target_list记录依赖本模块的其他模块4.3 版本控制机制通过.modinfo节区实现license模块许可证信息vermagic模块版本校验信息5. 内存管理细节5.1 内存区域划分模块加载过程涉及三种内存区域HDR视图初始加载的临时ELF映像CORE区域模块常驻内存部分INIT区域初始化专用内存(加载后释放)5.2 内存释放策略HDR视图在do_init_module前通过free_copy释放INIT区域在初始化完成后释放6. 模块状态跟踪内核通过module_state跟踪加载过程MODULE_STATE_UNFORMED初始配置阶段MODULE_STATE_COMING开始加载MODULE_STATE_LIVE加载成功MODULE_STATE_GOING加载失败7. 系统集成成功加载的模块会被链接到内核维护的全局模块链表modules中通过struct module的list成员实现。