s3c2410 framebuffer驱动中的mmap分析备忘

原文地址:http://hi.baidu.com/deep_pro/blog/item/4d5f2003122d3b83d53f7c73.html

这几天的高级驱动课真是听得happy,块设备、MTD设备讲的真是框架清晰,豁然开朗
趁着还热乎,有空,记录下s3c2410 framebuffer驱动中的mmap的实现,留待以后实现自己的物理内存映射时参考
此前也就是会掉mmap,如何在内核空间自己实现一个mmap还没有概念
s3c2410fb.c中的fb_ops里并没有mmap的实现,fb是老牌设备驱动了,发展成为一个子系统,所以缺什么实现都是放在更高层的代码里了。

s3c2410fb.c -》s3c24xxfb_probe-》s3c2410fb_map_video_memory -》
info->screen_base = dma_alloc_writecombine(fbi->dev, map_size, &map_dma, GFP_KERNEL);
info->fix.smem_start = map_dma;

从dma内存空间得到了一片物理内存,物理起始地址位于map_dma
info->screen_base 虽然得到的是虚拟地址,但是是属于内核空间的虚拟地址

然后在fbmem.c 中,
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;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值