linux 应用程序直接读写寄存器或物理内存

1.程序说明:

调试驱动程序时,经常遇到候需要查看或设置寄存器的情况,但是直接更改内核代码又不方便。

这里提供一个应用程序源码能在应用层访问底层寄存器。(网上找到的,进行过更改)。

这里只提供4字节数据的访问,如果需要其他字节宽度则需要更改代码。

line40 增加了O_DSYNC标志,防止cache导致数据写入不及时。

2. 内核实现位置

内核源码位置:/drivers/char/mem.c

3.应用程序源码

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <time.h>
 4 #include <unistd.h>
 5 #include <fcntl.h>
 6 #include <unistd.h>
 7 #include <stdint.h>
 8 #include <sys/mman.h>
 9 #include <errno.h>
10 
11 static int dev_fd;
12 int main(int argc, char **argv)
13 {
14     uint32_t addr, value, map_size,base;
15     void *align_addr;
16     int flag = 0;
17     int i;
18     unsigned char *map_base;
19 
20     if (argc != 5) {
21         printf("usage:   m_reg r base address readcount\n");
22         printf("example: m_reg r 0x50008000 20 1\n");
23         printf("usage:   m_reg w base address writevalue\n");
24         printf("example: m_reg w 0x50008000 20 0xffffffff\n");
25         return -1;
26     }
27 
28     if (argv[1][0] == 'r') {
29         flag = 0;
30         value = strtol(argv[4], NULL, 10);
31     }
32     else {
33         flag = 1;
34         value = strtol(argv[4], NULL, 16);
35     }
36 
37     base = strtol(argv[2], NULL, 16);
38     addr = strtol(argv[3], NULL, 16);
39 
40     dev_fd = open("/dev/mem", O_RDWR | O_NDELAY | O_DSYNC);
41 
42     if (dev_fd < 0)
43     {
44         printf("open(/dev/mem) failed.");
45         return 0;
46     }
47 
48     addr &= ~0x3;
49     align_addr = addr & ~0xff;
50 
51     map_size = addr + 0x100;
52     printf("map base:0x%x size:0x%x\n",base,map_size);
53     map_base = (unsigned int * )mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, base);
54     if(map_base == -1)
55     {
56         printf("map err %d\n",errno);
57         perror("errno:");
58         return -1;
59     }
60     
61     if (flag == 0) {
62 
63         for (i = 0; i < value; i++) {
64             if (i % 4 == 0) {
65                 printf("\n");
66                 printf("0x%08x\t", addr+i*4);
67             }
68             printf("%08x ", *(volatile unsigned int *)(map_base+addr+i*4));
69         }
70         printf("\n");
71 
72     }
73     else {
74         printf("0x%08x\t value:0x%x", addr,value);
75         *(volatile unsigned int *)(map_base + addr) = value;
76     }
77     printf("\n");
78 
79     if(dev_fd)
80         close(dev_fd);
81 
82     munmap((unsigned int *)map_base, map_size);
83 
84     return 0;
85 }

猜你喜欢

转载自www.cnblogs.com/fanguang/p/12284202.html
今日推荐