You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Linux内核驱动中使用ARM全局计时器读取计数值?

读取ARM全局计时器计数值的实现方法

你提到的_gt_counter_read()和gt_counter_read()都是静态函数,仅在arm_global_timer.c文件内部可见,且未通过EXPORT_SYMBOL系列宏导出,内核模块无法直接调用这类私有函数。正确的做法是通过Linux内核的clocksource框架来访问全局计时器的读取接口,具体实现如下:

核心思路

ARM全局计时器驱动会向内核注册一个clocksource结构体实例,其中的read成员函数就是封装了底层计数值读取逻辑的官方接口。我们只需要找到这个实例,就能调用它的read方法获取计数值。

具体代码实现

#include <linux/clocksource.h>
#include <linux/module.h>
#include <linux/init.h>

static struct clocksource *arm_gt_cs;

static int __init arm_gt_read_init(void)
{
    struct clocksource *cs;

    // 遍历系统中所有注册的clocksource,匹配ARM全局计时器
    list_for_each_entry(cs, &clocksource_list, list) {
        if (!strcmp(cs->name, "arm_global_timer")) {
            arm_gt_cs = cs;
            break;
        }
    }

    if (!arm_gt_cs) {
        pr_err("Failed to locate ARM global timer clocksource\n");
        return -ENODEV;
    }

    // 读取并打印计数值
    u64 counter = arm_gt_cs->read(arm_gt_cs);
    pr_info("ARM global timer counter: %llu\n", counter);

    return 0;
}

static void __exit arm_gt_read_exit(void)
{
    arm_gt_cs = NULL;
}

module_init(arm_gt_read_init);
module_exit(arm_gt_read_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ARM Global Timer Counter Reader");
MODULE_AUTHOR("Your Name");

关键细节说明

  • clocksource_list是内核维护的全局链表,存储了所有已注册的clocksource实例,遍历它即可找到目标计时器。
  • 对于ARM全局计时器来说,clocksource的read方法内部就是调用了你提到的gt_counter_read()函数,效果完全等价于直接调用私有静态函数。
  • 在4.19版本内核中,clocksource_list是全局可见的,可以直接遍历;若后续内核版本对其访问做了限制,可能需要调整,但你的目标版本无需担心。

编译与加载注意事项

  • 编译模块时需使用对应4.19内核的头文件和配置参数。
  • 加载模块需要root权限,且系统内核已开启CONFIG_ARM_GLOBAL_TIMER配置(即ARM全局计时器驱动已启用)。

内容的提问来源于stack exchange,提问作者dczanella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 17:54:25