Linux在应用层读写寄存器

先说结论:在应用层可以通过操作/dev/mem设备文件,以及mmap函数,将寄存器的地址映射到用户空间,然后直接在应用层对寄存器进行操作。

1、dev/mem 设备文件

该设备文件是物理内存的全映像,通过分析dev/mem设备驱动可以知道,通过这个设备文件可以映射整个处理器的地址空间,而不单单是内存。这里的地址空间指的是处理器总线上的全部可寻址空间。除了内存,还有外设IO空间。也就是说通过/dev/mem可以映射0-0xFFFFFFFF的全部物理地址(这个物理地址是真是有效的,处理器访问这个物理地址能够获取有效数据)。

2、mmap函数

/*
 * addr:指定要映射到的虚拟地址,如果写NULL则表示由sys_mmap来分配该虚拟地址
 * length:需要映射的长度
 * port:映射页的权限
 * flags: 标记位
 * fd: 句柄,通常为open("/dev/mem/" ,O_RDWR | O_NDELAY);的返回值
 * offset:需要映射的物理地址
 * 返回值:由物理地址映射得到的虚拟地址
 */
void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);

3、使用条件

当打开CONFIG_STRICT_DEVMEM时,mem驱动会对mmap要映射的物理地址进行范围和位置检查后才能进行映射。检查条件如下:

1:映射范围不能超过4G

2:该物理地址所在iomem不能exclusive

3:该物理地址不能处在lowmem中

4、代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#define MAP_SIZE 0x200
#define PHY_REG_BASE 0xFFB00000
static int fd;
int main (int argc,char *argv[])
{
    fd = open("/dev/mem/",O_RDWR | O_NDELAY);
    
    if(fd < 0)    
    {
        printf("open /dev/mem failed.\n");
        return 0;
    }
    unsigned char *var_reg_base = (unsigned char *)mmap(NULL,MAP_ZIZE,PROT_SREAD|PROT_WRITE,MAP_SHARED,fd,PHY_REG_BASE);
    for(int i = 0;i<MAP_SIZE;i = i+4)
    {
        printf("0x%x = ",(PHY_REG_BASE +i));
        printf("0x%x \n",*(volatile unsigned int *)(var_reg_base +i));
    }
    if(fd)
    {
        close(fd);
    }
    munmap(var_reg_base,phy_reg_base);
    return 0;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值