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

arm64平台下linux访问寄存器

通用寄存器

示例:读取寄存器值

// 用户态程序或内核代码中均可使用
unsigned long reg_value;
asm volatile (
    "mov %0, x10"   // 将X10的值保存到reg_value变量
    : "=r" (reg_value)
);
printk("X10 = 0x%lx\n", reg_value);

示例:写入寄存器值

unsigned long new_value = 0x1234;
asm volatile (
    "mov x9, %0"    // 将new_value的值写入X9
    : 
    : "r" (new_value)
);

内核模块中直接访问 

// 内核模块示例
void read_registers(void) {
    unsigned long sp, pc;
    asm volatile (
        "mov %0, sp \n"   // 读取SP(栈指针)
        "mov %1, pc \n"   // 读取PC(程序计数器)
        : "=r" (sp), "=r" (pc)
    );
    pr_info("SP=0x%lx, PC=0x%lx\n", sp, pc);
}

系统寄存器

需要通过msr写、mrs读取:

linux内核定义了read_sysreg/write_sysreg相关的函数:arch/arm64/include/asm/sysreg.h

以读取寄存器为例 :read_sysreg和read_sysreg_s的区别是一个检测权限?(来自deepseek答案),实际操作read_sysreg接受字符串类型寄存器写法,如elr_el1,vbar_el1等(这些忽略大小写,本质上也是as汇编命令,属于binutils软件,中内置的)。./opcodes/aarch64-opc.c:

而read_sysreg_s只能接受SYS_ELR_EL1,SYS_VBAR_EL1这种内核定义的寄存器编码:

sys_reg: 

/*
 * ARMv8 ARM reserves the following encoding for system registers:
 * (Ref: ARMv8 ARM, Section: "System instruction class encoding overview",
 *  C5.2, version:ARM DDI 0487A.f)
 *	[20-19] : Op0
 *	[18-16] : Op1
 *	[15-12] : CRn
 *	[11-8]  : CRm
 *	[7-5]   : Op2
 */
#define Op0_shift	19
#define Op0_mask	0x3
#define Op1_shift	16
#define Op1_mask	0x7
#define CRn_shift	12
#define CRn_mask	0xf
#define CRm_shift	8
#define CRm_mask	0xf
#define Op2_shift	5
#define Op2_mask	0x7

#define sys_reg(op0, op1, crn, crm, op2) \
	(((op0) << Op0_shift) | ((op1) << Op1_shift) | \
	 ((crn) << CRn_shift) | ((crm) << CRm_shift) | \
	 ((op2) << Op2_shift))

 和寄存器的定义有说明:http://hehezhou.cn/register2025/AArch64-elr_el1.html

 案例:

uint64_t read_ttbr0_el1(void) {
    uint64_t ttbr0;
    asm volatile("mrs %0, ttbr0_el1" : "=r" (ttbr0));
    return ttbr0;
}
static int __init test_init(void)
{

        printk("ttbr0_el1 %llx\n",read_ttbr0_el1());
        printk("ttbr0_el1 %llx\n",read_sysreg_s(SYS_TTBR0_EL1));
        printk("elr_el1 %llx\n",read_sysreg(elr_el1));
        printk("midr_el1 %llx\n",read_sysreg(midr_el1));
        printk("vbar_el1 %llx\n",read_sysreg(vbar_el1));
        printk("vbar_el1 %llx\n",read_sysreg_s(SYS_VBAR_EL1));


        return 0;
}

http://www.dtcms.com/a/108367.html

相关文章:

  • Python----机器学习(线性回归:前向传播和损失函数)
  • 【C++基础知识】 C 预处理器中的 #line 指令详解
  • RabbitMQ应用2
  • Linux系统之SFTP-搭建SFTP服务器
  • ui-tars和omni-parser使用
  • JavaScript 模块化详解( CommonJS、AMD、CMD、ES6模块化)
  • 网络安全-等级保护(等保) 1-0 等级保护制度公安部前期发文总结
  • 蓝桥杯 web 表格数据转化(组件挂载、模板字符串)
  • 【硬件视界9】网络硬件入门:从网卡到路由器
  • C# 扩展方法
  • 跨网连接vscode
  • 银联三级等保定级报告
  • CMake学习--Window下VSCode 中 CMake C++ 代码调试操作方法
  • 闭环SOTA!北航DiffAD:基于扩散模型实现端到端自动驾驶「多任务闭环统一」
  • 面基spring如何处理循环依赖问题
  • conda 清除 tarballs 减少磁盘占用 、 conda rename 重命名环境、conda create -n qwen --clone 当前环境
  • 机器学习、深度学习和神经网络
  • vscode调试python(transformers库的llama为例)
  • C#实现HiveQL建表语句中特殊数据类型的包裹
  • 用docker部署goweb项目
  • RainbowDash 的 Robot
  • C++学习笔记(三十一)——map
  • Git的基础使用方法
  • 微信小程序唤起app
  • 【Docker】使用Docker快速部署n8n和unclecode/crawl4ai
  • PEFT实战(一)——LoRA
  • 大模型学习一:deepseek api 调用实战以及参数介绍
  • 【动手学深度学习】#7 现代卷积神经网络
  • C++多态:从青铜九鼎到虚函数表的千年演化密码
  • Pytorch|RNN-心脏病预测