自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux內(nèi)核如何訪問另外一個模塊的函數(shù)和變量

系統(tǒng) Linux
有粉絲問我Linux內(nèi)核如何訪問另外一個模塊的函數(shù)和變量,今天就這個問題給大家介紹一下內(nèi)核中兩個模塊,一個A,一個B,A模塊中有操作函數(shù),B模塊要調(diào)用A模塊的函數(shù)。

[[386922]]

一、問題整理

內(nèi)核中兩個模塊,一個A,一個B,A模塊中有操作函數(shù),B模塊要調(diào)用A模塊的函數(shù)。


二、分析

這是一個驅(qū)動工程師經(jīng)常遇到的一個問題,該問題其實是模塊符號導(dǎo)出問題,實現(xiàn)該功能比較簡單,借助EXPORT_SYMBOL()即可。

1. 什么是符號?

這里的符號主要指的是全局變量和函數(shù),靜態(tài)全局變量其實也可以被另外一個模塊訪問到。

2. 為什么要導(dǎo)出符號?

↓ Linux內(nèi)核采用的是以模塊化形式管理內(nèi)核代碼。內(nèi)核中的每個模塊相互之間是相互獨(dú)立的,也就是說A模塊的全局變量和函數(shù),B模塊是無法直接訪問的。

有些時候,我們寫一些模塊代碼的時候,發(fā)現(xiàn)部分函數(shù)功能別人已經(jīng)實現(xiàn)了,此時我們就想如果我們可以調(diào)用他們已經(jīng)實現(xiàn)好的函數(shù)接口就好了。那如何才能做到這點(diǎn)呢?

就靠符號導(dǎo)出了,也就是說你可以把你實現(xiàn)的函數(shù)接口和全局變量導(dǎo)出,以供其他模塊使用。

在Linux內(nèi)核的世界里,如果一個模塊已經(jīng)以靜態(tài)的方式編譯進(jìn)的內(nèi)核,那么它導(dǎo)出的符號就會出現(xiàn)在全局的內(nèi)核符號表中。

在Ubuntu 14.04系統(tǒng)中,Linux內(nèi)核的全局符號表存放在以下文件:

  1. /usr/src/linux-headers-3.2.0-29-generic-pae/Module.symvers 

如果打開這個文件,可以發(fā)現(xiàn)里面的內(nèi)容就是:

  1. Addr------->符號名------>模塊名------>導(dǎo)出符號的宏 

 

3. 如何導(dǎo)出符號?

Linux內(nèi)核給我們提供了兩個宏:

  1. EXPORT_SYMBOL(name); 
  2. EXPORT_SYMBOL_GPL(name); 

上面宏定義的任一個使得給定的符號在模塊外可用;GPL版本的宏定義只能使符號對GPL許可的模塊可用;符號必須在模塊文件的全局部分輸出,在任何函數(shù)之外,因為宏定義擴(kuò)展成一個特殊用途的并被期望是全局存取的變量的聲明。

4. 模塊編譯時,如何尋找使用的符號?

  • a.在本模塊中符號表中,尋找符號(函數(shù)或變量實現(xiàn))
  • b.在內(nèi)核全局符號表中尋找
  • c.在模塊目錄下的Module.symvers文件中尋找

5. 案例演示

模塊A導(dǎo)出全局變量global_var和函數(shù)show兩個符號供模塊B使用。

A模塊

  1. #include <linux/init.h> 
  2. #include <linux/module.h> 
  3. static int global_var = 100; 
  4. static void show(void) 
  5.  printk("show():  global_var =%d \n",global_var); 
  6. static int hello_init(void) 
  7.  printk("module b :global_var=%d\n",global_var); 
  8.  return 0; 
  9. static void hello_exit(void) 
  10.  printk("hello_exit \n"); 
  11.  return
  12. }EXPORT_SYMBOL(global_var); 
  13. EXPORT_SYMBOL(show); 
  14. MODULE_AUTHOR("yikoulinux"); 
  15. MODULE_LICENSE("GPL"); 
  16. module_init(hello_init); 
  17. module_exit(hello_exit);  

B模塊

  1. #include <linux/init.h> 
  2. #include <linux/module.h> 
  3.  
  4. extern int global_var; 
  5. extern  void show(void); 
  6. static int hello_init(void) 
  7.  printk("module a: global_var= %d\n",global_var); 
  8.  show(); 
  9.  return 0; 
  10. static void hello_exit(void) 
  11.  printk("hello_exit \n"); 
  12.  return
  13. MODULE_AUTHOR("yikoulinux"); 
  14. MODULE_LICENSE("GPL"); 
  15. module_init(hello_init); 
  16. module_exit(hello_exit); 

調(diào)試步驟:

1.編譯模塊A,然后加載模塊A,在模塊A編譯好后,在它的當(dāng)前目錄會看到一個Module.symvers文件,這里存放的就是我們模塊A導(dǎo)出的符號。

2.將模塊A編譯生成的Module.symvers文件拷貝到模塊B目錄下,然后編譯模塊B,加載模塊B。

3.通過dmesg查看模塊打印的信息。打印信息如下:


由結(jié)果可知,我們在B模塊中訪問到了模塊A的全局變量global_var以及函數(shù)show。

 

責(zé)任編輯:姜華 來源: 一口Linux
相關(guān)推薦

2021-07-06 14:36:05

RustLinux內(nèi)核模塊

2014-07-24 14:35:26

Linux內(nèi)核模塊

2018-10-15 10:10:41

Linux內(nèi)核補(bǔ)丁

2009-09-11 08:44:36

2011-08-29 15:12:24

UbuntuLinux模塊

2020-11-10 07:11:23

Linux內(nèi)核補(bǔ)丁

2022-10-10 17:00:19

地址內(nèi)核函數(shù)

2018-12-06 08:34:15

Linux訪問控制安全攔截技術(shù)

2021-05-26 07:53:58

Linux運(yùn)維Linux系統(tǒng)

2021-05-18 14:25:30

Linux運(yùn)維Linux系統(tǒng)

2018-06-19 09:07:57

Linux內(nèi)核模塊

2019-02-11 14:35:59

Linux硬件監(jiān)控工具命令

2023-07-25 15:17:38

Linux操作系統(tǒng)開發(fā)

2009-08-18 11:01:51

2013-08-01 10:58:53

2023-02-27 12:53:14

Linux內(nèi)核

2021-02-20 11:34:43

Linux內(nèi)核指針

2010-01-22 11:01:04

linux內(nèi)核模塊

2023-09-28 13:21:32

2023-05-08 08:05:42

內(nèi)核模塊Linux
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號