/proc/kallsyms 中标有 "T" 的内核符号未导出
kernel symbol marked with "T" in /proc/kallsyms is not exported
符号machine_power_off
在/proc/kallsyms
中用"T"标记:
$ grep -w machine_power_off /proc/kallsyms
ffffffff8102391b T machine_power_off
但它是not exported。 kallsyms 中的 "T" 是否足以导出符号?导出是否足以在其他模块中使用?
我使用它的模块编译时出现警告:
WARNING: "machine_power_off" [/path/to/module.ko] undefined!
在主机 (3.2.0-4-amd64) 上我可以加载此模块,但在 VirtualBox (3.16.0-4-amd64) 上它会产生以下消息:
insmod: ERROR: could not insert module module.ko: Unknown symbol in module
为什么这个模块加载到我的主机系统中,而不是在 VirtualBox 中?
在/proc/kallsyms
中标记"T"意味着该符号是全局可见的,并且可以在其他内核的代码中使用(例如通过驱动程序,编译内置).
但是为了在 内核模块的代码 中可用,需要使用 EXPORT_SYMBOL
或类似的方式导出符号。导出符号列表与内核中所有符号列表分开维护。
可以在文件 /lib/modules/<kernel-version>/build/Module.symvers
.
中找到导出的符号
(此文件应该存在,以便针对给定内核构建内核模块)。
要使用全局但未导出的内核符号(例如您提到的 machine_power_off
符号),您可以在模块代码中使用 kallsyms_lookup
:
#include <linux/kallsyms.h>
static void (*machine_power_off_p)(void);
machine_power_off_p = (void*) kallsyms_lookup_name("machine_power_off");
现在您可以通过machine_power_off_p
指针调用machine_power_off
函数:
(*machine_power_off_p)();
符号machine_power_off
在/proc/kallsyms
中用"T"标记:
$ grep -w machine_power_off /proc/kallsyms
ffffffff8102391b T machine_power_off
但它是not exported。 kallsyms 中的 "T" 是否足以导出符号?导出是否足以在其他模块中使用?
我使用它的模块编译时出现警告:
WARNING: "machine_power_off" [/path/to/module.ko] undefined!
在主机 (3.2.0-4-amd64) 上我可以加载此模块,但在 VirtualBox (3.16.0-4-amd64) 上它会产生以下消息:
insmod: ERROR: could not insert module module.ko: Unknown symbol in module
为什么这个模块加载到我的主机系统中,而不是在 VirtualBox 中?
在/proc/kallsyms
中标记"T"意味着该符号是全局可见的,并且可以在其他内核的代码中使用(例如通过驱动程序,编译内置).
但是为了在 内核模块的代码 中可用,需要使用 EXPORT_SYMBOL
或类似的方式导出符号。导出符号列表与内核中所有符号列表分开维护。
可以在文件 /lib/modules/<kernel-version>/build/Module.symvers
.
(此文件应该存在,以便针对给定内核构建内核模块)。
要使用全局但未导出的内核符号(例如您提到的 machine_power_off
符号),您可以在模块代码中使用 kallsyms_lookup
:
#include <linux/kallsyms.h>
static void (*machine_power_off_p)(void);
machine_power_off_p = (void*) kallsyms_lookup_name("machine_power_off");
现在您可以通过machine_power_off_p
指针调用machine_power_off
函数:
(*machine_power_off_p)();