内核版本:Linux-4.19


1. EXPORT_SYMBOL 的作用:

EXPORT_SYMBOL 定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在其它内核模块中直接调用,即使用 EXPORT_SYMBOL 可以将一个函数以符号的方式导出给其他模块使用。

EXPORT_SYMBOL(name);
EXPORT_SYMBOL_GPL(name); 这两个宏均用于给定的符号导出到模块外部。_GPL版本导出的符号只能被 GPL 许可证下的模块使用。

我们以 EXPORT_SYMBOL 为例。

2. EXPORT_SYMBOL 宏定义如下:

#define EXPORT_SYMBOL(sym)					\
__EXPORT_SYMBOL(sym, "")

3. __EXPORT_SYMBOL 宏定义如下:

#include <generated/autoksyms.h>
#define __EXPORT_SYMBOL(sym, sec) \
__cond_export_sym(sym, sec, __is_defined(__KSYM_##sym))
#define __cond_export_sym(sym, sec, conf) \
___cond_export_sym(sym, sec, conf)
#define ___cond_export_sym(sym, sec, enabled) \
__cond_export_sym_##enabled(sym, sec)
#define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec)
#define __cond_export_sym_0(sym, sec) /* nothing */

4. ___EXPORT_SYMBOL 宏定义如下:

/* For every exported symbol, place a struct in the __ksymtab section */
#define ___EXPORT_SYMBOL(sym, sec) \
extern typeof(sym) sym; \
__CRC_SYMBOL(sym, sec) \
static const char __kstrtab_##sym[] \
__attribute__((section("__ksymtab_strings"), used, aligned(1))) \
= #sym; \
__KSYMTAB_ENTRY(sym, sec)

5. __KSYMTAB_ENTRY 宏定义如下:

#define __KSYMTAB_ENTRY(sym, sec)					\
static const struct kernel_symbol __ksymtab_##sym \
__attribute__((section("___ksymtab" sec "+" #sym), used)) \
= { (unsigned long)&sym, __kstrtab_##sym } struct kernel_symbol {
unsigned long value;
const char *name;
};

经过层层的宏展开,得到了最终的结果。

6. 分析总结:

在内核符号导出中。调用了EXPORT_SYMBOL(sym),说的来说完成了以下操作:
(1) 定义一个字符数组存放内核导出符号的名称。并放置到 “__ksymtab_strings” 的 section 中。
(2) 定义一个内核符号结构用于存放导出符号的内存地址和名称,并放置到 “ "___ksymtab" sec "+" #sym ” 中。

内核中 EXPORT_SYMBOL 标志分析的更多相关文章

  1. linux内核中链表代码分析---list.h头文件分析(一)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...

  2. linux内核中链表代码分析---list.h头文件分析(二)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...

  3. linux内核中mtd架构分析

    一. 引言 MTD(memory technology device内存技术设备)是用于访问memory设备(RAM.ROM.flash)的Linux的子系统.MTD的主要目的是为了使新的memory ...

  4. FreeBSD 内核中的SYSINIT分析【转】

    FreeBSD kernel是一个膨大的系统, 对于这样一个大系统, 里面往往包含了大量的子系统和  模块,当系统初始化时这些模块就需要初始化, 按照通常的思路,这些初始化过程必须在某处  被显式地调 ...

  5. Linux内核中的GPIO系统之(3):pin controller driver代码分析

    一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道,pin control subsystem也不例外,被它驱动的硬件叫做pin controller(一般ARM soc的datash ...

  6. Linux内核中的list用法和实现分析

    这些天在思考知识体系的完整性,发现总是对消息队列的实现不满意,索性看看内核里面的链表实现形式,这篇文章就当做是学习的i笔记吧.. 内核代码中有很多的地方使用了list,而这个list的用法又跟我们平时 ...

  7. Linux内核中SPI总线驱动分析

    本文主要有两个大的模块:一个是SPI总线驱动的分析 (研究了具体实现的过程): 另一个是SPI总线驱动的编写(不用研究具体的实现过程). 1 SPI概述 SPI是英语Serial Peripheral ...

  8. 内核中container_of宏的详细分析【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637597.html 内核中container_of宏的详细分析 16年2月28日09:00:37 内核中 ...

  9. Linux内核分析--内核中的数据结构双向链表续【转】

    在解释完内核中的链表基本知识以后,下面解释链表的重要接口操作: 1. 声明和初始化 实际上Linux只定义了链表节点,并没有专门定义链表头,那么一个链表结构是如何建立起来的呢?让我们来看看LIST_H ...

随机推荐

  1. 若干排序算法的Python实现方法及原理

    今天突然想到了一个问题:让你立即把堆排.快排等等排序算法写出来会不会,并且不能犯逻辑错误? 我说:不会,至少需要思考一下,并且可能还需要时间调试. 之前总是觉得,不就是排序算法吗?有什么大不了的?网上 ...

  2. SOLID原则(OOD&OOP)

    SOLID原则是面向对象编程和面向对象设计的头五大原则.学习及应用这五大原则可以构建一个易于维护和扩展的应用程序,我们一起看看到底是那五大原则. S--单一责任原则(SRP) --Single Res ...

  3. 自学java能不能找到找到一份java工作。

    关于自学Java能不能通过社招找到一份互联网公司Java开发的工作,有无数的人问出这样的问题,答案没有标准的,只能从概率去考虑.有的人可以,有的人不可以,有的人自学就业的概率就是高,有的概率就是低. ...

  4. 用node探究http缓存

    用node搞web服务和直接用tomcat.Apache做服务器不太一样, 很多工作都需要自己做.缓存策略也要自己选择,虽然有像koa-static,express.static这些东西可以用来管理静 ...

  5. 【转】委托的N种写法,你喜欢哪种?

    一.委托调用方式 1. 最原始版本: delegate string PlusStringHandle(string x, string y); class Program { static void ...

  6. [Leetcode]724. Find Pivot Index

    Given an array of integers nums, write a method that returns the "pivot" index of this arr ...

  7. OSPF 高级实验

    一.环境准备 1. 软件:GNS3 2. 路由:c7200 二.实验操作 实验要求: 1.理解 OSPF 虚链路原理及何时需要使用虚链路. 2.掌握 OSPF 虚链路配置方法. 3.掌握 OSPF 的 ...

  8. 设计模式之行为类模式PK

    行为类模式包括: 责任链模式 命令模式 解释器模式 迭代器模式 中介者模式 备忘录模式 观察者模式 状态模式 策略模式 模板方法模式 访问者模式 行为型模式涉及到算法和对象间职责的分配 行为类模式关注 ...

  9. vue学习笔记4

    父组件向子组件传值 组件实例定义方式,注意:一定要使用props属性来定义父组件传递过来的数据 <script> // 创建 Vue 实例,得到 ViewModel var vm = ne ...

  10. ArcEngine GroupLayer监听图层改变

    最近项目中需要用到在TOC监听图层的变化,从而针对添加的不同图层进行不同的操作.但是当TOC中添加图层组时,无法监听到图层组中添加图层的动作.也就无法获取到向图层组中添加的图层. 在开发手册中也没有找 ...