- 论坛徽章:
- 0
|
本帖最后由 Alan0521 于 2012-09-05 09:11 编辑
最近看LCD驱动,fb_mmap函数有些地方有些疑问,望大家提点,谢谢!
主要是代码中红字部分,不清楚什么意思。
static int
fb_mmap(struct file *file, struct vm_area_struct * vma)
__acquires(&info->lock)
__releases(&info->lock)
{
int fbidx = iminor(file->f_path.dentry->d_inode);
struct fb_info *info = registered_fb[fbidx];
struct fb_ops *fb = info->fbops;
unsigned long off;
unsigned long start;
u32 len;
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
return -EINVAL;
off = vma->vm_pgoff << PAGE_SHIFT;
if (!fb)
return -ENODEV;
//如果在fb_ops里实现了fb_mmap,调用用户自己实现的fb_mmap即可,如前所述,这里没有实现
if (fb->fb_mmap) {
int res;
mutex_lock(&info->lock);
res = fb->fb_mmap(info, vma);
mutex_unlock(&info->lock);
return res;
}
mutex_lock(&info->lock);
/* frame buffer memory */
start = info->fix.smem_start;
//起始地址是页对齐的
len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
//mmap中的off含义根据具体的驱动不同而不同
//显卡设备里往往是用作把显卡寄存器也直接映射给用户空间,加速操作
if (off >= len) {
/* memory mapped io */
off -= len;
if (info->var.accel_flags) {
mutex_unlock(&info->lock);
return -EINVAL;
}
start = info->fix.mmio_start;
len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
}
mutex_unlock(&info->lock);
start &= PAGE_MASK;
if ((vma->vm_end - vma->vm_start + off) > len)
return -EINVAL;
off += start;
//指定该段内存属性
vma->vm_pgoff = off >> PAGE_SHIFT;
/* This is an IO map - tell maydump to skip this VMA */
vma->vm_flags |= VM_IO | VM_RESERVED;
fb_pgprotect(file, vma, off);
//正式映射物理内存到用户空间虚拟地址
if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
return 0;
}
|
|