Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 写入/dev/mem失败,地址错误_C_Linux_Io_Arm_Qemu - Fatal编程技术网

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

C 写入/dev/mem失败,地址错误,c,linux,io,arm,qemu,C,Linux,Io,Arm,Qemu,我正在尝试从用户空间访问/dev/mem。为此目的使用qemu系统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>

我正在尝试从用户空间访问/dev/mem。为此目的使用qemu系统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;
}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
int-fd;
char ch='a';
fd=打开(“/dev/mem”,O_RDWR | O_SYNC);
如果(fd<0){
perror(“开放式失败”);
返回-1;
}
如果(lseek(fd,0x101f1000,寻道集)=-1){
perror(“lseek”);
}
if(写入(fd,&ch,sizeof(ch))=-1){
佩罗(“书面”);
}
关闭(fd);
返回0;
}
它失败并出现错误:
写:地址不正确[可能不是你的主要问题,但仍然是]

如果上一次调用失败,则只需使用
errno
(或调用
peror()
)即可(并记录为在失败时设置
errno

那么这个

lseek(fd, 0x101f1000, SEEK_SET);
perror("lseek");
应该像

if ((off_t) -1 == lseek(fd, 0x101f1000, SEEK_SET))
{
  perror("lseek() failed");
}

write()
的调用也一样,顺便说一句。

尝试使用/dev/mem上的读写系统调用访问设备寄存器不是一个好主意/dev/mem实现这些系统调用主要是为了方便访问RAM,如果您试图在地址空间的某个区域上访问设备,则无法保证它是否会对设备进行正确宽度的访问。对于访问设备,您应该改为使用mmap(),然后直接访问正确的地址(这使您能够更好地控制访问的宽度以及所接触的确切地址)。例如,您可以查看devmem本身的源代码:--不到100行代码,非常简单,您已经知道它适用于您的用例。

对问题的更改使我的答案无法理解。在给出答案/评论后,请不要更改问题,只添加内容。@md.jamal:实际代码(仅在函数失败时调用
peror
)是否显示
lseek:Success
?如果是,lseek失败。lseek成功且写入失败,我已更新代码和output@md.jamal查看
mmap()
,UART寄存器不在进程虚拟地址空间内。也许您可以使用
strace
查看
devmem
如何读取/写入内存。。。
if ((off_t) -1 == lseek(fd, 0x101f1000, SEEK_SET))
{
  perror("lseek() failed");
}