1. 程式人生 > >Linux核心模組間函式呼叫正確方法

Linux核心模組間函式呼叫正確方法

模組之間發生呼叫關係是常有的事情,下面以兩個模組A、B,B使用A模組提供的函式為例,講解正確使用的方法。
模組A中使用EXPORT_SYMBOL或EXPORT_SYMBOL_GPL將要提供給B模組的函式匯出;
模組B中用extern 宣告需要用到的A模組提供的函式。
程式碼如下:

模組A的程式碼 – A_func.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/jiffies.h>

// Print jiffies
void A_print_jiffies(void) { printk("jiffies is : %llu\n", (u64)jiffies); return; } EXPORT_SYMBOL(A_print_jiffies); static int __init A_init(void) { printk("A_func module init!\n"); return 0; } static void __exit A_exit(void) { printk("A_func module exit!\n"
); return; } module_init(A_init); module_exit(A_exit); MODULE_AUTHOR("[email protected]"); MODULE_DESCRIPTION("Module A"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); 1 模組B的程式碼 – B_func.c #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/jiffies.h>
extern void A_print_jiffies(void); static int __init B_init(void) { printk("B_func module init!\n"); A_print_jiffies(); return 0; } static void __exit B_exit(void) { printk("B_func module exit!\n"); return; } module_init(B_init); module_exit(B_exit); MODULE_AUTHOR("[email protected]"); MODULE_DESCRIPTION("Module B!"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); 1 模組A的Makefile obj-m := A_func.o KERNELDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: rm -f *.o *.ko *.mod.c *.order *.symvers 1 模組B的Makefile obj-m := B_func.o KERNELDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: rm -f *.o *.ko *.mod.c *.order *.symvers

1
接下來,有3種方式使得模組B編譯及載入不出現Warning或Failed.
方法一:
A模組在make之後,會產生一個Module.symvers檔案,將該檔案拷貝到B模組原始檔目錄中,然後執行make
方法二:
修改B模組的Makefile檔案:
新增

KBUILD_EXTRA_SYMBOLS += /path_to_module_A/Module.symvers
export KBUILD_EXTRA_SYMBOLS
obj-m := xhz2_func.o
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

KBUILD_EXTRA_SYMBOLS += /home/xhz/Project/Temp_Module/Module.symvers
export KBUILD_EXTRA_SYMBOLS

default:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
        rm -f *.o *.ko *.mod.c *.order *.symvers
1

方法三:
修改Linux核心原始碼樹中的Module.symers檔案,將A模組編譯產生的Module.symvers的內容新增在此檔案中。(注意將空格替換為Tab,否則編譯B時會報錯)。
個人推薦使用第二種方法,相比方法一省去拷貝檔案的步驟。相比方法三,無須修改Linux核心原始碼樹中的Module.symvers.

相關推薦

Linux核心模組函式呼叫正確方法

模組之間發生呼叫關係是常有的事情,下面以兩個模組A、B,B使用A模組提供的函式為例,講解正確使用的方法。 模組A中使用EXPORT_SYMBOL或EXPORT_SYMBOL_GPL將要提供給B模組的函式匯出; 模組B中用extern 宣告需要用到的A模組

Linux核心模組新增的兩種方法

 Linux核心模組新增的兩種方法 靜態載入: 把元件都新增進核心檔案中,在目錄kongfig檔案中增加新程式碼對應的編譯選項,在Makefile檔案中新增編譯條目。 動態載入:

linux核心模組通訊辦法

這裡僅僅涉及到共享全域性變數。 方法1: 核心中新增標頭檔案宣告 核心中本身就存在全域性變數, 比如jiffies。 類似的在核心的模組中include/linux/xxx.h新建這個標頭檔案

linux核心模組替換系統呼叫

安裝核心模組,使自己的程式碼進入核心空間執行,可以替換linux原有的系統呼叫。 更改mkdir的系統呼叫的核心模組程式碼如下:(ubuntu1510 X86_64) #include <linux/module.h> #include <linux/k

linux核心模組之間共享函式或者全域性變數

