内核模块符号的导出

复制代码
grep -rn "EXPORT_SYMBOL" 

搜索EXPORT_SYSMBOL这个宏

这一节讲的是 **"内核模块之间如何共享函数 / 变量" 的核心机制 **,可以拆解为 3 个关键部分理解:

1. 为什么需要 "内核模块符号导出"?

内核模块编译后是独立的.ko文件,默认情况下:

  • 模块 A 里的函数 / 变量,模块 B 是 "看不见" 的,没法直接调用;
  • 但复杂驱动需要分层(比如把 "硬件控制" 和 "业务逻辑" 拆成两个模块),这时候就需要让模块 A 把自己的函数 / 变量 "暴露出来",供模块 B 调用 ------ 这个 "暴露" 的操作,就是 "符号导出"。

2. 什么是 "内核模块符号导出"?

简单说:在模块里,用特定宏把函数 / 变量标记为 "公共可用",当这个模块加载到内核时,这些函数 / 变量会被记录到内核公共符号表里,其他模块加载时就能从这个表中找到并调用它们。

3. 具体怎么实现(用到的工具)?

这一节里提到的两个宏,就是实现符号导出的核心:

作用
EXPORT_SYMBOL(sym) 导出符号(函数 / 变量,sym是要导出的名字),所有内核模块都能调用
EXPORT_SYMBOL_GPL(sym) 仅允许遵循 GPL 协议的内核模块调用(因为 Linux 内核是 GPL 协议的)

4. 额外注意点

  • 头文件不用单独引 :这两个宏定义在include/linux/export.h里,但内核模块的常用头文件module.h已经包含了export.h,所以写模块代码时,只要包含了#include <linux/module.h>,就可以直接用这两个宏。
  • 符号表的记录 :导出的符号会被记录到内核的Module.symvers文件中(之前提到的那个文件),其他模块编译时需要依赖这个文件,才能找到导出的符号。

举个简单例子(帮助理解)

比如你写了两个模块:

  • 模块 A(导出方)

    c

    复制代码
    #include <linux/module.h>
    // 定义一个要导出的函数
    void my_shared_func(void) {
        printk("这是模块A导出的函数\n");
    }
    // 导出这个函数,供其他模块调用
    EXPORT_SYMBOL(my_shared_func);
    
    // 模块加载/卸载函数(省略)
    module_init(xxx_init);
    module_exit(xxx_exit);
    MODULE_LICENSE("GPL");
  • 模块 B(调用方)

    c

    复制代码
    #include <linux/module.h>
    // 声明要调用的、模块A导出的函数
    extern void my_shared_func(void);
    
    static int __init b_init(void) {
        my_shared_func(); // 直接调用模块A导出的函数
        return 0;
    }
    module_init(b_init);
    MODULE_LICENSE("GPL");

当模块 A 先加载到内核,模块 B 再加载时,就能成功调用my_shared_func------ 这就是符号导出的实际作用。

相关推荐
Trouvaille ~10 小时前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
芷栀夏10 小时前
深度解析 CANN 异构计算架构:基于 ACL API 的算子调用实战
运维·人工智能·开源·cann
全栈工程师修炼指南11 小时前
Nginx | stream 四层反向代理:SSL、PREREAD 阶段模块指令浅析与实践
运维·网络·网络协议·nginx·ssl
旖旎夜光11 小时前
Linux(13)(中)
linux·网络
威迪斯特12 小时前
CentOS图形化操作界面:理论解析与实践指南
linux·运维·centos·组件·图形化·桌面·xserver
一方热衷.12 小时前
在线安装对应版本NVIDIA驱动
linux·运维·服务器
独自归家的兔12 小时前
ubuntu系统安装dbswitch教程 - 备份本地数据到远程服务器
linux·运维·ubuntu
m0_6948455712 小时前
tinylisp 是什么?超轻量 Lisp 解释器编译与运行教程
服务器·开发语言·云计算·github·lisp
ONE_SIX_MIX12 小时前
ubuntu 24.04 用rdp连接,桌面黑屏问题,解决
linux·运维·ubuntu
龙飞0512 小时前
Systemd -systemctl - journalctl 速查表:服务管理 + 日志排障
linux·运维·前端·chrome·systemctl·journalctl