[英]write on /dev/mem fails with bad address
我正在尝试从用户空间访问 /dev/mem。 为此目的使用 qemu-system-arm。
UART0 被映射:0x101f1000 和 UARTDR 被放置在偏移量 0x0
$ devmem 0x101f1000 8 0x61
以上在控制台上写了'a'。
当我尝试从 C 代码实现相同的逻辑时,它失败了
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int fd;
char ch = 'a';
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) {
perror("open failed");
return -1;
}
if (lseek(fd, 0x101f1000, SEEK_SET) == -1) {
perror("lseek");
}
if (write(fd, &ch, sizeof(ch)) == -1) {
perror("write");
}
close(fd);
return 0;
}
它失败并出现错误:写:地址错误
尝试通过使用 /dev/mem 上的读写系统调用来访问设备寄存器不是一个好主意。 /dev/mem 实现这些系统调用主要是为了方便访问 RAM,如果您尝试在具有设备的地址空间区域上执行此操作,则无法保证它是否会为设备访问正确的宽度。 对于访问设备,您应该改用 mmap(),然后直接访问正确的地址(这使您可以更好地控制访问的宽度以及确切地触摸哪些地址)。 举个例子,你可以查看 devmem 本身的源代码: https : //github.com/hackndev/tools/blob/master/devmem2.c——不到 100 行代码,它非常简单,你已经知道它适用于您的用例。
[可能不是你的主要问题,但仍然]
lseek: Success write: Bad address
您只想使用errno
(或调用perror()
)是前一次调用失败(并且记录为在失败时设置errno
)。
所以这
lseek(fd, 0x101f1000, SEEK_SET);
perror("lseek");
应该看起来像
if ((off_t) -1 == lseek(fd, 0x101f1000, SEEK_SET))
{
perror("lseek() failed");
}
对write()
的调用也是如此,顺便说一句。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.