当前位置: 首页 > news >正文

Linux内核 -- 汇编结合ko案例之PMU获取cpu cycle技术

ARMv7汇编实现周期计数读取与清空

本文档详细描述了如何在ARMv7平台上使用汇编语言编写周期计数器读取与清空函数,如何在内核模块中导出这些函数供其他模块调用,以及如何使用Netlink接口供用户态程序进行调用。

1. 汇编函数实现

首先,编写汇编函数以实现周期计数器的读取与清空。创建文件cpu_cycle.S

.global clear_cycle_counter
.global get_cycle_count
.global select_cycle_counter
.global cm_enable_pmu// 开启PMU功能
cm_enable_pmu:MRC p15, 0, r0, c9, c12, 0 // 读取 PMU_CTRL寄存器值到R0ORR r0, r0, #1MCR p15, 0, r0, c9, c12, 0 // 将R0的值写入PMU_CTRL寄存器值// 清空周期计数器
clear_cycle_counter:// 将0写入周期计数器寄存器MCR p15, 0, r0, c9, c13, 2MOV pc, lr// 获取周期计数
get_cycle_count:// 从周期计数器寄存器读取值MRC p15, 0, r0, c9, c13, 2MOV pc, lrselect_cycle_counter://选择周期计数器 如nt98528是0~5// 选择0号计数器MOV r0, #0MCR p15, 0, r0, c9, c12, 5MOV pc, lr

2. 内核模块实现

接下来,编写内核模块代码,以导出汇编函数并通过Netlink提供接口。创建文件cm_cpu_cycle.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <net/sock.h>#define NETLINK_USER 31// 声明汇编函数
extern void clear_cycle_counter(void);
extern unsigned int get_cycle_count(void);// 导出汇编函数
EXPORT_SYMBOL(clear_cycle_counter);
EXPORT_SYMBOL(get_cycle_count);static struct sock *nl_sk = NULL;static void nl_recv_msg(struct sk_buff *skb) {struct nlmsghdr *nlh;int pid;struct sk_buff *skb_out;int msg_size;char *msg = NULL;int res;nlh = (struct nlmsghdr*)skb->data;pid = nlh->nlmsg_pid; // 获取发送者的PIDif (strncmp((char*)nlmsg_data(nlh), "clear", 5) == 0) {clear_cycle_counter();msg = "Cycle counter cleared";} else if (strncmp((char*)nlmsg_data(nlh), "get", 3) == 0) {unsigned int cycle_count = get_cycle_count();msg_size = snprintf(NULL, 0, "Cycle count: %u", cycle_count);msg = kmalloc(msg_size + 1, GFP_KERNEL);snprintf(msg, msg_size + 1, "Cycle count: %u", cycle_count);} else {msg = "Invalid command";}msg_size = strlen(msg);skb_out = nlmsg_new(msg_size, 0);if (!skb_out) {pr_err("Failed to allocate new skb
");return;}nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0);NETLINK_CB(skb_out).dst_group = 0;strncpy(nlmsg_data(nlh), msg, msg_size);res = nlmsg_unicast(nl_sk, skb_out, pid);if (res < 0)pr_err("Error while sending back to user
");if (msg && strncmp(msg, "Cycle count: ", 13) == 0)kfree(msg);
}static int __init cm_cpu_cycle_init(void) {struct netlink_kernel_cfg cfg = {.input = nl_recv_msg,};nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);if (!nl_sk) {pr_err("Error creating socket.
");return -10;}pr_info("cm_cpu_cycle module loaded.
");return 0;
}static void __exit cm_cpu_cycle_exit(void) {netlink_kernel_release(nl_sk);pr_info("cm_cpu_cycle module unloaded.
");
}module_init(cm_cpu_cycle_init);
module_exit(cm_cpu_cycle_exit);MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cycle Count Management Module");
MODULE_AUTHOR("Your Name");

3. Makefile

创建Makefile以编译内核模块:

obj-m += cm_cpu_cycle.o
cm_cpu_cycle-objs := cm_cpu_cycle_main.o cpu_cycle.oall:make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesclean:make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

4. 用户态程序

编写用户态程序,通过Netlink接口与内核模块通信。创建文件user_program.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/netlink.h>#define NETLINK_USER 31struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
struct msghdr msg;void send_msg(const char *cmd) {nlh->nlmsg_len = NLMSG_SPACE(1024);nlh->nlmsg_pid = getpid();nlh->nlmsg_flags = 0;strcpy(NLMSG_DATA(nlh), cmd);iov.iov_base = (void *)nlh;iov.iov_len = nlh->nlmsg_len;msg.msg_name = (void *)&dest_addr;msg.msg_namelen = sizeof(dest_addr);msg.msg_iov = &iov;msg.msg_iovlen = 1;sendmsg(sock_fd, &msg, 0);recvmsg(sock_fd, &msg, 0);printf("Received message payload: %s
", (char *)NLMSG_DATA(nlh));
}int main() {sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);if (sock_fd < 0) {return -1;}memset(&src_addr, 0, sizeof(src_addr));src_addr.nl_family = AF_NETLINK;src_addr.nl_pid = getpid();bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr));memset(&dest_addr, 0, sizeof(dest_addr));dest_addr.nl_family = AF_NETLINK;dest_addr.nl_pid = 0;   // For Linux Kerneldest_addr.nl_groups = 0; // unicastnlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(1024));memset(nlh, 0, NLMSG_SPACE(1024));// 发送清空周期计数器命令send_msg("clear");// 发送获取周期计数器值命令send_msg("get");close(sock_fd);return 0;
}

