RV1126双摄调试记录

RV1126双摄调试记录 tomato 2024-01-04 17:26:55 428

硬件方案: 双12M IMX577
分辨率 4048x3040
bayer 大约18MB(视频处理中会多次以该大小分配内存块)

IMX577驱动

imx577 sensor 驱动可从rk3588中移植修改来用。
主要修改以下3点:
1.把RKMODULE_GET_CHANNEL_INFO宏定义及struct rkmodule_channel_info定义拷过来;

2.实现imx577_g_mbus_config函数,其中config->type = V4L2_MBUS_CSI2_DPHY;改为config->type = V4L2_MBUS_CSI2;

3.把函数挂到v4l2_subdev_video_ops结构体(注意不是v4l2_subdev_pad_ops)

dts修改:

channel 1( sensor -> vicap -> isp):
sensor -> csi_dphy0 -> mipi_csi2 -> rkcif_mipi_lvds
rkcif_mipi_lvds_sditf-> rkisp_vir0
channel 2( sensor -> isp):
sensor -> csi_dphy1 -> rkisp_vir1

排错分析

此时运行ispserver并访问video节点kernel会崩溃:

Unable to handle kernel paging request at virtual address ecc00000

[   21.439757] [<b011ba40>] (v7_dma_clean_range) from [<b0116d54>] (__map_sg_chunk+0x268/0x3b8)
[   21.440541] [<b0116d54>] (__map_sg_chunk) from [<b01170c8>] (__iommu_map_sg+0x224/0x238)
[   21.441264] [<b01170c8>] (__iommu_map_sg) from [<b0117114>] (arm_iommu_map_sg+0x18/0x20)
[   21.441982] [<b0117114>] (arm_iommu_map_sg) from [<b07d7c40>] (vb2_dma_sg_dmabuf_ops_map+0xd0/0x14c)
[   21.442789] [<b07d7c40>] (vb2_dma_sg_dmabuf_ops_map) from [<b0683f88>] (dma_buf_map_attachment+0x24/0x48)
[   21.443668] [<b0683f88>] (dma_buf_map_attachment) from [<b07974a4>] (vb2_dma_sg_map_dmabuf+0x28/0x9c)
[   21.444488] [<b07974a4>] (vb2_dma_sg_map_dmabuf) from [<b07d91d0>] (rkispp_event_handle+0x1e0/0x4d8)
[   21.445292] [<b07d91d0>] (rkispp_event_handle) from [<b07d4904>] (bridge_ioctl+0x1cc/0x5cc)
[   21.446029] [<b07d4904>] (bridge_ioctl) from [<b07def24>] (rkispp_start_streaming+0x228/0x56c)
[   21.446820] [<b07def24>] (rkispp_start_streaming) from [<b0791010>] (vb2_start_streaming+0x5c/0x150)
[   21.447629] [<b0791010>] (vb2_start_streaming) from [<b0792698>] (vb2_core_streamon+0x11c/0x15c)
[   21.448412] [<b0792698>] (vb2_core_streamon) from [<b077da30>] (__video_do_ioctl+0x1c8/0x3a0)
[   21.449162] [<b077da30>] (__video_do_ioctl) from [<b07811e0>] (video_usercopy+0x21c/0x650)
[   21.449921] [<b07811e0>] (video_usercopy) from [<b0277a94>] (do_vfs_ioctl+0xac/0x798)
[   21.450645] [<b0277a94>] (do_vfs_ioctl) from [<b02781b4>] (ksys_ioctl+0x34/0x58)
[   21.451310] [<b02781b4>] (ksys_ioctl) from [<b0101000>] (ret_fast_syscall+0x0/0x4c)
[   21.451988] Exception stack(0xda85dfa8 to 0xda85dff0)

kernel启动打印内存布局如下:

