移植vkms 到Linux-4.9.88内核(基于100ask_imx6ull_pro开发板)
何小龙老师-Blog主页
何小龙老师的DRM系列专栏文章,非常适合系统入门学习DRM,DRM 系列非常精彩
VKMS简介
VKMS 是 “Virtual Kernel Mode Setting” 的缩写,它于2018年7月5日被合入到 linux-4.19 主线版本中,并存放在 drivers/gpu/drm/vkms 目录下。之所以称它为 Virtual KMS,是因为该驱动不需要真实的硬件,它完全是一个软件虚拟的“显示”设备,甚至连显示都算不上,因为当它运行时,你看不到任何显示内容。它唯一能提供的,就是一个由高精度 timer 模拟的 VSYNC 中断信号!该驱动存在的目的,主要是为了 DRM 框架自测试,以及方便那些无头显示器设备的调试应用。虽然我们看不到 VKMS 的显示效果,但是在驱动流程上,它实现了 modesetting 该有的基本操作。因其逻辑简单,代码量少,拿来做学习案例讲解再好不过。
随着内核版本的不断升级,添加到 VKMS 的功能也越来越多,截止到目前最新的内核版本 kernel 5.7-rc2,该 VKMS 驱动已经集成了如下功能:
- Atomic Modeset
- VBlank
- Dumb Buffer
- Cursor & Primary Plane
- Framebuffer CRC 校验
- Plane Composition
- GEM Prime Import
inux-4.19-rc1 是 VKMS 的第一个版本,也最为简单,因此本文就以该版本为例,并将其反向移植到4.9.88 上。
————————————————
版权声明:本文为CSDN博主「何小龙」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hexiaolong2009/article/details/105180621
vkms 驱动移植,编译,测试
vkms-源码
vkms-BLOG
移植碰到的问题及解决方式
1.Cma相关符号 Undefined 问题
ERROR: "drm_gem_cma_dumb_create" [drivers/gpu/drm/vkms/vkms.ko] undefined!
ERROR: "drm_gem_cma_mmap" [drivers/gpu/drm/vkms/vkms.ko] undefined!
ERROR: "drm_fb_cma_create" [drivers/gpu/drm/vkms/vkms.ko] undefined!
ERROR: "drm_gem_cma_free_object" [drivers/gpu/drm/vkms/vkms.ko] undefined!
scripts/Makefile.modpost:91: recipe for target '__modpost' failed
第一次将vkms代码移植过去后,编译出现上面错误,原因及解决办法如下:
config DRM_VKMStristate "Virtual KMS (EXPERIMENTAL)"depends on DRMselect DRM_KMS_HELPERselect DRM_KMS_CMA_HELPERselect DRM_GEM_CMA_HELPERdefault nhelpVirtual Kernel Mode-Setting (VKMS) is used for testing or forrunning GPU in a headless machines. Choose this option to geta VKMS.If M is selected the module will be called vkms.
DRM_GEM_CMA_HELPER/DRM_KMS_CMA_HELPER 已经选定了,理论上CMA_HELPER相关的代码会编译,但是
执行 make modules -j4 提示上面的错误。
错误的原因在于:
选择vkms驱动之前,内核中没有其它驱动选择DRM_GEM_CMA_HELPER/DRM_KMS_CMA_HELPER
导致之前的编译的内核没有将drm_gem_cma_helper.c相关的内容编译进内核
解决办法:
重新编译内核,然后编译模块
make -j4
重新编译内核后,查看undefined的函数是否在内核符号表中
cat Module.symvers | grep drm_gem_cma_dumb_create
0x5bf9e3ea drm_gem_cma_dumb_create vmlinux EXPORT_SYMBOL_GPL
0x2b0173f8 drm_gem_cma_dumb_create_internal vmlinux EXPORT_SYMBOL_GPL
make modules -j4
ko 编译
- 方法1 内核源码编译
vkms.ko
1. 将vkms.7z解压,然后放到内核目录/Linux-4.9.88/drivers/gpu/drm/
https://download.csdn.net/download/wllw7176/856323562. 配置内核config
CONFIG_DRM_VKMS: ││ ││ Virtual Kernel Mode-Setting (VKMS) is used for testing or for ││ running GPU in a headless machines. Choose this option to get ││ a VKMS. ││ ││ If M is selected the module will be called vkms. ││ ││ ││ Symbol: DRM_VKMS [=m] ││ Type : tristate ││ Prompt: Virtual KMS (EXPERIMENTAL) ││ Location: ││ -> Device Drivers ││ -> Graphics support ││ Defined at drivers/gpu/drm/vkms/Kconfig:1 ││ Depends on: HAS_IOMEM [=y] && DRM [=y] ││ Selects: DRM_KMS_HELPER [=y] && DRM_KMS_CMA_HELPER [=y] && DRM_GEM_CMA_HELPER [=y]
3. make modules -j4
4. vkms.ko就是最终的驱动
5. linux内核源码目录编译的驱动并没有进行实际测试,测试的驱动是方法2编译vkms_drv.ko及vkms_drv_atomic.ko
- 方法2 独立目录编译
vkms_drv.ko vkms_drv_atomic.ko
1. 将目录下载解压到虚拟机的任何位置
https://download.csdn.net/download/wllw7176/856323972.解压得到目录 07_vkms, 根据自己的实际情况需修改Makefile
KERN_DIR=/ext_hdd/Public/local_100ask_imx6ull_sdk/Linux-4.9.88 #自己板子使用内核目录
CUR_DIR=`pwd`
OUT_PUT_DIR=$(CUR_DIR)/outputobj-m := vkms_drv.o vkms_drv_atomic.o CC = arm-linux-gnueabihf-gcc #自己使用的交叉工具链
INC_PATH +=
LOCAL_CFLAGS += -Wall
LDFLAGS += -pthreadall:@ if [ ! -d ${OUT_PUT_DIR} ]; then mkdir -p ${OUT_PUT_DIR}; fimake -C $(KERN_DIR) M=$(CUR_DIR) modules -j4 V=1#$(CC) $(INC_PATH) $(LOCAL_CFLAGS) $(LDFLAGS) $(tets_app_src) -o $(test_app_name) mv *.ko ${OUT_PUT_DIR} #ko文件会存放在 ./outputcp ${OUT_PUT_DIR}/*.ko ${sh_dir} #忽略这个,我自己测试用的.PHONY:clean
clean:make -C $(KERN_DIR) M=$(CUR_DIR) modules cleanrm -r ${OUT_PUT_DIR}/
3. 一切ok执行make 后vkms_drv_atomic.ko vkms_drv.ko 会在output目录下
ls output/
vkms_drv_atomic.ko vkms_drv.ko4. 驱动简单说明
vkms_drv.ko legacy接口
vkms_drv_atomic.ko 何小龙老师写的atomic接口版本
5. 后续基于drm的相关测试都基于这个 vkms_drv.ko vkms_drv_atomic.ko这2个驱动
测试
测试代码的修改及编译
1. 原始的libdrm-2.4.100源码自带的测试代码不支持vkms device,直接编译原始的会包如下错误
./libdrm_test_programs/modetest -M vkms
failed to open device 'vkms': No such file or directory2. 修改后的libdrm-2.4.100源码
https://download.csdn.net/download/wllw7176/85596305
包括自带的各种Drm测试程序:kmstest modeprint modetest proptest vbltest自己直接修改libdrm源码支持vkms device也很简单,做如下修改就行:
libdrm-2.4.100\src\tests\util\kms.c
static const char * const modules[] = {"i915","amdgpu","radeon","nouveau","vmwgfx","omapdrm","exynos","tilcdc","msm","sti","tegra","imx-drm","rockchip","atmel-hlcdc","fsl-dcu-drm","vc4","virtio_gpu","mediatek","meson","pl111","stm","sun4i-drm","armada-drm","vkms" //直接添加此行就行
};
3. 修改后重新编译libdrm源码,注意工具链要和编译ko的一致
4. 重新编译,在以下子目录可以找到各个测试程序:kmstest modeprint modetest proptest vbltest
ls build/tests/
kmstest modeprint modetest proptest vbltest
驱动测试
将ko文件及测试程序复制到板子上就可以测试了:
ls /dev/dri/card0
/dev/dri/card0[root@100ask:/home/tftp]# insmod vkms_drv.ko
[ 42.337970] vkms_drv: loading out-of-tree module taints kernel.
[ 42.350879] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[root@100ask:/home/tftp]# ls /dev/dri/card
card0 card1 #card1为新生成节点[root@100ask:/home/tftp]# ./libdrm_test_programs/kmstest -M vkms
main: All ok![root@100ask:/home/tftp]# ./libdrm_test_programs/modeprint vkms
Starting test
Resourcescount_connectors : 1
count_encoders : 1
count_crtcs : 1
count_fbs : 0Connector: Virtual-3id : 30encoder id : 0conn : connectedsize : 0x0 (mm)count_modes : 34count_props : 3props : 2 6 7count_encoders : 1encoders : 29
Mode: "1024x768" 1024x768 60
Mode: "4096x2160" 4096x2160 60
Mode: "4096x2160" 4096x2160 60
Mode: "2560x1600" 2560x1600 60
Mode: "2560x1600" 2560x1600 60
Mode: "1920x1440" 1920x1440 60
Mode: "1856x1392" 1856x1392 60
Mode: "1792x1344" 1792x1344 60
Mode: "2048x1152" 2048x1152 60
Mode: "1920x1200" 1920x1200 60
Mode: "1920x1200" 1920x1200 60
Mode: "1920x1080" 1920x1080 60
Mode: "1600x1200" 1600x1200 60
Mode: "1680x1050" 1680x1050 60
Mode: "1680x1050" 1680x1050 60
Mode: "1400x1050" 1400x1050 60
Mode: "1400x1050" 1400x1050 60
Mode: "1600x900" 1600x900 60
Mode: "1280x1024" 1280x1024 60
Mode: "1440x900" 1440x900 60
Mode: "1440x900" 1440x900 60
Mode: "1280x960" 1280x960 60
Mode: "1366x768" 1366x768 60
Mode: "1366x768" 1366x768 60
Mode: "1360x768" 1360x768 60
Mode: "1280x800" 1280x800 60
Mode: "1280x800" 1280x800 60
Mode: "1280x768" 1280x768 60
Mode: "1280x768" 1280x768 60
Mode: "1280x720" 1280x720 60
Mode: "800x600" 800x600 60
Mode: "800x600" 800x600 56
Mode: "848x480" 848x480 60
Mode: "640x480" 640x480 60Encoder: Virtualid :29crtc_id :0type :5possible_crtcs :0x0possible_clones :0x0Crtcid : 28x : 0y : 0width : 0height : 0mode : 0x65ed74gamma size : 0Ok[root@100ask:/home/tftp]# ./libdrm_test_programs/modetest -M vkms
Encoders:
id crtc type possible crtcs possible clones
29 0 Virtual 0x00000000 0x00000000Connectors:
id encoder status name size (mm) modes encoders
30 0 connected Virtual-3 0x0 34 29modes:name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)1024x768 60 1024 1048 1184 1344 768 771 777 806 65000 flags: nhsync, nvsync; type: preferred, driver4096x2160 60 4096 4104 4136 4176 2160 2208 2216 2222 556744 flags: phsync, nvsync; type: driver4096x2160 60 4096 4104 4136 4176 2160 2208 2216 2222 556188 flags: phsync, nvsync; type: driver2560x1600 60 2560 2752 3032 3504 1600 1603 1609 1658 348500 flags: nhsync, pvsync; type: driver2560x1600 60 2560 2608 2640 2720 1600 1603 1609 1646 268500 flags: phsync, nvsync; type: driver1920x1440 60 1920 2048 2256 2600 1440 1441 1444 1500 234000 flags: nhsync, pvsync; type: driver1856x1392 60 1856 1952 2176 2528 1392 1393 1396 1439 218250 flags: nhsync, pvsync; type: driver1792x1344 60 1792 1920 2120 2448 1344 1345 1348 1394 204750 flags: nhsync, pvsync; type: driver2048x1152 60 2048 2074 2154 2250 1152 1153 1156 1200 162000 flags: phsync, pvsync; type: driver1920x1200 60 1920 2056 2256 2592 1200 1203 1209 1245 193250 flags: nhsync, pvsync; type: driver1920x1200 60 1920 1968 2000 2080 1200 1203 1209 1235 154000 flags: phsync, nvsync; type: driver1920x1080 60 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: nhsync, nvsync; type: driver1600x1200 60 1600 1664 1856 2160 1200 1201 1204 1250 162000 flags: phsync, pvsync; type: driver1680x1050 60 1680 1784 1960 2240 1050 1053 1059 1089 146250 flags: nhsync, pvsync; type: driver1680x1050 60 1680 1728 1760 1840 1050 1053 1059 1080 119000 flags: phsync, nvsync; type: driver1400x1050 60 1400 1488 1632 1864 1050 1053 1057 1089 121750 flags: nhsync, pvsync; type: driver1400x1050 60 1400 1448 1480 1560 1050 1053 1057 1080 101000 flags: phsync, nvsync; type: driver1600x900 60 1600 1624 1704 1800 900 901 904 1000 108000 flags: phsync, pvsync; type: driver1280x1024 60 1280 1328 1440 1688 1024 1025 1028 1066 108000 flags: phsync, pvsync; type: driver1440x900 60 1440 1520 1672 1904 900 903 909 934 106500 flags: nhsync, pvsync; type: driver1440x900 60 1440 1488 1520 1600 900 903 909 926 88750 flags: phsync, nvsync; type: driver1280x960 60 1280 1376 1488 1800 960 961 964 1000 108000 flags: phsync, pvsync; type: driver1366x768 60 1366 1436 1579 1792 768 771 774 798 85500 flags: phsync, pvsync; type: driver1366x768 60 1366 1380 1436 1500 768 769 772 800 72000 flags: phsync, pvsync; type: driver1360x768 60 1360 1424 1536 1792 768 771 777 795 85500 flags: phsync, pvsync; type: driver1280x800 60 1280 1352 1480 1680 800 803 809 831 83500 flags: nhsync, pvsync; type: driver1280x800 60 1280 1328 1360 1440 800 803 809 823 71000 flags: phsync, nvsync; type: driver1280x768 60 1280 1344 1472 1664 768 771 778 798 79500 flags: nhsync, pvsync; type: driver1280x768 60 1280 1328 1360 1440 768 771 778 790 68250 flags: phsync, nvsync; type: driver1280x720 60 1280 1390 1430 1650 720 725 730 750 74250 flags: phsync, pvsync; type: driver800x600 60 800 840 968 1056 600 601 605 628 40000 flags: phsync, pvsync; type: driver800x600 56 800 824 896 1024 600 601 603 625 36000 flags: phsync, pvsync; type: driver848x480 60 848 864 976 1088 480 486 494 517 33750 flags: phsync, pvsync; type: driver640x480 60 640 656 752 800 480 490 492 525 25175 flags: nhsync, nvsync; type: driverprops:2 DPMS:flags: enumenums: On=0 Standby=1 Suspend=2 Off=3value: 06 link-status:flags: enumenums: Good=0 Bad=1value: 07 non-desktop:flags: immutable rangevalues: 0 1value: 018 CRTC_ID:flags: objectvalue: 0CRTCs:
id fb pos size
28 0 (0,0) (0x0)0 0 0 0 0 0 0 0 0 0 flags: ; type:props:19 ACTIVE:flags: rangevalues: 0 1value: 020 MODE_ID:flags: blobblobs:value:Planes:
id crtc fb CRTC x,y x,y gamma size possible crtcs
27 28 0 0,0 0,0 0 0x00000001formats: XR24props:8 type:flags: immutable enumenums: Overlay=0 Primary=1 Cursor=2value: 117 FB_ID:flags: objectvalue: 018 CRTC_ID:flags: objectvalue: 013 CRTC_X:flags: signed rangevalues: -2147483648 2147483647value: -32014 CRTC_Y:flags: signed rangevalues: -2147483648 2147483647value: -24015 CRTC_W:flags: rangevalues: 0 2147483647value: 64016 CRTC_H:flags: rangevalues: 0 2147483647value: 4809 SRC_X:flags: rangevalues: 0 4294967295value: 010 SRC_Y:flags: rangevalues: 0 4294967295value: 011 SRC_W:flags: rangevalues: 0 4294967295value: 4194304012 SRC_H:flags: rangevalues: 0 4294967295value: 31457280Frame buffers:
id size pitch[root@100ask:/home/tftp]# ./libdrm_test_programs/proptest -M vkms
Connector 30 (Virtual-3)2 DPMS:flags: enumenums: On=0 Standby=1 Suspend=2 Off=3value: 06 link-status:flags: enumenums: Good=0 Bad=1value: 07 non-desktop:flags: immutable rangevalues: 0 1value: 0
CRTC 28[root@100ask:/home/tftp]# ./libdrm_test_programs/vbltest -M vkms
[ 6034.724114] ------------[ cut here ]------------
[ 6034.728862] WARNING: CPU: 0 PID: 441 at drivers/gpu/drm/drm_irq.c:221 drm_update_vblank_count+0x234/0x33c
[ 6034.739209] ---[ end trace 9f17578627c8726f ]---
[ 6034.724114] ------------[ cut here ]------------
[ 6034.728862] WARNING: CPU: 0 PID: 441 at drivers/gpu/drm/drm_irq.c:221 drm_update_vblank_count+0x234/0x33c
[ 6034.738462] Modules linked in: vkms_drv_atomic(O) [last unloaded: vkms_drv]
[ 6034.738538] CPU: 0 PID: 441 Comm: vbltest Tainted: G O 4.9.88 #9
[ 6034.738554] Hardware name: Freescale i.MX6 UltraLite (Device Tree)
[ 6034.738639] [<8010eb90>] (unwind_backtrace) from [<8010b29c>] (show_stack+0x10/0x14)
[ 6034.738702] [<8010b29c>] (show_stack) from [<803c310c>] (dump_stack+0x84/0x98)
[ 6034.738753] [<803c310c>] (dump_stack) from [<8012dd34>] (__warn+0xe8/0x100)
[ 6034.738797] [<8012dd34>] (__warn) from [<8012ddfc>] (warn_slowpath_null+0x20/0x28)
[ 6034.738844] [<8012ddfc>] (warn_slowpath_null) from [<804b20fc>] (drm_update_vblank_count+0x234/0x33c)
[ 6034.738893] [<804b20fc>] (drm_update_vblank_count) from [<804b2840>] (drm_vblank_enable+0xd4/0xdc)
[ 6034.738939] [<804b2840>] (drm_vblank_enable) from [<804b2900>] (drm_vblank_get+0xb8/0xe0)
[ 6034.738985] [<804b2900>] (drm_vblank_get) from [<804b3280>] (drm_wait_vblank+0xc4/0x4bc)
[ 6034.739029] [<804b3280>] (drm_wait_vblank) from [<804b10c0>] (drm_ioctl+0x1f4/0x40c)
[ 6034.739080] [<804b10c0>] (drm_ioctl) from [<80211750>] (do_vfs_ioctl+0x9c/0x924)
[ 6034.739134] [<80211750>] (do_vfs_ioctl) from [<8021200c>] (SyS_ioctl+0x34/0x5c)
[ 6034.739187] [<8021200c>] (SyS_ioctl) from [<80107740>] (ret_fast_syscall+0x0/0x48)
[ 6034.739209] ---[ end trace 9f17578627c8726f ]---
starting count: 2
freq: 60.38Hz #驱动里面设置的帧率
freq: 60.00Hz
freq: 60.00Hz
freq: 60.00Hz
freq: 60.00Hz
freq: 60.00Hz
freq: 60.00Hz
freq: 60.00Hz./libdrm_test_programs/modetest -M vkms -P 27@28:1024x768 #plane 设置测试
testing 1024x768@XR24 overlay plane 27./libdrm_test_programs/modetest -M vkms -s 30@28:1280x720 #set mode测试
setting mode 1280x720-60Hz@XR24 on connectors 30, crtc 28至此基本移植测试完成!!!