今天我来给大家伙儿唠唠,我在捣鼓内核模块的时候,遇到的一个挺有意思的玩意儿——EXPORT_SYMBOL
。这东西,说白,就是用来把你写的函数“广而告之”的,让别的模块也能使唤你写的这个函数。
我也不清楚这是个就记得在代码里看到过好几次 EXPORT_SYMBOL
,后面跟着一个函数名。当时我就纳闷,这是干啥用的?后来我一查资料,好家伙,原来这东西还挺关键。
你想,咱写内核模块,有时候写的一些函数,不仅仅是给自己用的,还想让别的模块也用一用。这时候,就得靠 EXPORT_SYMBOL
。它就像一个“广播员”,把你写的函数名和地址,告诉给内核,这样别的模块想用的时候,就能找得到。
具体咋操作?也不难。我来给你们捋一捋我当时是怎么弄的:
- 1,你得有个函数,想让别人也能用的,比如我写个函数叫
my_awesome_function
。 - 然后,在你的模块代码里,找到合适的地方,一般是模块的面,加上一行
EXPORT_SYMBOL(my_awesome_function);
这样,就把my_awesome_function
这个函数给“广播”出去。 - 接着,我重新编译内核模块,然后加载它。
- 3,我去
/proc/kallsyms
这个文件里瞅一眼,果然能看到my_awesome_function
的信息,说明它已经被成功“广播”出去。
打个比方,就像村里有个广播站,你写个函数,就是写首好歌,你想让全村人都听到,就得把歌名和你在哪儿唱歌,告诉给广播站。EXPORT_SYMBOL
就相当于广播站,它把你的歌名和地址,也就是函数名和函数地址,记录下来,广播给整个村子,也就是内核。这样,别的模块,也就是村里的其他人,想听你的歌,就知道去哪儿找你。
咱也不能啥函数都往外“广播”,有些函数只是模块内部用的,就没必要公开。EXPORT_SYMBOL
主要还是用在那些需要被其他模块调用的函数上。
我还发现,这玩意儿在 2.6 内核里才开始用的,2.4 内核里,默认情况下,非 static 的函数和变量都会自动导入到内核空间,都不用 EXPORT_SYMBOL
标记的。现在的新内核,都得用它来明确指定要导出的函数。
对,如果你的模块里有两个函数,比如 func1
和 func2
,func2
想调用 func1
,那你就得在 func1
所在的模块里,用 EXPORT_SYMBOL(func1);
把它“广播”出去,然后在 func2
所在的模块里,用 extern int func1();
声明一下,这样 func2
就能用 func1
。
EXPORT_SYMBOL
这个东西,对于写内核模块来说,还是挺重要的。它能让你的代码更好地被复用,也能让不同的模块之间更好地协作。我这回算是彻底搞明白,以后再写内核模块,就知道该怎么用它。