下面为用户层函数代码:
void simple_test(char *filename, int dma_fd)
{
int file_fd
void *user_mem = NULL;
int pagesize = 0;
int rc;
file_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_DIRECT, 0666);
user_mem = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, dma_fd, 0);
if (user_mem == (void*) -1)
{
fprintf(stderr, "mmap: %s\n", strerror(errno));
exit(-1);
}
printf("user_mem %p\n", user_mem);
rc = write(file_fd, user_mem, pagesize);
if (rc < 0)
{
perror("write file");
}
else if(rc != pagesize)
{
printf("Write file fail 0x%lx != 0x%lx.\n", rc, pagesize);
}
rc = munmap(user_mem, pagesize);
if (rc)
{
perror("munmap");
}
}
内核驱动使用dma_alloc_coherent分配的内存,使用dma_mmap_coherent映射到用户空间。
执行测试函数simple_test时报write file: Bad addree
映射的地址和长度都是页大小的整数倍。不使用O_DIRECT时没有错误。
https://blog.csdn.net/pplogic/article/details/86978353
在Linux下,使用O_DIRECT模式创建文件时,需要满足一些特定的要求。其中之一是写入文件的缓冲区必须是页对齐的,而且长度必须是页大小的整数倍。根据您提供的代码,可能是由于没有正确对齐缓冲区导致了Bad address错误。
为了解决这个问题,您可以执行以下步骤:
下面是修改后的示例代码:
void simple_test(char *filename, int dma_fd)
{
int file_fd;
void *user_mem = NULL;
int pagesize = 0;
int rc;
pagesize = sysconf(_SC_PAGESIZE);
file_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_DIRECT, 0666);
user_mem = mmap(0, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, dma_fd, 0);
if (user_mem == (void*) -1)
{
fprintf(stderr, "mmap: %s\n", strerror(errno));
exit(-1);
}
// 对齐缓冲区
void *aligned_mem = (void *)(((unsigned long)user_mem + pagesize - 1) & ~(pagesize - 1));
printf("user_mem %p\n", aligned_mem);
rc = write(file_fd, aligned_mem, pagesize);
if (rc < 0)
{
perror("write file");
}
else if(rc != pagesize)
{
printf("Write file fail 0x%lx != 0x%lx.\n", rc, pagesize);
}
rc = munmap(user_mem, pagesize * 2);
if (rc)
{
perror("munmap");
}
}
根据您的具体情况进行适当的修改和调整。确保对齐缓冲区的大小是页大小的整数倍