用户态程序参考代码:
最简单的DRM应用程序 (single-buffer)_hexiaolong2009的专栏-CSDN博客_drm应用
modeset-single-buffer.c
驱动参考代码:
DRM 驱动程序开发(VKMS)_hexiaolong2009的专栏-CSDN博客_drm_driver
本文主要通过用户态的调用流程跟踪内核vkms驱动的调用逻辑:
(1) drmModeGetResources
drm_ioctl_*控制宏定义在文件:
drivers/gpu/drm/drm_ioctl.c
DRM_IOCTL_MODE_GETRESOURES
vkms_test-148 [000] .... 98437.235964: drm_mode_getresources <-drm_ioctl_kernel
vkms_test-148 [000] .... 98437.235975: <stack trace>
=> ftrace_graph_call
=> drm_ioctl_kernel
=> drm_ioctl
=> sys_ioctl
=> ret_fast_syscall
(2)drmModeGetConnector
DRM_IOCTL_MODE_GETCONNECTOR
vkms_test-157 [001] .... 98790.566146: drm_mode_getconnector <-drm_ioctl_kernel
vkms_test-157 [001] .... 98790.566293: <stack trace>
=> ftrace_graph_call
=> drm_ioctl_kernel
=> drm_ioctl
=> sys_ioctl
=> ret_fast_syscall
(3)创建dumb-buffer
dumb_create用于创建gem object, 并分配物理buffer,这里使用shmmem实现,通过drm_mode_create_dumb.handle标识该gem object, 该hanle实际上是由drm_file.object_idr分配的唯一id,通过该handle就可以找到gem object, 具体应该是通过drm_gem_object_lookup查找,这个待确认
DRM_IOCTL_MODE_CREATE_DUMB--->drm_driver.dumb_create
vkms_test-163 [001] .... 99530.991049: drm_gem_shmem_dumb_create <-drm_mode_create_dumb
vkms_test-163 [001] .... 99530.991070: <stack trace>
=> ftrace_graph_call
=> drm_mode_create_dumb
=> drm_mode_create_dumb_ioctl
=> drm_ioctl_kernel
=> drm_ioctl
=> sys_ioctl
=> ret_fast_syscall
(3)drmModeAddFB
对应于fb_create,用于创建framebuffer object,并绑定gem objects。
注意这里创建的fb object用来给KMS层也就是(plane/crtc等)使用的,将将该fb绑定到对应的crtc或者plane上之后就可以显示了。而fb object对应的真正物理内存是用dumb_create申请的gem object
注意fb object使用在用户态使用buffer_object.fb_id标识,内核态drm驱动中使用drm_buffer.base.id标识,注意base成员变量为drm_mode_object类型, 这里的fb_id实际上是base的id
该id由drm_device.mode_config.object_idr统一分配,该fb(drm_buffer)会添加到drm_device.mode_config.fb_list上统一管理,根据fb_id__drm_mode_object_find找到drm_mode_object(base), 然后通过obj_to_fb接口反推出framebuffer object
DRM_IOCTL_MODE_ADDFB2-->drm_mode_config_funcs.fb_create
vkms_test-169 [002] .... 100006.855986: drm_gem_fb_create <-drm_internal_framebuffer_create
vkms_test-169 [002] .... 100006.856008: <stack trace>
=> ftrace_graph_call
=> drm_internal_framebuffer_create
=> drm_mode_addfb2
=> drm_mode_addfb
=> drm_mode_addfb_ioctl
=> drm_ioctl_kernel
=> drm_ioctl
=> sys_ioctl
=> ret_fast_syscall
(3)由drm_driver.dumb_map_offset或drm_gem_dumb_map_offset给gem objects对应的物理buffer分配一个虚拟地址空间的offset,具体是为什么要分配这个offset,需要进一步确认
DRM_IOCTL_MODE_MAP_DUMB
DRM_IOCTL_MODE_MAP_DUMB
(4)mmap映射虚拟地址
vkms_test-182 [003] .... 103516.192589: drm_gem_mmap <-mmap_region
vkms_test-182 [003] .... 103516.192611: <stack trace>
=> ftrace_graph_call
=> mmap_region
=> do_mmap
=> vm_mmap_pgoff
=> ksys_mmap_pgoff
=> sys_mmap_pgoff
=> ret_fast_syscall
(4)drmModeSetCrtc将framebuffer object通过其fb_id绑定到对应的crtc上
对应驱动drm_crtc_funcs.set_config
DRM_IOCTL_MODE_SETCRTC
vkms_test-188 [001] .... 104164.872704: drm_atomic_helper_set_config <-drm_mode_setcrtc
vkms_test-188 [001] .... 104164.872723: <stack trace>
=> ftrace_graph_call
=> drm_mode_setcrtc
=> drm_ioctl_kernel
=> drm_ioctl
=> sys_ioctl
=> ret_fast_syscall
具体细节后续接着分析