export symbol 与 export symbol gpl

export symbol 与 export symbol gpl1.EXPORT_SYMBOLEXPORT_SYMBOL(my_pub_func);在预编译阶段会解析为:externvoid*__crc_my_pub_func__attribute__((weak));staticconstunsignedlong__kcrctab_my_pub_func__attribute__((__used__))__attri

大家好,又见面了,我是你们的朋友全栈君。

1.EXPORT_SYMBOL

EXPORT_SYMBOL( my_pub_func);

在预编译阶段会解析为:

extern void *__crc_my_pub_func __attribute__((weak));

static const unsigned long __kcrctab_my_pub_func __attribute__((__used__)) __attribute__((section(“__kcrctab” “”), unused)) = (unsigned long) &__crc_my_pub_func;

static const char __kstrtab_my_pub_func[] __attribute__((section(“__ksymtab_strings”))) = “” “my_pub_func”;

static const struct kernel_symbol __ksymtab_my_pub_func __attribute__((__used__)) __attribute__((section(“__ksymtab” “”), unused)) = { (unsigned long)&my_pub_func, __kstrtab_my_pub_func };

很显然__ksymtab_my_pub_func存储了my_pub_func的地址和符号信息,该符号对应的地址

只有insmod后才会确定;

__ksymtab_my_pub_func会链接到__ksymtab section,__ksymtab section中的所有内容就构成了

内核”导出”的符号表,这个表在insmod 时候会用到.
2./proc/kallsyms

cat /proc/kallsyms会打印出内核当前的符号表,例如:



d8834a24 t snd_free_sgbuf_pages [snd_page_alloc]

c0180d7a U create_proc_entry [snd_page_alloc]

d88341d8 T snd_dma_free_pages [snd_page_alloc]

c013d858 U __get_free_pages [snd_page_alloc]

d8834ab5 t snd_malloc_sgbuf_pages [snd_page_alloc]

c014f906 U kmem_cache_alloc [snd_page_alloc]

c0106dcd U dma_alloc_coherent [snd_page_alloc]



其中第一列是该符号在内核地址空间中的地址;第二列是符号属性,小写表示

局部符号,大写表示全局符号,具体含义参考man nm; 第三列表示符号字符串.

这里只显示EXPORT_SYMBOL,EXPROT_SYMBOL_GPL处理过的符号。
3.System.map内核符号文件

通过more /boot/System.map 可以查看内核符号列表。

可以显示编译好内核后所有在内核中的符号,模块中的要另行查看。
4.通过nm vmlinux也可以查看内核符号列表

可以显示编译好内核后所有在内核中的符号,模块中的要另行查看。
5.通过nm module_name可以查看模块的符号列表

但是得到是相对地址,只有加载后才会分配绝对地址。比如:e1000模块,如果e1000中的符号经过EXPORT_SYMBOL处理,等加载后,我们可以通过more /boot/System.map和nm vmlinux命令查看到,但是没有EXPORT_SYMBOL的,我目前不知道怎么查看。
另个试验:

1.验证EXPORT_SYMBOL

模块hello.c代码如下:

     
Java代码
复制代码
收藏代码export symbol 与 export symbol gpl

  1. 1 #include <linux/module.h>  
  2.       2 #include <linux/kernel.h>  
  3.       3 
  4.       4 static int __init a_init_module(void)  
  5.       5 {  
  6.       6     unsigned long *__kcrctab_per_cpu__hrtimer_bases = 0xc02678b4;  
  7.       7     unsigned char *__kstrtab_per_cpu__hrtimer_bases = 0xc026926b;  
  8.       8     struct kernel_symbol *__ksymtab_per_cpu__hrtimer_bases = 0xc0265018;  
  9.       9 
  10.      10     printk(“__kcrctab_per_cpu__hrtimer_bases = %08x\n”, *__kcrctab_per_cpu__hrtimer_bases);  
  11.      11     printk(“__kstrtab_per_cpu__hrtimer_bases = %s\n”, __kstrtab_per_cpu__hrtimer_bases);  
  12.      12     printk(“__ksymtab_per_cpu__hrtimer_bases value = %08x, name = %s\n”, __ksymtab_per_cpu__hrtimer_bases->value,\  
  13.      13     __ksymtab_per_cpu__hrtimer_bases->name);  
  14.      14 
  15.      15     return 0;  
  16.      16 }  
  17.      17 
  18.      18 static void __exit a_cleanup_module(void)  
  19.      19 {  
  20.      20     printk(“Bye, Bye\n”);  
  21.      21 }  
  22.       22 module_init(a_init_module);  
  23.      23 module_exit(a_cleanup_module); 
