Linux2.6内核mmap的问题! 请高手指教!
问题:用户空间调用mmap时老是返回NULL
用户空间代码片断
char * p;
int i;
int fd;
int len = 512;
fd = open("/dev/tdev",O_RDWR);
p = (char *)mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
printf("buffer address 0x%x n",p);
printf("buffer data <%s> n",p);
内核空间代码:
unsigned char *buffer;
static void *rvmalloc(unsigned long size)
{
void *mem;
unsigned long adr;
size = PAGE_ALIGN(size);
mem = vmalloc_32(size);
if (!mem)
return NULL;
memset(mem, 0, size); /* Clear the ram out, no junk to the user */
adr = (unsigned long) mem;
while (size > 0) {
SetPageReserved(vmalloc_to_page((void *)adr));
adr += PAGE_SIZE;
size -= PAGE_SIZE;
}
return mem;
}
void init()
{
buffer = rvmalloc(640);
}
static int adspdev_mmap(struct file *file, struct vm_area_struct *vma)
{
unsigned long start = vma->vm_start;
unsigned long size = vma->vm_end - vma->vm_start;
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long page, pos;
if (size > 640)
return -EINVAL;
pos = (unsigned long)(buffer);
while (size > 0)
{
page = vmalloc_to_pfn((void *)pos);
if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
{
return -EAGAIN;
}
start += PAGE_SIZE;
pos += PAGE_SIZE;
if (size > PAGE_SIZE)
size -= PAGE_SIZE;
else
size = 0;
}
vma->vm_flags &= ~VM_IO; /* not I/O memory */
vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
return 0;
}
此外:
Linux 2.6内核是不是没有remap_page_range了?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我使用的是no mmu的芯片和uClinux系统,没有虚拟内存,完全是线性地址空间,地址是连续的物理地址。
干脆不用mmap, 管它内核空间还是用户空间直接读写地址了!
查了一下源代码
2.6内核remap_page_range改成改成remap_pfn_range()了
vmalloc分配的内存在物理上是不连续的, 所以必须分别映射每一个内存页,使用nopage。2.6remap_page_range这个函数被新的函数替代了。
using the nopage() method here.
应该是你的驱动中的mmap函数存在问题,你可以去看看ldd