嵌入式 Linux 对内存的直接读写(devmem)

来源:互联网 发布:国际数据流量怎么开通 编辑:程序博客网 时间:2024/06/05 09:07

摘要】 在Linux开发中着实用到的调试工具并不是很多。devmem的方式是提供给驱动开发人员,在应用层能够侦测内存地址中的数据变化,以此来检测驱动中对内存或者相关配置的正确性验证。

http://blog.csdn.net/hens007/article/details/7268447


原文链接:http://blog.csdn.net/xy010902100449/article/details/47028497


这个工具的原理也比较简单,就是应用程序通过mmap函数实现对/dev/mem驱动中mmap方法的使用,映射了设备的内存到用户空间,实现对这些物理地址的读写操作。

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <signal.h>#include <fcntl.h>#include <ctype.h>#include <termios.h>#include <sys/types.h>#include <sys/mman.h>#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \  __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)#define MAP_SIZE 4096UL#define MAP_MASK (MAP_SIZE - 1)int main(int argc, char **argv) {    int fd;    void *map_base, *virt_addr;     unsigned long read_result, writeval;    off_t target;    int access_type = 'w';    if(argc < 2) {//若参数个数少于两个则打印此工具的使用方法        fprintf(stderr, "\nUsage:\t%s { address } [ type [ data ] ]\n"            "\taddress : memory address to act upon\n"            "\ttype    : access operation type : [b]yte, [h]alfword, [w]ord\n"            "\tdata    : data to be written\n\n",            argv[0]);        exit(1);    }    target = strtoul(argv[1], 0, 0);    if(argc > 2)        access_type = tolower(argv[2][0]);    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;    printf("/dev/mem opened.\n");     fflush(stdout);    /* Map one page */ //将内核空间映射到用户空间    map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);    if(map_base == (void *) -1) FATAL;    printf("Memory mapped at address %p.\n", map_base);     fflush(stdout);    virt_addr = map_base + (target & MAP_MASK);    //针对不同的参数获取不同类型内存数据&nbsp;   switch(access_type) {        case 'b':            read_result = *((unsigned char *) virt_addr);            break;        case 'h':            read_result = *((unsigned short *) virt_addr);            break;        case 'w':            read_result = *((unsigned long *) virt_addr);            break;        default:            fprintf(stderr, "Illegal data type '%c'.\n", access_type);            exit(2);    }    printf("Value at address 0x%X (%p): 0x%X\n", target, virt_addr, read_result);     fflush(stdout);        //若参数大于3个,则说明为写入操作,针对不同参数写入不同类型的数据    if(argc > 3) {        writeval = strtoul(argv[3], 0, 0);        switch(access_type) {            case 'b':                *((unsigned char *) virt_addr) = writeval;                read_result = *((unsigned char *) virt_addr);                break;            case 'h':                *((unsigned short *) virt_addr) = writeval;                read_result = *((unsigned short *) virt_addr);                break;            case 'w':                *((unsigned long *) virt_addr) = writeval;                read_result = *((unsigned long *) virt_addr);                break;        }        printf("Written 0x%X; readback 0x%X\n", writeval, read_result);         fflush(stdout);    }    if(munmap(map_base, MAP_SIZE) == -1) FATAL;    close(fd);    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
memdev:直接读写内存。可以在busybox的杂项中找到:CONFIG_USER_BUSYBOX_DEVMEM:                                       devmem is a small program that reads and writes from physical     memory using /dev/mem.                                           Symbol: USER_BUSYBOX_DEVMEM [=y]                                  Prompt: devmem                                                      Defined at ../user/busybox/busybox-1.14.3/miscutils/Kconfig:216   Depends on: USER_BUSYBOX_BUSYBOX                                  Location:                                                           -> BusyBox (USER_BUSYBOX_BUSYBOX [=y])                              -> Miscellaneous Utilities                                  [用法]Usage: devmem ADDRESS [WIDTH [VALUE]]读取:在地址0x97000000读取32bit值(WIDTH默认等于32, 可选值为[8, 16, 32, 64])/dev # devmem 0x97000000 0x11111111读取:在地址0x97000000读取16bit值/dev # devmem 0x97000000 160x1111写入:在地址0x97000000写入32bit值0x7777ABCD/dev # devmem 0x97000000 32 0x7777ABCD/dev # devmem 0x97000000              0x7777ABCD注意:如果/dev下没有mem这个node,会出现错误:/dev # devmem 0x97000000 devmem: can't open '/dev/mem': No such file or directory这时可以在Host系统中手动创建一个(例如在NFS root filesystem模式):host@host-laptop:~/embedded/tftpboot/nfsroot/dev$ sudo mknod mem -m666 c 1 1注意这里的权限是666,允许任何人任意读写,可以很好的配合程序debug。/dev # devmem 0x970000000x7777ABCD
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 哈罗单车电动车骑着没电了怎么办 招聘线上测评的通行证过期了怎么办 上海落户在国企辞职后户口怎么办 老党员干部档案丢失人以去世怎么办 档案中的年龄有涂改办理退休怎么办 到办理退休不知档案在那怎么办 职工办理退休时档案丢了怎么办 老婆嫌我穷把我和孩子抛弃了怎么办 我招工表比我实际年龄小一岁怎么办 考上好学校名额被顶替了怎么办 面试题领导越级安排工作你怎么办 一个23岁的大学生身体肥胖怎么办 雷达手表把调时间的把出来了怎么办 农村没有住电表被卸载了怎么办 工商已吊销未注销要恢复营业怎么办 中专类学校取消后在编的老师怎么办 情迁微信内置抢红包版本过低怎么办 船运货给客户货到他不要怎么办 摩拜单车锁了还在计费怎么办 旧公司股份现成立新公司股份怎么办 比亚迪l3线路进水打不着火怎么办 新成立的建筑公司没有业绩怎么办 被骗做了深圳国税实名办税怎么办 天猫精灵生活灯老是离线怎么办 电信合约没到期不想用了怎么办 电信合约卡到期不想用了怎么办 欧普照明平板灯坏了怎么办 交通违章处理了但系统没更新怎么办 车里的空调一直吹的是热气怎么办 丰田雷凌保养手册丢了怎么办 海尔电视两年主板坏了怎么办 海信电视保修期内主板坏了怎么办 乐视电视的主板坏了怎么办 车电瓶没电了打不着火怎么办 面包车没电了打不着火怎么办 汽车电瓶没电了打不着火怎么办 自动挡的车没有电打不起来火怎么办 自动挡汽车没电了打不着火怎么办 自动挡小车没电了打不着火怎么办 被4s店销售骗了怎么办 宇通客车尿素泵不工作怎么办