Linux內核模塊-導出符號表(五)

一、簡介
  •   如果一個模塊需要向其他模塊導出符號(方法或全局變量),需要使用:
         EXPORT_SYMBOL(name);
         EXPORT_SYMBOL_GPL(name);
 注意:符號必須在模塊文件的全局部分導出,不能再函數部分導出。
            更多信息可參考 <linux/module.h>文件             
  •  顯示所有導出的符號
          [root@localhost test]# cat /proc/kallsyms

  • 應用步驟
  1. 在模塊函數定義之後使用EXPORT_SYMBOL(function_name);
  2. 在調用該函數的模塊中使用extern對之聲明;
  3. 首先加載定義該函數的模塊,在家在調用該函數的模塊。
二、應用實例
  1. 代碼
  • hello-3.c
    /*
    * hello-3.c - Illustration the difference
    * between EXPORT_SYMBOL and EXPORT_SYMBOL_GPL
    * Include hello-3.c hello-4.c
    */
    
    # include <linux/kernel.h> /* Wd're doing kernel work */
    # include <linux/module.h> /* specifically, a module */
     # include <linux/init.h>   /* Need for the macros */
    
    void function1(void)
    {
         printk(KERN_INFO "Hello world 3\n");
    }
    EXPORT_SYMBOL(function1);
    
    void function2(void)
    {
         printk(KERN_INFO "Hello world 3 again\n");
    }
    EXPORT_SYMBOL_GPL(function2);
    
    static int __init hello_3_init(void)
    {
          return 0;
    }
    
      static void __exit hello_3_exit(void)
    {
           printk(KERN_INFO "Bye\n");
    }
    
    module_init(hello_3_init);
    module_exit(hello_3_exit);
    
    MODULE_LICENSE("GPL");
    


  • hello-4.c
    /*
    * hello-4.c - Illustration the difference
    * between EXPORT_SYMBOL and EXPORT_SYMBOL_GPL
    * Include hello-3.c hello-4.c
    */
    # include <linux/kernel.h> /* Wd're doing kernel work */
    # include <linux/module.h> /* specifically, a module */
     # include <linux/init.h>   /* Need for the macros */
    
    extern int function1(void);
    extern int function2(void);
    
    static int __init hello_4_init(void)
    {
         function1();
      // function2();
          return 0;
    }
    
      static void __exit hello_4_exit(void)
    {
           printk(KERN_INFO "Goodbye\n");
    }
    
    module_init(hello_4_init);
    module_exit(hello_4_exit);
    
    //MODULE_LICENSE("GPL");

  • Makefile文件
 obj-m += hello-3.o
   obj-m += hello-4.o

   PWD := $(shell pwd)

   KVER := $(shell uname -r)

   KDIR := /lib/modules/$(KVER)/build

all:
         make -C $(KDIR) M=$(PWD) modules

clean:
        make -C $(KDIR) M=$(PWD) clean

注意:all和clean下面,命令行前的空隙是按“Tab鍵”。
      
         2.操作步驟
[root@localhost test]# make
[root@localhost test]# insmod hello-3.ko
[root@localhost test]# insmod hello-4.ko
[root@localhost test]# rmmod hello-4.ko
[root@localhost test]# rmmod hello-3.ko
[root@localhost test]# dmesg | tail -10
。。。。。
Hello world 3
Hello world 3 again
Goodbye
Bye
        3.可能異常
a.裝載順序,先insmod hello-4.ko,然後insmod hello-3.ko,會有以下出錯信息:
[root@localhost test]# insmod hello-4.ko
insmod: error inserting 'hello-4.ko': -1 Unknown symbol in module
注意:裝載順序,必須先是聲明函數的模塊,然後裝載調用函數的模塊。
           這樣才能獲取導出符號(對應內存地址),找到函數地址。
b.在hello-4.c中註釋掉MODULE_LISENCE("GPL"),裝載hello-4.ko時,會有以下出錯信息:
insmod: error inserting 'hello-4.ko': -1 Unknown symbol in module
注意:這就是  EXPORT_SYMBOL與 EXPORT_SYMBOL_GPL用法的區別。
c.卸載時,先rmmod hello-3.ko,然後rmmod hello-4.ko,會有如下出錯信息:
[root@localhost test]# rmmod hello-3.ko
ERROR: Module hello_3 is in use by hello_4
注意:函數被調用時不能卸載,應先卸載調用函數的模塊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章