5. 编译与加载模块

编译内核模块:

make

加载内核模块:

sudo insmod cm_cpu_cycle.ko

运行用户态程序:

gcc user_program.c -o user_program
./user_program

卸载内核模块:

sudo rmmod cm_cpu_cycle

通过以上步骤,可以实现一个在内核态使用汇编语言编写的周期计数读取与清空功能,并通过Netlink接口供用户态程序进行调用的完整示例。

相关文章:

Linux内核 -- 汇编结合ko案例之PMU获取cpu cycle技术

ARMv7汇编实现周期计数读取与清空 本文档详细描述了如何在ARMv7平台上使用汇编语言编写周期计数器读取与清空函数&#xff0c;如何在内核模块中导出这些函数供其他模块调用&#xff0c;以及如何使用Netlink接口供用户态程序进行调用。 1. 汇编函数实现 首先&#xff0c;编写…...

探索 Symfony 框架:工作原理、特点及技术选型

目录 1. 概述 2. Symfony 的工作原理 2.1 MVC 架构 2.2 前端控制器模式 2.3 路由机制 2.4 依赖注入容器 2.5 事件驱动架构 3. Symfony 的特点 3.1 高度可扩展性 3.2 强大的社区支持和生态系统 3.3 优秀的性能和可伸缩性 3.4 严格的代码规范和最佳实践 4. Symfony …...

从万里长城防御体系看软件安全体系建设@安全历史03

长城&#xff0c;是中华民族的一张重要名片&#xff0c;是中华民族坚韧不屈、自强不息的精神象征&#xff0c;被联合国教科文组织列入世界文化遗产名录。那么在古代&#xff0c;长城是如何以其复杂的防御体系&#xff0c;一次次抵御外族入侵&#xff0c;而这些防御体系又能给软…...

ISO 19110操作要求类中的/req/operation/formal-definition详细解释

/req/operation/formal-definition 要求: 每个要素操作实体必须具有一个形式定义&#xff08;formal definition&#xff09;&#xff0c;该定义应明确描述操作的行为和影响。 具体解释 定义 要素操作实体&#xff08;feature operation entity&#xff09;&#xff1a;这…...

豆包大语言模型API调用错误码一览表

本文介绍了您可能从 API 和官方 SDK 中看到的错误代码。 http code说明 400 原因&#xff1a;错误的请求&#xff0c;例如缺少必要参数&#xff0c;或者参数不符合规范等 解决方法&#xff1a;检查请求后重试 401 原因&#xff1a;认证错误&#xff0c;代表服务无法对请求进…...

AI辅助设计:如何通过机器学习革新创意工作流程

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法&#xff0c;大数据&#xff0c;深度学习 &#x1f492; 公众号…...

轻松解锁电脑强悍性能,4000MHz的玖合星舞 DDR4 内存很能打

轻松解锁电脑强悍性能&#xff0c;4000MHz的玖合星舞 DDR4 内存很能打 哈喽小伙伴们好&#xff0c;我是Stark-C~ 很多有经验的电脑玩家在自己DIY电脑选购内存条的时候&#xff0c;除了内存总容量&#xff0c;最看重的参数那就是频率了。内存频率和我们常说的CPU主频一样&…...

SpringBoot | 使用jwt令牌实现登录认证,使用Md5加密实现注册

对于登录认证中的令牌&#xff0c;其实就是一段字符串&#xff0c;那为什么要那么麻烦去用jwt令牌&#xff1f;其实对于登录这个业务&#xff0c;在平常我们实现这个功能时&#xff0c;可能大部分都是通过比对用户名和密码&#xff0c;只要正确&#xff0c;就登录成功&#xff…...

Springboot基于Redis的高性能分布式缓存数据库的实现与实例

一、引言 在现代的分布式系统和高并发应用中&#xff0c;缓存机制显得尤为重要。Redis作为一种开源&#xff08;BSD许可&#xff09;的内存键值存储&#xff0c;因其高性能、丰富的数据结构和多样化的应用场景&#xff0c;成为开发者们的首选。在这篇博客中&#xff0c;我们将…...

