当前位置: 技术问答>linux和unix
Linux2.6内核mmap的问题! 请高手指教!
来源: 互联网 发布时间:2016-01-03
本文导语: 问题:用户空间调用mmap时老是返回NULL 用户空间代码 char * p; int i; ...
问题:用户空间调用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 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 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了?
用户空间代码
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 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 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了?
|
你需要找出在内核中到底是哪一地方出了错,跟踪到这个问题后来再提问,这样看不出有什么错误的
个人认为,你是映射的高端地址吗??对于常规的RAM地址,用MMAP好像不行
个人认为,你是映射的高端地址吗??对于常规的RAM地址,用MMAP好像不行
|
from 2.6.15 (maybe elder version, I'm not sure now...), remap_page_range() changed to remap_pfn_range()
|
pos = (unsigned long)(buffer);
该为pos = (unsigned long)(buffer)+offset;试试
该为pos = (unsigned long)(buffer)+offset;试试