zoukankan      html  css  js  c++  java
  • Linux 操作系统读写寄存器

    Linux 内核中操作寄存器

    其实对于 Linux 内核中操作寄存器是一件特别简单的事情,首先你需要知道你要操作寄存器的地址,有可能是网卡状态寄存器,有可能是门铃寄存器等等,不管是什么寄存器他都是在内存中映射出来的一段地址。

    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/io.h>
    
    static int __init hello_init(void)
    {
            /* ioremap 由物理地址转换为虚拟地址 */
            unsigned long register_address = (unsigned long)ioremap(0x800286020c4, 4);
            /* 操作该寄存器 */
            *(unsigned int *)register_address = 0x1000;
            /* 读取该寄存器 */
            pr_err("*register_address = %x
    ", *(unsigned int *)register_address);
    
            return 0;
    }
    
    static void __exit hello_exit(void)
    {
            printk(KERN_ALERT "Bye man, I have been unload.
    ");
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    MODULE_AUTHOR("Jackie Liu <liuyun01@kylinos.cn>");
    MODULE_LICENSE("GPL");

    Linux 应用层操作寄存器

    应用层操作寄存器首先需要将内核映射到核外空间,内核已经提供了一个 /dev/mem 的文件接口,这个文件相当于整个系统内存所在,将该文件打开然后指定需要映射的内存的位置即可。需要注意的是,一般 mmap 映射的是一段内存地址空间,譬如一段 PCIe 寄存器空间等等,而不是一个单独的寄存器地址

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/mman.h>
    
    
    #define AUDIO_REG_BASE  (0x80028780000)
    #define MAP_SIZE    0x80000
    
    static int dev_fd;
    int main(int argc, char **argv)
    {
    
        dev_fd = open("/dev/mem", O_RDWR | O_NDELAY);
    
        if (dev_fd < 0)
        {
            printf("open(/dev/mem) failed.");
            return 0;
        }
    
        unsigned char *map_base=(unsigned char * )mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, AUDIO_REG_BASE );
        if (map_base == MAP_FAILED)
            return -1;
    
        printf("%x 
    ", *(volatile unsigned int *)(map_base));
    
        printf("%x 
    ", *(volatile unsigned int *)(map_base+0x38)); //打印该寄存器地址的value
    
    #if 1 // LINE IN
        printf("%x 
    ", *(volatile unsigned int *)(map_base+0x30));
    
        *(volatile unsigned int *)(map_base + 0x30) = 0x208121bc; //修改该寄存器地址的value
        usleep(1000000);
        *(volatile unsigned int *)(map_base + 0x30) &= ~(0x1<<16); //修改该寄存器地址的value
        usleep(1000000);
    
        printf("%x 
    ", *(volatile unsigned int *)(map_base+0x30));
    #endif
    
        if(dev_fd)
            close(dev_fd);
    
        munmap(map_base,MAP_SIZE);//解除映射关系
    
        return 0;
    }
  • 相关阅读:
    tcp/udp并发(大吞吐量)性能测试工具
    postman prerequest动态加密数据构造
    匹配ip的正则表达式
    通过adb命令保存并重命名截图
    python3 urlencode及urldecode
    Android安全测试工具Drozer coverity fortify
    windows下adb shell命令杀进程方式
    postman批量构造数据
    Android app发热功耗思路
    Jenkins+ant+Jenkins接口持续集成测试配置
  • 原文地址:https://www.cnblogs.com/libra13179/p/13809241.html
Copyright © 2011-2022 走看看