devmem

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

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

  1. 用法: devmem2 { address } [ type [ data ] ]
  2. address : 物理地址
  3. 如果是要修改该地址的数据,需要填入下面的参数;如果只是读取,省略即可
  4. type :要访问的数据类型 : [b]yte, [h]alfword, [w]ord
  5. data :想要写入的数据
通过使用,发现IO内存和物理内核都可以读写。
-----------------------------------------------------------------------------------------
  在后来的模块调试中,有一次需要查看内核虚拟地址中的数据,我又想起了“/dev/kmem”,直接就在网上找了一个通过这个节点读取 (仅支持读取)内核虚拟地址中的数据。 经过测试,只适用于内核逻辑地址。
加入Makefile后打包,分享如下:

使用方法:
  1. 用法: devkmem { address }
  2. address : 虚拟地址(内核逻辑地址)
-----------------------------------------------------------------------------------------------
/dev/mem和/dev/kmem其实是在同一个驱动中代码中产生的:drivers/char/mem.c

<think>好的,我现在需要帮助用户解决如何使用devmem工具批量读取内存地址的问题。首先,我得回忆一下devmem的基本用法和相关知识。根据用户提供的引用内容,特别是引用[1]和[3],devmem是通过mmap映射物理地址到用户空间,允许直接读写内存。基本命令格式是`devmem ADDRESS [WIDTH [VALUE]]`,其中ADDRESS是物理地址,WIDTH是数据宽度,默认32位,VALUE是要写入的值,如果不写VALUE则是读取。 用户的需求是批量读取多个内存地址的值,而devmem本身每次只能处理一个地址。所以需要想办法循环调用devmem或者编写脚本。首先想到的是使用Shell脚本,比如for循环遍历地址列表。例如,可以写一个脚本,循环读取从起始地址开始,按偏移量递增的多个地址。或者用户可能有特定的地址列表,每个地址都需要单独读取。 接下来,我需要考虑如何构造这样的脚本。比如,如果用户要读取0x97000000到0x9700000F之间的每个32位地址,可以用seq生成地址序列,然后逐个调用devmem。或者用C语言写一个程序,直接调用mmap,这样效率更高,但可能用户更倾向于使用现有的工具如devmem结合脚本。 另外,引用[4]提到devmem常用于驱动调试,直接操作物理地址,但需要注意安全性,因为错误操作可能导致系统崩溃。在批量读取时,尤其要确保地址范围是合法的,避免访问受限区域。 可能的问题包括:如何传递多个地址给devmem,如何处理不同的数据宽度,以及如何格式化输出以便用户查看。还需要注意权限问题,可能需要root权限执行devmem。 可能的解决方案是编写一个Shell脚本,读取一个地址列表文件,逐行调用devmem,并将结果保存到文件。或者使用awk、xargs等工具批量处理。此外,如果地址连续,可以用循环结构自动递增地址值。 最后,要提醒用户谨慎操作,确保地址有效,并考虑使用后台执行或日志记录,特别是在大量读取时。总结步骤应该是:确定地址列表,编写脚本循环调用devmem,处理输出,注意事项。</think>### 分步说明:使用devmem批量读取内存地址 #### 方法1:Shell脚本循环读取(适用于连续地址) ```bash #!/bin/bash BASE_ADDR=0x97000000 # 起始地址 COUNT=10 # 读取次数 WIDTH=32 # 数据宽度(8/16/32/64) for ((i=0; i<COUNT; i++)) do ADDR=$(printf "0x%X" $((BASE_ADDR + i*4))) # 地址按4字节递增(32位宽度) VALUE=$(devmem $ADDR $WIDTH) echo "Address: $ADDR => Value: $VALUE" done ``` **说明**: - 通过`BASE_ADDR`设置起始物理地址,`COUNT`控制读取次数 - `i*4`表示每次地址递增4字节(对应32位宽度),若使用16位则改为`i*2` - 输出格式为`Address: 0x... => Value: 0x...` #### 方法2:从文件读取离散地址(适用于非连续地址) 1. 创建地址列表文件`addr_list.txt`: ``` 0x97000000 0x97000010 0x97000020 ``` 2. 编写脚本: ```bash #!/bin/bash WIDTH=32 while read ADDR do VALUE=$(devmem $ADDR $WIDTH 2>/dev/null) echo "$ADDR: $VALUE" done < addr_list.txt ``` #### 方法3:使用xargs单行命令 ```bash echo -e "0x97000000\n0x97000004" | xargs -I{} devmem {} 32 ``` #### 注意事项 1. **权限要求**:必须使用`sudo`或以root用户执行[^1][^3] 2. **地址有效性**:避免访问保留内存区域(如MMIO寄存器)导致系统崩溃[^4] 3. **性能优化**:连续读取时建议使用C语言直接调用`mmap`(参考引用[1]原理) ```c int fd = open("/dev/mem", O_RDWR); void *map = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, base_addr); ``` 4. **错误处理**:添加`2>/dev/null`可屏蔽权限错误提示 #### 扩展应用 通过`awk`实现十六进制转换: ```bash devmem 0x97000000 32 | awk '{printf "DEC: %d\nHEX: 0x%X\n", $1, $1}' ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值