一、export_symbol概述
EXPORT_SYMBOL(symbol_name); EXPORT_SYMBOL_GPL(symbol_name);
在Linux內核中,驅動程序和內核的其他部分之間是通過叫做symbol(符號)的接口來通信的,一個symbol可以是一個函數、一個全局變量或其他對象等等。默認情況下,這些symbol只能在內核中使用,因此,它們不會被其他程序訪問。如果想要將symbol導出給外部模塊使用,可以使用EXPORT_SYMBOL和EXPORT_SYMBOL_GPL宏來實現。
EXPORT_SYMBOL和EXPORT_SYMBOL_GPL的區別在於,EXPORT_SYMBOL_GPL只導出給使用了GPL或可以互操作的許可證的模塊使用。由於這些許可證限制了使用這些符號的模塊的範圍,因此EXPORT_SYMBOL_GPL被認為比EXPORT_SYMBOL更加安全。
二、export_symbol的使用
在驅動程序中,通常的做法是使用EXPORT_SYMBOL或EXPORT_SYMBOL_GPL來導出一些公共的接口或者符號,以便其他的模塊或者驅動程序可以訪問這些接口。通常在頭文件中定義這些符號,並在C文件中實現這些符號的功能。下面是一個簡單示例:
kernel_module.h
#ifndef __KERNEL_MODULE_H__ #define __KERNEL_MODULE_H__ void hello_world(void); #endif /* __KERNEL_MODULE_H__ */
kernel_module.c
#include "kernel_module.h" void hello_world(void) { printk(KERN_ALERT "Hello world!\n"); } EXPORT_SYMBOL_GPL(hello_world);
在這個例子中,我們定義了一個簡單的hello_world函數,並將其導出給其他的模塊使用。我們使用了EXPORT_SYMBOL_GPL宏使這個函數只能被使用了GPL或可以互操作的許可證的模塊調用。
三、export_symbol的注意事項
在使用export_symbol時,需要注意以下幾點:
1.導出符號需要用於編譯到內核中的代碼
export_symbol只對編譯到內核中的符號起作用。如果將模塊編譯成為動態模塊,則導出符號的宏不起作用。
2.導出符號的名字是全局的
導出符號的名字是全局的,可能會與其他符號發生衝突。為了避免衝突,可以使用一些命名約定來避免這種情況,例如添加前綴或後綴到導出的符號名字中。
3.使用EXPORT_SYMBOL_GPL時需要遵循GPL或者可以互操作的許可證
使用EXPORT_SYMBOL_GPL時,必須使用GPL或者可以和GPL互操作的許可證。對於商業閉源產品來說,使用EXPORT_SYMBOL_GPL可能會使其不能使用內核中的一些功能,因為這些功能使用了GPL許可證。
四、小結
export_symbol是內核中用來導出符號的一種機制,可以將這些符號作為接口供其他模塊或者驅動程序調用。在使用export_symbol時需要注意導出符號的名字是全局的,使用EXPORT_SYMBOL_GPL時需要遵循GPL或者可以互操作的許可證。使用export_symbol時需要注意導出符號需要用於編譯到內核中的代碼。
原創文章,作者:SMYQ,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/147599.html