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

我正在尝试从用户空间访问/ 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;
}

它失败并显示错误:     写:错误的地址

cjh1031 回答:在/ dev / mem上写入失败,地址错误

尝试通过使用在/ 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,SEEK_SET))
{
  perror("lseek() failed");
}

与呼叫write()(顺便说一句)相同。

本文链接:https://www.f2er.com/3038428.html

大家都在问