首页 > 解决方案 > per_cpu 变量的 kallsyms_lookup_name

问题描述

我正在尝试按名称检索变量的内核符号。该变量定义为 per_cpu。如何使用 kallsyms_lookup_name 来检索它?

标签: linuxlinux-kernellinux-device-driver

解决方案


对于简短的回答,您可以使用APIkallsyms_lookup_name仔细访问 per-cpu 变量。get_cpu_ptr

对于长篇大论,我们必须明白通过kallsyms_lookup_name破坏我们内核模块的 API 稳定性来访问 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它时,我们没有收到一个可以像通常发生的那样被取消引用的有效地址,而是一个伪装成指针的偏移量。假设&<var>偏移量的标准 per-cpu API 不起作用,但我们可以使用较低级别的 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_ptrAPI 来访问这个 per-cpu 变量:

struct tick_sched *tick_sched = get_cpu_ptr(PER_CPU_tick_cpu_sched);
/* Access tick_sched here */
put_cpu_ptr(tick_sched);

推荐阅读