美文网首页BB-black开发板[Linux arm-v8]
framebuffer驱动qemu仿真调试--Apple的学习笔

framebuffer驱动qemu仿真调试--Apple的学习笔

作者: applecai | 来源:发表于2021-01-12 21:21 被阅读0次

    一,前言

    之前ubuntu18.04配置网桥支持qemu模拟开发板挂载NFS启动LCD--Apple的学习笔记
    已经完成了qemu仿真LCD,并且实现了framebuffer的应用。于是想调试下源码,原因是光看代码可能会理解错误。但是vexpress a9开发板看了下设备树后发现他用的不是LCDC的framebuffer而是用了drm框架。
    但是复习了下DRM框架后,发现其实framebuffer都是注册的,那么就可以当做fbdev用了。然后分析代码的话还是选简单的s3c2410fb.c来分析,看了代码后,发现和我之前分析fbtft使用framebuffer子系统类似,可以参考Linux驱动OLED屏st7735s(framebuffer学习)--Apple的学习笔记。为了能实际调试我在直接下载了一个被二次开发过的qemu,能支持mini2440仿真。

    二,s3c2410fb.c关键代码分析(内核版本5.4.61)

    1.设置寄存器为LCDC设置总线时序margin timer及刷新频率,LCD内存起始地址
    s3c2410fb_set_par ->s3c2410fb_activate_var --->s3c2410fb_calculate_tft_lcd_regs和s3c2410fb_set_lcdaddr
    2.probe函数会挂上具体芯片的操作函数
    fbinfo->fbops = &s3c2410fb_ops;

    static struct fb_ops s3c2410fb_ops = {
        .owner      = THIS_MODULE,
        .fb_check_var   = s3c2410fb_check_var,
        .fb_set_par = s3c2410fb_set_par,
        .fb_blank   = s3c2410fb_blank,
        .fb_setcolreg   = s3c2410fb_setcolreg,
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
    };
    `
    2.probe函数中填充fbinfo后注册register_framebuffer,然后用户空间就可以操作文件系统了。
    ret = register_framebuffer(fbinfo);
    ```c
    static const struct file_operations fb_fops = {
        .owner =    THIS_MODULE,
        .read =     fb_read,
        .write =    fb_write,
        .unlocked_ioctl = fb_ioctl,
    #ifdef CONFIG_COMPAT
        .compat_ioctl = fb_compat_ioctl,
    #endif
        .mmap =     fb_mmap,
        .open =     fb_open,
        .release =  fb_release,
    #if defined(HAVE_ARCH_FB_UNMAPPED_AREA) || \
        (defined(CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA) && \
         !defined(CONFIG_MMU))
        .get_unmapped_area = get_fb_unmapped_area,
    #endif
    #ifdef CONFIG_FB_DEFERRED_IO
        .fsync =    fb_deferred_io_fsync,
    #endif
        .llseek =   default_llseek,
    };
    

    3.fb_mmap在s3c2410.c中没有调用。PAGE_ALIGNvm_iomap_memory为关键函数,一个是alian一个是将虚拟地址转到物理地址,具体的page MMU相关函数内容我不展开,将来做专题分析。

    static int fb_mmap(struct file *file, struct vm_area_struct * vma)
    {
        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;
        mutex_lock(&info->mm_lock);
        //没有注册mmap所以没进入
        if (fb->fb_mmap) {   
            printk("mmap-1\n");
            int res;
            res = fb->fb_mmap(info, vma);
            mutex_unlock(&info->mm_lock);
            return res;
        }
        // 走如下路径
        /* frame buffer memory */
        start = info->fix.smem_start;
        len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
        printk("mmap-start=0x%x,len=%d\n",start,len);
        if (off >= len) {
            printk("mmap-off=0x%x\n",off);
            /* memory mapped io */
            off -= len;
            if (info->var.accel_flags) {
                mutex_unlock(&info->mm_lock);
                return -EINVAL;
            }
            start = info->fix.mmio_start;
            len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
        }
        mutex_unlock(&info->mm_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);
        printk("mmap-2\n");
        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;
    }
    

    三,调试

    之前我记得fbtft还使用了通用的mmap,并且开启了defio。s3c2410bf.c中没有使用自己的mmap,我添加调试信息来验证,打印输出的结果也如此,实际仿真与理解一致。见下图左下角log。


    image.png

    相关文章

      网友评论

        本文标题:framebuffer驱动qemu仿真调试--Apple的学习笔

        本文链接:https://www.haomeiwen.com/subject/fzveaktx.html