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 }