防止多次点击,vue的按钮上做简易的防抖节流处理

话不多说,上个视频,看看是不是你要的效果 防抖节流 1.创建一个directive.js // directive.js export default {install(Vue) {// 防重复点击(指令实现)Vue.directive(repeatClick, {inserted(el, binding) {el.addEventListener(click, () > {if (!el.disabled) {el.disabl…...

云计算【第一阶段(21)】Linux引导过程与服务控制

目录 一、linux操作系统引导过程 1.1、开机自检 1.2、MBR引导 1.3、GRUB菜单 1.4、加载 Linux 内核 1.5、init进程初始化 1.6、简述总结 1.7、初始化进程centos 6和7的区别 二、排除启动类故障 2.1、修复MBR扇区故障 2.1.1、 实验 2.2、修复grub引导故障 2.2.1、实…...

Google 发布最新开放大语言模型 Gemma 2,现已登陆 Hugging Face Hub

Google 发布了最新的开放大语言模型 Gemma 2&#xff0c;我们非常高兴与 Google 合作&#xff0c;确保其在 Hugging Face 生态系统中的最佳集成。你可以在 Hub 上找到 4 个开源模型 (2 个基础模型和 2 个微调模型) 。发布的功能和集成包括&#xff1a; Hub 上的模型https://hf.…...

智能分析赋能等保:大数据技术在安全审计记录中的应用

随着信息技术的飞速发展&#xff0c;大数据技术在各行各业中的应用愈发广泛&#xff0c;特别是在网络安全领域&#xff0c;大数据技术为安全审计记录提供了强有力的支撑。本文将深入探讨智能分析如何赋能等保&#xff08;等级保护&#xff09;&#xff0c;以及大数据技术在安全…...

Django中,update_or_create()

在Django中&#xff0c;可以使用update_or_create()方法来更新现有记录或创建新记录。该方法接受一个字典作为参数&#xff0c;用于指定要更新或创建的字段和对应的值。 update_or_create()方法的语法如下&#xff1a; 代码语言&#xff1a;python obj, created Model.obje…...

每日一学(1)

目录 1、ConCurrentHashMap为什么不允许key为null&#xff1f; 2、ThreadLocal会出现内存泄露吗&#xff1f; 3、AQS理解 4、lock 和 synchronized的区别 1、ConCurrentHashMap为什么不允许key为null&#xff1f; 底层 putVal方法 中 如果key || value为空 抛出…...

SpringMVC(1)——入门程序+流程分析

MVC都是哪三层&#xff1f;在Spring里面分别对应什么&#xff1f;SpringMVC的架构是什么&#xff1f; 我们使用Spring开发JavaWeb项目&#xff0c;一般都是BS架构&#xff0c;也就是Browser&#xff08;浏览器&#xff09;-Server&#xff08;服务器&#xff09;架构 这种架构…...

成绩发布背后:老师的无奈与痛点

在教育的广阔天地里&#xff0c;教师这一角色承载着无数的期望与责任。他们不仅是知识的传播者&#xff0c;更是学生心灵的引路人。而对于班主任老师来说&#xff0c;他们的角色更加多元&#xff0c;他们不仅是老师&#xff0c;还必须是“妈妈”。除了像其他老师一样备课、上课…...

MySQL 索引之外的相关查询优化总结

在这之前先说明几个概念&#xff1a; 1、驱动表和被驱动表&#xff1a;驱动表是主表&#xff0c;被驱动表是从表、非驱动表。驱动表和被驱动表并非根据 from 后面表名的先后顺序而确定&#xff0c;而是根据 explain 语句查询得到的顺序确定&#xff1b;展示在前面的是驱动表&am…...

EE trade:贵金属投资的优点及缺点

贵金属(如黄金、白银、铂金和钯金)一直以来都是重要的投资和避险工具。它们具有独特的物理和化学特性&#xff0c;广泛应用于各种行业&#xff0c;同时也被视为财富储备。在进行贵金属投资时&#xff0c;了解其优点和缺点对于做出明智的投资决策至关重要。 一、贵金属投资的优…...

python工作目录与文件目录

工作目录 文件目录&#xff1a;文件所在的目录 工作目录&#xff1a;执行python命令所在的目录 D:. | main.py | ---data | data.txt | ---model | | model.py | | train.py | | __init__.py | | | ---nlp | | | bert.py | …...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)

目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 ​编辑​编辑 UDP的特征 socke函数 bind函数 recvfrom函数&#xff08;接收函数&#xff09; sendto函数&#xff08;发送函数&#xff09; 五、网络编程之 UDP 用…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...