1 #include <linux/module.h>
      2 #include <linux/kernel.h>
      3
      4 static int __init a_init_module(void)
      5 {
      6     unsigned long *__kcrctab_per_cpu__hrtimer_bases = 0xc02678b4;
      7     unsigned char *__kstrtab_per_cpu__hrtimer_bases = 0xc026926b;
      8     struct kernel_symbol *__ksymtab_per_cpu__hrtimer_bases = 0xc0265018;
      9
     10     printk("__kcrctab_per_cpu__hrtimer_bases = %08x\n", *__kcrctab_per_cpu__hrtimer_bases);
     11     printk("__kstrtab_per_cpu__hrtimer_bases = %s\n", __kstrtab_per_cpu__hrtimer_bases);
     12     printk("__ksymtab_per_cpu__hrtimer_bases value = %08x, name = %s\n", __ksymtab_per_cpu__hrtimer_bases->value,\
     13     __ksymtab_per_cpu__hrtimer_bases->name);
     14
     15     return 0;
     16 }
     17
     18 static void __exit a_cleanup_module(void)
     19 {
     20     printk("Bye, Bye\n");
     21 }
      22 module_init(a_init_module);
     23 module_exit(a_cleanup_module);
     

     Makefile配置文件如下:

     

Java代码
复制代码
收藏代码export symbol 与 export symbol gpl

  1. 1 #  
  2.      2 # Makefile for hello.c file  
  3.      3 #  
  4.      4 KDIR:=/lib/modules/$(shell uname -r)/build  
  5.      5 
  6.      6 obj-m:=hello.o  
  7.      7 
  8.      8 default:  
  9.      9     $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules  
  10.     10 clean:  
  11.     11     $(RM) .*.cmd *.mod.c *.o *.ko -r .tmp* 
 1 #
      2 # Makefile for hello.c file
      3 #
      4 KDIR:=/lib/modules/$(shell uname -r)/build
      5
      6 obj-m:=hello.o
      7
      8 default:
      9     $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
     10 clean:
     11     $(RM) .*.cmd *.mod.c *.o *.ko -r .tmp*

     make; insmod hello.ko之后通过dmesg的运行结果:

__kcrctab_per_cpu__hrtimer_bases = 1ac19564

__kstrtab_per_cpu__hrtimer_bases = per_cpu__hrtimer_bases

__ksymtab_per_cpu__hrtimer_bases value = c0279ea0, name = per_cpu__hrtimer_bases
通过nm vmlinux | grep per_cpu__hrtimer_bases我们可以看到如下的对应关系:

1ac19564 A __crc_per_cpu__hrtimer_bases

c02678b4 r __kcrctab_per_cpu__hrtimer_bases

c026926b r __kstrtab_per_cpu__hrtimer_bases

c0265018 r __ksymtab_per_cpu__hrtimer_bases

c0279ea0 d per_cpu__hrtimer_bases
对比如上两列数据。

本实验只是为了验证一下EXPROT_SYMBOL.

2.1.EXPORT_SYMBOL和EXPORT_SYMBOL_GPL的区别

模块1:hello.c

     

Java代码
复制代码
收藏代码export symbol 与 export symbol gpl

  1. 1 #include <linux/module.h>  
  2.       2 #include <linux/kernel.h>  
  3.       3 
  4.       4 void function1(void)  
  5.       5 {  
  6.       6     printk(“hello wold\n”);  
  7.       7 }  
  8.       8 EXPORT_SYMBOL(function1);  
  9.       9 
  10.      10 void function2(void)  
  11.      11 {  
  12.      12     printk(“hello wold again\n”);  
  13.      13 }  
  14.      14 EXPORT_SYMBOL_GPL(function2);  
  15.      15 
  16.      16 
  17.      17 static int __init a_init_module(void)  
  18.      18 {  
  19.      19     return 0;  
  20.      20 }  
  21.      21 
  22.      22 static void __exit a_cleanup_module(void)  
  23.      23 {  
  24.      24     printk(“<1>Bye, Bye\n”);  
  25.      25 
  26.      26 }  
  27.      27 
  28.      28 module_init(a_init_module);  
  29.      29 module_exit(a_cleanup_module); 
1 #include <linux/module.h>
      2 #include <linux/kernel.h>
      3
      4 void function1(void)
      5 {
      6     printk("hello wold\n");
      7 }
      8 EXPORT_SYMBOL(function1);
      9
     10 void function2(void)
     11 {
     12     printk("hello wold again\n");
     13 }
     14 EXPORT_SYMBOL_GPL(function2);
     15
     16
     17 static int __init a_init_module(void)
     18 {
     19     return 0;
     20 }
     21
     22 static void __exit a_cleanup_module(void)
     23 {
     24     printk("<1>Bye, Bye\n");
     25
     26 }
     27
     28 module_init(a_init_module);
     29 module_exit(a_cleanup_module);

模块2:hello2.c

   