[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xed000000 - 0xff800000   ( 296 MB)
[    0.000000]     lowmem  : 0xb0000000 - 0xecc00000   ( 972 MB)
[    0.000000]     pkmap   : 0xafe00000 - 0xb0000000   (   2 MB)
[    0.000000]     modules : 0xaf000000 - 0xafe00000   (  14 MB)
[    0.000000]       .text : 0x(ptrval) - 0x(ptrval)   (12256 kB)
[    0.000000]       .init : 0x(ptrval) - 0x(ptrval)   (1024 kB)
[    0.000000]       .data : 0x(ptrval) - 0x(ptrval)   ( 699 kB)
[    0.000000]        .bss : 0x(ptrval) - 0x(ptrval)   ( 310 kB)

可知vb2_start_streaming过程中在v7_dma_clean_range函数错误访问了lowmem的up边界。
崩溃堆栈可知该崩溃发生在rkispp驱动的attachment dma_buf中
但实际该dma_buf是rkisp_rkispp_bridge驱动在isp中分配通过bridge挂接到rkispp中 共用。
追查发现rkisp分配的dma_buf采用的videobuf2-rdma-sg.c分配器,该分配器alloc会从cma-isp(dts中的isp_reserved)中分配连续内存,没有充分利用上scatter/gather机制,通过的dts可知cma-isp仅在VICAP及isp/ispp驱动中被使用,内存使用比较一致,垃圾碎片问题应当不会严重,即便碎片致使分配不到整块大内存也该报错而非分配成功使用崩溃。

整理思路继续分析

deconfig中打开CONFIG_CMA_DEBUGFS=y
此命令会在debugfs中导出cma信息供调试
编译烧写启动系统
cat /sys/kernel/debug/cma/cma-isp/base_pfn
发现base_pfn基址在187,392,左移12位正好0x2DC00000,有dts的isp_reserved可知该cma大小为256MB,此信息也可通过执行dmesg|grep Reserved得到下面两行信息获得:
[ 0.000000] Reserved memory: created CMA memory pool at 0x3f800000, size 8 MiB
[ 0.000000] Reserved memory: created CMA memory pool at 0x2dc00000, size 256 MiB

可知该cam-isp范围在0x2DC00000 ~ 0x3DC00000
通过内存布局可知lowmem在0xB0000000 ~ 0xECC00000

# cma.c
    for (;;) {
        mutex_lock(&cma->lock);
        bitmap_no = bitmap_find_next_zero_area_off(cma->bitmap,
                bitmap_maxno, start, bitmap_count, mask,
                offset);
        if (bitmap_no >= bitmap_maxno) {
            mutex_unlock(&cma->lock);
            break;
        }
        bitmap_set(cma->bitmap, bitmap_no, bitmap_count);
        /*
         * It's safe to drop the lock here. We've marked this region for
         * our exclusive use. If the migration fails we will take the
         * lock again and unmark it.
         */
        mutex_unlock(&cma->lock);

        pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit);
        if (cma->inactive) {
            ret = 0;
            page = pfn_to_page(pfn);
            break;
        }
        。。。
    }

以上代码可知,在cma->inactive为True时cma分配内存直接简单映射到lowmem,inactive在dts默认被设置故成立(取消设置影响较大,不建议),而追踪cma 区域初始化代码发现cma的start地址总是在有效物理内存区域top_down而分配,且未考虑vmalloc对lowmem的挤压。
综合考虑两个内存范围:
cma-isp phys 0x2DC00000 ~ 0x3DC00000
lowmem virtual 0xB0000000 ~ 0xECC00000
故cma分配的物理内存可能超出lowmem高址16MB,即cma在尾端认为尚有足够内存分配,然而在lowmem却越界,故而崩溃。

结论

cma空间布局仅考虑物理内存可用空间优先高址分配,映射到lowmem使用,而32bit linux系统lowmem通常涵盖不完物理内存,导致cma分配的内存在lowmem存在映射越zone的风险,同时vmalloc也会挤压lowmem空间使问题恶化。

解决

解决方案一

既然问题是cma空间布局跟lowmem存在不协调风险,那么分配时能够控制start,end主动与既知lowmem区域协调最好不过。

# rv1126_xxxx.dts
&isp_reserved {
    alloc-ranges = <0x10000000 0x10000000>;
    size = <0x10000000>;
};

以上dts配置控制cma分配区域,避免与lowmem出现差集。
该方案依然使用cma,保留性能优势,然而cma也存在使内存利用不充分的弊端。

解决方案二

直接使用系统内存配合sg机制

# driver/media/platform/rockchip/isp/hw.c
static int rkisp_hw_probe(struct platform_device *pdev) {
    ......
    if (is_mem_reserved) {
        /* reserved memory using rdma_sg */
        hw_dev->mem_ops = &vb2_rdma_sg_memops;
        hw_dev->is_dma_sg_ops = true;
    } else if (hw_dev->is_mmu) {
        hw_dev->mem_ops = &vb2_dma_sg_memops;
        hw_dev->is_dma_sg_ops = true;
    } else {
        hw_dev->mem_ops = &vb2_dma_contig_memops;
    }
    ......
}

以上源码可知rkisp/hw驱动可通过is_mem_reserved控制使用哪个分配器,默认的vb2_rdma_sg_memops会从预留的cma分配连续物理/虚拟空间, 其中vb2_dma_sg_memops分配器可凭借list方式从系统内存分散申请dma空间,不要求连续,理论性能弱于cma但实际视频处理帧率并未有明显变化,该方式能更充分利用内存资源。
至于is_mem_reserved,追踪源码即知可通过dts的rkisp节点的memory-region字段有无间接被设置。
以下为具体修改:

# rv1126.dtsi
rkisp {
    ...
    # memory-region = <&isp_reserved>;
    ...
};
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
tomato
红包 1 2 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
tomato
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区