1、 在被呼叫函式中定義函式或者全域性量       unsigned char g_data = 0;       int set_g_data(unsigned char num)       {                    ..........       

linux kernel中列印函式呼叫的堆疊的方法

在linux核心除錯中,經常用到的列印函式呼叫堆疊的方法非常簡單,只需在需要檢視堆疊的函式中加入: dump_stack();或 __backtrace();即可。 dump_stack()在~/kernel/ lib/Dump_stack.c中定義 void

Linux進程的通信方法簡介

進程通信 linux 一、本地進程間的通信方式: 1.管道(pipe) 利用管道文件可以進行進程間數據的通信,通常是具有血緣關系的父子進程間的通信方式。 管道通信為半雙工模式,父子進程可以通過調用內核中的read()和write()命令來向管道文件進行讀寫操作。

LINUX核心模組載入Windows下驅動

最近一段時間以來,幾乎每一臺行動式計算機都內建了無線功能,但是它們中有很多並不支援Linux。因此,除非這些計算機設定了雙啟動,這樣做LINUX使用者也未必可以使用無線網絡卡,儘管如此,除非Windows正在執行,否則這些便攜計算機可能依然無法連線到無線網路。   最近一段時間以來,幾乎每一臺行

Linux核心模組程式設計

Linux核心模組程式設計 (作者:Baron_wu 禁止轉載) 首先,建立一個核心模組並插入Linux核心中。這是實驗第一部分 首先檢視當前核心模組使用情概況:lsmod Module:模組名 Size:模組大小 Used by:這些模組在哪被使用 接下來編寫一個simple.c

linux 核心模組程式設計之LED驅動程式(六)

我使用的是tiny6410的核心板,板子如下,淘寶可以買到 為了不與板子上的任何驅動發生IO衝突,我使用CON1那一排沒用到的IO口,引腳如下   LED1 LED2 LED3 LED4

linux 核心模組程式設計之核心符號匯出(五)

/proc/kallsyms 記錄了核心中所有匯出的符號的名字與地址 我們需要編譯2個核心模組,然後其中一個核心模組去呼叫另一個核心模組中的函式 hello.c程式碼如下 #include <linux/module.h> #include <linux/in

linux 核心模組程式設計之模組引數(四)

通過巨集module_param指定模組引數,模組引數用於在載入模組時傳遞給模組。 module_param(name, type, perm) name是模組引數的名字 type是這個引數的型別,常見值:bool、int、charp(字串型) perm是模組

linux 核心模組程式設計之編譯多個原始檔(三)

編譯擁有多個原始檔的核心模組的方式和編譯一個原始檔的方式差不多,我們先來看下我們需要的檔案都有哪些。 首先是main.c檔案 #include <linux/module.h> #include <linux/init.h> MODULE_LICENSE

linux 核心模組程式設計之hello word(二)

我們的目的是要編譯個hello.ko的檔案,然後安裝到核心中。 先來看下需要的程式碼,hello.c檔案如下 #include <linux/module.h> #include <linux/init.h> static int hello_init(vo

linux 核心模組程式設計之環境搭建(一)

這裡介紹些關於Tiny6410開發板核心的編譯,為後期驅動開發做前期的準備。 開發環境:64位的Ubuntu 14.01虛擬機器 目標機:友善之臂Tiny6410開發板 核心:linux-2.6.38-20110325.tar.gz 核心原始碼下載地址 htt

JS不同檔案函式呼叫

假設條件是:JS(A)要呼叫JS(B)的函式.那麼要滿足以下條件: 1.要保證你所呼叫的JS必須在同一個頁面裡. 也就是JS(A)和JS(B)都要在頁面X裡. 2.要保證你所呼叫的JS先於呼叫者本身被解釋.也就是JS(B)要先於JS(A)被解釋.反映在頁面上,就是JS(B)要寫到JS(A)的前面.

Linux核心模組程式設計——Hello World

一、實驗環境: 環境配置:VMware® Workstation 15 Pro、ubuntu Desktop 18.10、記憶體 2GB、處理器數量2、每個處理器核心數量1、硬碟大小30GB……還有一個就是用的咱Xidian的源(因為校內不需要流量啊,而且還很快!) 二、知識儲備

Linux核心模組程式設計系列1

1.準備工作 使用如下命令檢視自己Linux的核心版本 uname -a 結果如下: Linux VM-73-203-debian 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1+deb9u1 (2018-05-07) x86_64 GNU/Lin

函式呼叫函式,父函式呼叫方法,子函式重寫了,那麼最後父函式呼叫的是自己的方法,還是子函式方法

Q:子類呼叫父類的方法,父類中某個方法所呼叫的方法,子類也重寫了,那麼最後父類中的方法呼叫的是自己的方法,還是子類的方法。 A:呼叫的是子類的方法。     看程式碼: public class Parent { public void used

Linux核心模組開發 Slab快取記憶體介面與用例

在核心模組開發或者驅動開發中經常會使用到記憶體分配,常見的方式是呼叫 kmalloc 介面分配記憶體。 static __always_inline void *kmalloc(size_t size, gfp_t flags); kmalloc介面使用簡單,並且不會對所