Java代码
复制代码
收藏代码export symbol 与 export symbol gpl

  1. 1 #include <linux/module.h>  
  2.      2 #include <linux/kernel.h>  
  3.      3 
  4.      4 //MODULE_LICENSE(“GPL”);  
  5.      5 
  6.      6 static int __init a_init_module(void)  
  7.      7 {  
  8.      8     function1();  
  9.      9 //    function2();  
  10.     10     return 0;  
  11.     11 }  
  12.     12 
  13.     13 static void __exit a_cleanup_module(void)  
  14.     14 {  
  15.     15     printk(“<1>Bye, Bye\n”);  
  16.     16 
  17.     17 }  
  18.     18 
  19.     19 module_init(a_init_module);  
  20.     20 module_exit(a_cleanup_module); 
 1 #include <linux/module.h>
      2 #include <linux/kernel.h>
      3
      4 //MODULE_LICENSE("GPL");
      5
      6 static int __init a_init_module(void)
      7 {
      8     function1();
      9 //    function2();
     10     return 0;
     11 }
     12
     13 static void __exit a_cleanup_module(void)
     14 {
     15     printk("<1>Bye, Bye\n");
     16
     17 }
     18
     19 module_init(a_init_module);
     20 module_exit(a_cleanup_module);

    

    首先编译后两个模块:hello.ko, hello2.ko

    A.在hello2.c中注释掉MODULE_LICENSE(“GPL”)和function2()两行,先insmod hello.ko然后insmod hello2.ko,一切正常。

    B.先insmod hello2.ko然后insmod hello.ko,会有出错信息,通过dmesg查看显示如下:hello2: Unknown symbol function1

    C.在hello2.c中打开function2(),先insmod hello.ko然后insmod hello2.ko,模块hello2.ko无法加载,显示如下信息:insmod: error inserting ‘hello2.ko’: -1 File exists,通过dmesg查看显示如下:hello2: Unknown symbol function2。在hello2.c中打开MODULE_LICENSE(“GPL”)或者用MODULE_LICENSE(“Dual BSD/GPL”),先insmod hello.ko然后insmod hello2.ko,一切正常。

所以说EXPORT_SYMBOL_GPL的符号必须要用MODULE_LICENSE(“GPL”)或者用MODULE_LICENSE(“Dual BSD/GPL”)之后才能在模块中引用。而且MODULE_LICENSE(“char”)中的char不可以是任意字符,否则错误和没有MODULE_LICENSE效果一样。
    D.没有看MODULE_LICENSE内核代码,下一步去研读代码。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158162.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pantum打印机驱动安装m6506_打印机驱动怎么装(安装步骤)[通俗易懂]

    pantum打印机驱动安装m6506_打印机驱动怎么装(安装步骤)[通俗易懂]  您可以先下载打印机的驱动,首先打开控制面板,然后双击控制面板中的打印机和传真图标,安装新打印机直接点左边的添加打印机,接着弹出添加打印机向导,系统将自动检测打印机类型。接下来详细介绍:  1、一般打印机的说明书上会有驱动的下载链接或者是直接上品牌官网找到下载中心,下载对应型号的驱动;  2、在打开开始菜单找到【设备和打印机】,或者从【控制面板】中找到,硬件和声音的相关选项找到;  3、点击页面…

    2022年4月19日
    945
  • python股票数据分析_用Python抓取新浪的股票数据「建议收藏」

    最近做数据分析,先是找到了Tushare这个免费开源的第三方财经包,但后来用了几天之后发现,它的日交易历史数据有时候有不准确的情况,查看源代码发现,这个包的数据源是凤凰财经,而对比凤凰网站其站点的数据本身就是有出入的,所以到也不是Tushare的问题。于是百度了一圈,发现很多网友都是获取新浪的股票数据,包括其历史数据和实时数据。于是乎试了一下,发现速度还挺快,没有具体去测时间但从感官上要比Tush…

    2022年4月7日
    172
  • 框架梳理|企业大数据管理之道「建议收藏」

    框架梳理|企业大数据管理之道「建议收藏」大数据管理——企业转型升级与竞争力重塑之道》一书,从大数据驱动决策、大数据优化管理、大数据智慧营销、大数据发现创新、大数据推动转型、大数据保障安全六个维度全面分析了大数据对传统企业的应用价值,提供可借鉴的案例和深度有格局的思考。本文主要讲述的就是对于这本书的个人看法。

    2022年5月1日
    57
  • 初中英语语法(003)-be动词和一般动词的一般过去式

    初中英语语法(003)-be动词和一般动词的一般过去式be.动词和一般动词的过去式1、什么是过去式:当一个状态是当前的状态,或者一个动作发生在现在,那么就是现在时,动词要用现在式。当一个动作发生在过去,或者一个状态是过去的状态,现在已经没有了,那么就是过去时,动词要用过去式。因此,过去式用于过去的时间的状态和发生的事件。2、be.动词的过去式:be.动词的变化规则:am/is=&amp;gt;was,are=&amp;gt;were当时间副词改变的…

    2022年4月19日
    43
  • intellijidea2021最新激活码(JetBrains全家桶)[通俗易懂]

    (intellijidea2021最新激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~BI7JCUH1TG-eyJsaWNlb…

    2022年3月22日
    62
  • 云计算平台构建与实验设计

    课程设计任务书一、作业目的  物联网的核心是应用,应用的核心是云计算。通过构建一个云计算平台,并利用这个平台设计云计算实验,将结果与普通的电脑计算比较两者的差别,感受云计算的优越性能,从而对物联网有更深刻的体验与认识。二、作业内容及要求    能够按照课程设计任务书按照相应的要求完成整个云计算平台的搭建,要完成这个任务,就要对云计算平台的架构和原理有一定的认识,对物联网的应用层有深入的学习,通…

    2022年4月6日
    47

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号