内核版本: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. BZOJ_3436_小K的农场_差分约束

    BZOJ_3436_小K的农场_差分约束 题意: 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得 一些含糊的信息(共m个),以下列三种形式描述 ...

  2. BZOJ_2440_[中山市选2011]完全平方数_容斥原理+线性筛

    BZOJ_2440_[中山市选2011]完全平方数_容斥原理 题意: 求第k个不是完全平方数倍数的数 分析: 二分答案,转化成1~x中不是完全平方数倍数的数的个数 答案=所有数-1个质数的平方的倍数+ ...

  3. Python数据结构应用6——树

    数据结构中的树的结点和机器学习中决策树的结点有一个很大的不同就是,数据结构中的树的每个叶结点都是独立的. 树的高度(Height)指叶结点的最大层树(不包含根结点) 一.树的建立 树可以这样定义:一棵 ...

  4. Java基础-单列设计模式

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  5. Angular2+ 使用 Protractor 与 Modify Header Value (HTTP Headers) 插件 完成 Windows Authorization 验证

    入职新公司第二周,接到了一个E2E测试的任务,两天的时间把所有的测试条件都写完了,结果剩下三天都卡在了Windows Authorization验证这里. 先说一下公司项目Authorize的逻辑 第 ...

  6. STM32F1固件库文件讲解与基于固件库新建MDK工程模板

    操作系统:win10 1.文件目录 (在cmd下用"cd 文件夹" 进入到要显示的文件夹,如cd d:\en.stsw-stm32054,然后输入tree 回车就会出现上图的目录结 ...

  7. linux命令----查看磁盘空间

    今天用“web发布平台”发布测试的服务,两个节点中发现有一个节点没有发布成功,压测TPS始终上不去,排查后发现只有一个节点在打日志,另一个节点的服务进程都没有在运行,由此断定应该是没有发布成功,有点坑 ...

  8. 页面性能优化-原生JS实现图片懒加载

    在项目开发中,我们往往会遇到一个页面需要加载很多图片的情况.我们可以一次性加载全部的图片,但是考虑到用户有可能只浏览部分图片.所以我们需要对图片加载进行优化,只加载浏览器窗口内的图片,当用户滚动时,再 ...

  9. 树莓派3b+_32位linux系统arm架构安装JDK

    如图我的Raspbian系统如下图版本信息: 可以看到是armv7l,我查了一下是32位的arm架构,即下载第一个就好了 然后用SSH Secure Shell远程上去把压缩包或者解压后的文件传过去 ...

  10. PdfReader按页将PDF切割成多个PDF

    private MemoryStream GetNewPdfByPageNum(PdfReader pdfReader, int pageNum) { MemoryStream memoryStrea ...