zoukankan      html  css  js  c++  java
  • linux 内核中EXPORT_SYMBOL()分析与实践

    linux 内核中EXPORT_SYMBOL()分析与实践

    linux内核版本 时间 备注
    4.1.15 2021/11/1 技术总结

    一、EXPORT_SYMBOL()分析

    ​ EXPORT_SYMBOL实际是一个宏函数。用于将函数或者符号向全部内核代码公开,不用修改内核代码就可以在内核模块中直接调用(注意是在内核模块中),即:使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用。

    ​ 定义如下://出自 linux dir/include/linux/export.h文件

    #define __EXPORT_SYMBOL(sym, sec)				
    	extern typeof(sym) sym;					
    	__CRC_SYMBOL(sym, sec)					
    	static const char __kstrtab_##sym[]			
    	__attribute__((section("__ksymtab_strings"), aligned(1))) 
    	= VMLINUX_SYMBOL_STR(sym);				
    	extern const struct kernel_symbol __ksymtab_##sym;	
    	__visible const struct kernel_symbol __ksymtab_##sym	
    	__used							
    	__attribute__((section("___ksymtab" sec "+" #sym), unused))	
    	= { (unsigned long)&sym, __kstrtab_##sym }
    
    #define EXPORT_SYMBOL(sym)					
    	__EXPORT_SYMBOL(sym, "")
    

    这里以EXPORT_SYMBOL(system_state)为例,经过宏替换后结果如下:

    extern typeof (system_state) system_state;
    extern __visible void *__crc_system_state  __attribute__ ((weak));
    static const unsigned long  __kcrctab_system_state __used  __attribute__ ((section("___kcrctab" sec "+" #sym), unused))   =  (unsigned long) &__crc_system_state;
    
    static const char __kstrtab_system_state[] __attribute__((section("__ksymtab_strings"), aligned(1))) = "system_state";
    
    extern const struct kernel_symbol  __ksymtab_system_state;
        
    __visible const struct kernel_symbol   __ksymtab_system_state  __used  __attribute__ ((section("___ksymtab" sec "+" #sym), unused)) = {(unsigned long)&system_state,__kstrtab_system_state};
        
    

    以上代码实则是:对于每个使用EXPORT_SYMBOL()导出的符号,都将在ksymtab节中放置一个与之关联的结构体。

    二、实践过程记录

    创建一个module_first模块和module_second模块,再创建一个makefile文件。

    //module_first.c
    #include <linux/types.h>
    #include <linux/kernel.h>
    #include <linux/delay.h>
    #include <linux/ide.h>
    #include <linux/init.h>
    #include <linux/module.h>
    
    static int module_first_function(void)
    {
        printk("this is module_first_function
    ");
    
        return 0;
    }
    EXPORT_SYMBOL(module_first_function);  /*导出module_first_function函数供module_second模块使用 */ 
    
    static  int __init module_first_init(void)
    {
        printk("module_first_init
    ");
    
        return 0;
    } 
    
    static int __exit module_first_exit(void)
    {
        printk("module_first_exit
    ");
    
        return 0;
    }
    
    // 指定驱动的入口函数和出口函数
    module_init(module_first_init);
    module_exit(module_first_exit);
    MODULE_AUTHOR("iriczhao");
    MODULE_LICENSE("GPL");
    
    //module_second.c
    
    #include <linux/types.h>
    #include <linux/kernel.h>
    #include <linux/delay.h>
    #include <linux/ide.h>
    #include <linux/init.h>
    #include <linux/module.h>
    
    extern int module_first_function(void);
    
    static int module_second_function(void)
    {
        /* 此处调用module_first模块中module_first_function函数 */
        module_first_function();
    
        printk("============================
    ");
        printk("this is module_second_function
    ");
        printk("============================
    ");
        
        return 0;
    }
    
    static  int __init module_second_init(void)
    {
        printk("module_second_init
    ");
        module_second_function();
        return 0;
    } 
    
    static int __exit module_second_exit(void)
    {
        printk("module_second_exit
    ");
        return 0;
    }
    
    // 指定驱动的入口函数和出口函数
    module_init(module_second_init);
    module_exit(module_second_exit);
    MODULE_AUTHOR("iriczhao");
    MODULE_LICENSE("GPL");
    

    makefile 文件

    KERNELDIR := /home/iriczhao/linux/linux-imx-rel_imx_4.1.15_2.1.0_ga
    
    CURRENT_PATH := $(shell pwd)
    
    obj-m := module_first.o module_second.o
    
    build: kernel_modules
    
    kernel_modules:
    	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
    
    clean:
    	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
    
    

    编译构建后,将生成的module_first.ko和module_second.ko两个模块文件拷贝到运行环境根文件系统中。加载模块,运行结果如下:

    可见,根据上图红框中内容显示,在module_second模块中成功调用了module_first模块中使用EXPORT_SYMBOL声明的module_first_function函数。
    image


    本文完!!!

  • 相关阅读:
    day01--计算机硬件基础笔记
    22 Jun 18 Django,ORM
    21 Jun 18 Django,ORM
    20 Jun 18 复习, mysql
    20 Jun 18 Django,ORM
    19 Jun 18 复习, 正则表达式
    19 Jun 18 Django
    15 Jun 18 复习, shutil模块
    15 Jun 18 Django
    14 Jun 18 复习, form表单
  • 原文地址:https://www.cnblogs.com/iriczhao/p/15493106.html
Copyright © 2011-2022 走看看