繁体   English   中英

在 /dev/mem 上写入失败,地址错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM