我试图通过名字来检索一个变量的内核符号,这个变量被定义为per_cpu。这个变量被定义为per_cpu,如何使用kallsyms_lookup_name来检索它?我如何使用 kallsyms_lookup_name 来检索它?
简而言之,你可以使用以下方法来访问 per-cpu 变量 kallsyms_lookup_name
仔细随 get_cpu_ptr
API。
对于长篇大论的答案,我们要明白,通过访问API的 kallsyms_lookup_name
颠覆了我们内核模块的API稳定性。在未来的内核中,它很可能会被破坏,而且不能保证未来的内核甚至会拥有 kallsyms_lookup_name
函数的访问。
现在,关于如何做到这一点 -
假设我们在头文件中声明了以下的per-cpu变量。
DECLARE_PER_CPU(struct tick_sched, tick_cpu_sched);
内核对per-cpu的实现对以下地址有不同的含义。tick_cpu_sched
即 &tick_cpu_sched
. 它是per-cpu部分内部的偏移量,而不是绝对地址。当我们调用 kallsym_lookup_name
上,我们并没有像通常情况下那样收到一个可以被重新引用的有效地址,而是收到一个伪装成指针的偏移量。标准的每处理器API假设 &<var>
是偏移量不能用,但我们可以用一个低级的API。get_cpu_ptr
.
所以我们用 kallsyms_lookup_name
在我们的内核模块的init函数中。
struct tick_sched *PER_CPU_tick_cpu_sched =
(struct tick_sched *)kallsyms_lookup_name("tick_cpu_sched");
我把它命名为 PER_CPU_tick_cpu_sched
来提醒自己不要直接访问它。
现在我们可以使用 get_cpu_ptr
API来访问这个每个cpu变量。
struct tick_sched *tick_sched = get_cpu_ptr(PER_CPU_tick_cpu_sched);
/* Access tick_sched here */
put_cpu_ptr(tick_sched);