hypervisor display显卡节点card0生成过程

news2024/10/5 21:22:50

ditsi 配置

lagvm/LINUX/android/vendor/qcom/proprietary/devicetree/qcom

direwolf-g9ph.dts   #include "direwolf-vm-la.dtsi"
direwolf-vm-la.dtsi #include "display/quin-vm-display-la.dtsi"
quin-vm-display-la.dtsi
//对应/sys/class/drm/card0/device/driver的节点
//dtsi节点层级
//soc:
//qcom,sde-cfg:
//qcom,sde-sub-cfg@0:
//qcom,sde_kms_hyp@ae00000
&soc {
        sde_cfg: qcom,sde-cfg {
                compatible = "qcom,sde-cfg";

                qcom,sde-sub-cfg@0 {
                        reg = <0>;
                        wfd_kms: qcom,wfd_kms@0 {
                                compatible = "qcom,wfd-kms";
                                qcom,client-id = "7815";
                        };

                        qcom,sde_kms_hyp@ae00000 {
                                compatible = "qcom,sde-kms-hyp";
                                qcom,kms = <&wfd_kms>;
                        };
                };

                qcom,sde-sub-cfg@1 {
                        reg = <1>;
                        qcom,sde_kms_hyp@ae00000 {
                                compatible = "qcom,sde-kms-hyp-legacy";
                                qcom,client-id = "7815";
                        };
                };
        };
};

 Makfile 配置

# SPDX-License-Identifier: GPL-2.0-only
//单LA 
# auto-detect subdirs
ifeq (y, $(findstring y, $(CONFIG_ARCH_SA8155) $(CONFIG_ARCH_SA6155) $(CONFIG_ARCH_SA8195)))
include $(srctree)/techpack/display/config/augen3disp.conf
LINUXINCLUDE += -include $(srctree)/techpack/display/config/augen3dispconf.h
LINUXINCLUDE += -I$(srctree)/techpack/display/include \
        -I$(srctree)/techpack/display/include/uapi/display

USERINCLUDE = -I$(srctree)/techpack/display/include/uapi/display
endif
//Q+A  这个CONFIG_QTI_QUIN_GVM宏enable
ifeq (y, $(findstring y, $(CONFIG_QTI_QUIN_GVM)))
include $(srctree)/techpack/display/config/gvmgen3disp.conf
LINUXINCLUDE += -include $(srctree)/techpack/display/config/gvmgen3dispconf.h
endif

//根据config 配置msm-hyp msm-hyp-legacy msm-cfg参与编译
obj-$(CONFIG_DRM_MSM) += msm/
obj-$(CONFIG_DRM_MSM_HYP) += msm-hyp/
obj-$(CONFIG_DRM_MSM_HYP_LEGACY) += msm-hyp-legacy/
obj-$(CONFIG_MSM_SDE_ROTATOR) += rotator/
obj-$(CONFIG_DRM_MSM_CFG) += msm-cfg/

/techpack/display/config/gvmgen3dispconf.h
* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
 */

#define CONFIG_DRM_MSM_HYP 1
#define CONFIG_DRM_MSM_HYP_WFD 1
#define CONFIG_SYNC_FILE 1
#define CONFIG_DRM_MSM_LEASE 1
gvmgen3disp.conf
export CONFIG_DRM_MSM_LEASE=y
export CONFIG_SYNC_FILE=y
export CONFIG_DRM_MSM_HYP_WFD=y
ifeq ($(CONFIG_QGKI), y)
export CONFIG_DRM_MSM_HYP=y
export CONFIG_DRM_MSM_HYP_LEGACY=y
export CONFIG_DRM_MSM_CFG=y
endif

drm设备创建card0 和renderD128

1,前面提到的需要分析的代码中,其实只有红框部分代码有用(msm-cfg&msm-hyp-legacy),绿框中的代码在内核驱动加载的时候只会运行register,而根本不会执行probe函数。

2,绿框中的代码完全不编译也不影响系统运行,这些代码感觉像是历史遗留代码

3,驱动加载时,msm-cfg模块会先加载,然后带起msm-hyp-legacy模块,本质上他们是一个模块,目的是创建android系统需要的drm设备card0 和renderD128,驱动实现中,这两个节点只提供非常有限的文件操作功能,比如open/close,ioctl则几乎不实现。这点在目录下NOTES也说的很明白:

NOTES about msm drm/kms hyp driver:
 
This driver registers with drm framework for the purpose of creating the 
/dev/dri/card0 path, which User Space DRM masters rely on. 
Furthermore, per-CRTC VBLANK and PAGE_FLIP events are queued to the device
path to notify User Space components listeners.
 
No other IOCTL or HW support is provided through this driver.

/*
396   * Platform driver:
397   */
398  
399  static int msm_pdev_probe(struct platform_device *pdev)
400  {
401          struct device *dev = &pdev->dev;
402          struct drm_device *ddev;
403          struct msm_drm_private *priv;
404          int ret;
405  
406          ddev = drm_dev_alloc(&msm_driver, dev);
407          if (!ddev) {
408                  dev_err(dev, "failed to allocate drm_device\n");
409                  return -ENOMEM;
410          }
411  
412          platform_set_drvdata(pdev, ddev);
413  
414          priv = kzalloc(sizeof(*priv), GFP_KERNEL);
415          if (!priv) {
416                  ret = -ENOMEM;
417                  goto priv_alloc_fail;
418          }
419  
420          ddev->dev_private = priv;
421          priv->dev = ddev;
422  
423          ret = drm_dev_register(ddev, 0);
424          if (ret) {
425                  dev_err(dev, "failed to register drm device\n");
426                  goto fail;
427          }
428  
429          return 0;
430  
431  fail:
432  
433  priv_alloc_fail:
434          drm_dev_put(ddev);
435          return ret;
436  }
struct drm_device *drm_dev_alloc(struct drm_driver *driver,
820                                   struct device *parent)
821  {
822          struct drm_device *dev;
823          int ret;
824  
825          dev = kzalloc(sizeof(*dev), GFP_KERNEL);
826          if (!dev)
827                  return ERR_PTR(-ENOMEM);
828  
829          ret = drm_dev_init(dev, driver, parent);
830          if (ret) {
831                  kfree(dev);
832                  return ERR_PTR(ret);
833          }
834  
835          return dev;
836  }
837  EXPORT_SYMBOL(drm_dev_alloc);
int drm_dev_init(struct drm_device *dev,
632                   struct drm_driver *driver,
633                   struct device *parent)
634  {
635          int ret;
636  
637          if (!drm_core_init_complete) {
638                  DRM_ERROR("DRM core is not initialized\n");
639                  return -ENODEV;
640          }
641  
642          BUG_ON(!parent);
643  
644          kref_init(&dev->ref);
645          dev->dev = get_device(parent);
646          dev->driver = driver;
647  
648          /* no per-device feature limits by default */
649          dev->driver_features = ~0u;
650  
651          drm_legacy_init_members(dev);
652          INIT_LIST_HEAD(&dev->filelist);
653          INIT_LIST_HEAD(&dev->filelist_internal);
654          INIT_LIST_HEAD(&dev->clientlist);
655          INIT_LIST_HEAD(&dev->vblank_event_list);
656  
657          spin_lock_init(&dev->event_lock);
658          mutex_init(&dev->struct_mutex);
659          mutex_init(&dev->filelist_mutex);
660          mutex_init(&dev->clientlist_mutex);
661          mutex_init(&dev->master_mutex);
662  
663          dev->anon_inode = drm_fs_inode_new();
664          if (IS_ERR(dev->anon_inode)) {
665                  ret = PTR_ERR(dev->anon_inode);
666                  DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
667                  goto err_free;
668          }
669  
670          if (drm_core_check_feature(dev, DRIVER_RENDER)) {
671                  ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
672                  if (ret)
673                          goto err_minors;
674          }
675         //创建生成card0&render128
676          ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
677          if (ret)
678                  goto err_minors;
679  
680          ret = drm_legacy_create_map_hash(dev);
681          if (ret)
682                  goto err_minors;
683  
684          drm_legacy_ctxbitmap_init(dev);
685  
686          if (drm_core_check_feature(dev, DRIVER_GEM)) {
687                  ret = drm_gem_init(dev);
688                  if (ret) {
689                          DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
690                          goto err_ctxbitmap;
691                  }
692          }
693  
694          ret = drm_dev_set_unique(dev, dev_name(parent));
695          if (ret)
696                  goto err_setunique;
697  
698          return 0;
699  
700  err_setunique:
701          if (drm_core_check_feature(dev, DRIVER_GEM))
702                  drm_gem_destroy(dev);
703  err_ctxbitmap:
704          drm_legacy_ctxbitmap_cleanup(dev);
705          drm_legacy_remove_map_hash(dev);
706  err_minors:
707          drm_minor_free(dev, DRM_MINOR_PRIMARY);
708          drm_minor_free(dev, DRM_MINOR_RENDER);
709          drm_fs_inode_free(dev->anon_inode);
710  err_free:
711          put_device(dev->dev);
712          mutex_destroy(&dev->master_mutex);
713          mutex_destroy(&dev->clientlist_mutex);
714          mutex_destroy(&dev->filelist_mutex);
715          mutex_destroy(&dev->struct_mutex);
716          drm_legacy_destroy_members(dev);
717          return ret;
718  }
719  EXPORT_SYMBOL(drm_dev_init);

112  static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
113  {
114          struct drm_minor *minor;
115          unsigned long flags;
116          int r;
117  
118          minor = kzalloc(sizeof(*minor), GFP_KERNEL);
119          if (!minor)
120                  return -ENOMEM;
121  
122          minor->type = type;
123          minor->dev = dev;
124  
125          idr_preload(GFP_KERNEL);
126          spin_lock_irqsave(&drm_minor_lock, flags);
            //获取次设备号
127          r = idr_alloc(&drm_minors_idr,
128                        NULL,
129                        64 * type,
130                        64 * (type + 1),
131                        GFP_NOWAIT);
132          spin_unlock_irqrestore(&drm_minor_lock, flags);
133          idr_preload_end();
134  
135          if (r < 0)
136                  goto err_free;
137  
138          minor->index = r;
139  
140          minor->kdev = drm_sysfs_minor_alloc(minor);
141          if (IS_ERR(minor->kdev)) {
142                  r = PTR_ERR(minor->kdev);
143                  goto err_index;
144          }
145  
146          *drm_minor_get_slot(dev, type) = minor;
147          return 0;
148  
149  err_index:
150          spin_lock_irqsave(&drm_minor_lock, flags);
151          idr_remove(&drm_minors_idr, minor->index);
152          spin_unlock_irqrestore(&drm_minor_lock, flags);
153  err_free:
154          kfree(minor);
155          return r;
156  }
struct device *drm_sysfs_minor_alloc(struct drm_minor *minor)
386  {
387          const char *minor_str;
388          struct device *kdev;
389          int r;
390  
391          if (minor->type == DRM_MINOR_RENDER)
392                  minor_str = "renderD%d";
393          else
394                  minor_str = "card%d";
395  
396          kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
397          if (!kdev)
398                  return ERR_PTR(-ENOMEM);
399  
400          device_initialize(kdev);
401          kdev->devt = MKDEV(DRM_MAJOR, minor->index);
402          kdev->class = drm_class;
403          kdev->type = &drm_sysfs_device_minor;
404          kdev->parent = minor->dev->dev;
405          kdev->release = drm_sysfs_release;
406          dev_set_drvdata(kdev, minor);
407           //根据次设备号set 设备名
408          r = dev_set_name(kdev, minor_str, minor->index);
409          if (r < 0)
410                  goto err_free;
411  
412          return kdev;
413  
414  err_free:
415          put_device(kdev);
416          return ERR_PTR(r);
417  }

创建dbuggfs 节点

根据DRM_MINOR_PRIMARY DRM_MINOR_PRIMARY

使用次设备号创建card0 和renderD128 debug节点

使用命令mount debugfs 后可以看到debug 节点

mount -t debugfs none /sys/kernel/debug/

 /**
941   * drm_dev_register - Register DRM device
942   * @dev: Device to register
943   * @flags: Flags passed to the driver's .load() function
944   *
945   * Register the DRM device @dev with the system, advertise device to user-space
946   * and start normal device operation. @dev must be initialized via drm_dev_init()
947   * previously.
948   *
949   * Never call this twice on any device!
950   *
951   * NOTE: To ensure backward compatibility with existing drivers method this
952   * function calls the &drm_driver.load method after registering the device
953   * nodes, creating race conditions. Usage of the &drm_driver.load methods is
954   * therefore deprecated, drivers must perform all initialization before calling
955   * drm_dev_register().
956   *
957   * RETURNS:
958   * 0 on success, negative error code on failure.
959   */
960  int drm_dev_register(struct drm_device *dev, unsigned long flags)
961  {
962          struct drm_driver *driver = dev->driver;
963          int ret;
964  
965          mutex_lock(&drm_global_mutex);
966  
967          ret = drm_minor_register(dev, DRM_MINOR_RENDER);
968          if (ret)
969                  goto err_minors;
970  
971          ret = drm_minor_register(dev, DRM_MINOR_PRIMARY);
972          if (ret)
973                  goto err_minors;
974  
975          ret = create_compat_control_link(dev);
976          if (ret)
977                  goto err_minors;
978  
979          dev->registered = true;
980  
981          if (dev->driver->load) {
982                  ret = dev->driver->load(dev, flags);
983                  if (ret)
984                          goto err_minors;
985          }
986  
987          if (drm_core_check_feature(dev, DRIVER_MODESET))
988                  drm_modeset_register_all(dev);
989  
990          ret = 0;
991  
992          DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
993                   driver->name, driver->major, driver->minor,
994                   driver->patchlevel, driver->date,
995                   dev->dev ? dev_name(dev->dev) : "virtual device",
996                   dev->primary->index);
997  
998          goto out_unlock;
999  
1000  err_minors:
1001          remove_compat_control_link(dev);
1002          drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
1003          drm_minor_unregister(dev, DRM_MINOR_RENDER);
1004  out_unlock:
1005          mutex_unlock(&drm_global_mutex);
1006          return ret;
1007  }
1008  EXPORT_SYMBOL(drm_dev_register);

static int drm_minor_register(struct drm_device *dev, unsigned int type)179  {
180          struct drm_minor *minor;
181          unsigned long flags;
182          int ret;
183  
184          DRM_DEBUG("\n");
185  
186          minor = *drm_minor_get_slot(dev, type);
187          if (!minor)
188                  return 0;
189  
190          ret = drm_debugfs_init(minor, minor->index, drm_debugfs_root);
191          if (ret) {
192                  DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n");
193                  goto err_debugfs;
194          }
195  
196          ret = device_add(minor->kdev);
197          if (ret)
198                  goto err_debugfs;
199  
200          /* replace NULL with @minor so lookups will succeed from now on */201          spin_lock_irqsave(&drm_minor_lock, flags);
202          idr_replace(&drm_minors_idr, minor, minor->index);
203          spin_unlock_irqrestore(&drm_minor_lock, flags);
204  
205          DRM_DEBUG("new minor registered %d\n", minor->index);
206          return 0;
207  
208  err_debugfs:
209          drm_debugfs_cleanup(minor);
210          return ret;
211  }

【1】参考连接 https://blog.csdn.net/kill150/article/details/131323757icon-default.png?t=N7T8https://blog.csdn.net/kill150/article/details/131323757

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1320291.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试面试八股文(超详细整理)

请你说一说测试用例的边界 参考回答&#xff1a; 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充&#xff0c;这种情况下&#xff0c;其测试用例来自等价类的边界。 常见的边界值 1)对16-bit 的整数而言 32…

Python纯净式下载与安装

1. 下载 Download Python | Python.org 建议下老版本些的&#xff0c;毕竟求稳。 点击需要的版本&#xff0c;然后滑倒最下面&#xff0c;可以看到不同系统对应的下载选项&#xff1a; 2. 安装 如果下载慢的话&#xff0c;可以复制链接到迅雷下载&#xff0c;下载完成后&…

Docker部署MinIO对象存储服务器结合内网穿透实现远程访问

文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器&#xff0c;可以在各种环境中运行&#xff0c;例如本地、Docker容器、Kubernetes集群等。它兼…

人工智能革命:共同探索AIGC时代的未来

一、引言 随着大数据和强大的计算能力的兴起&#xff0c;人工智能技术&#xff08;AI&#xff09;正在快速发展&#xff0c;并为各个领域带来革命性的变化。人工智能与智能计算技术&#xff08;AIGC&#xff09;的融合不仅为企业、科研机构和普通用户提供了巨大的机遇&#xff…

【算法题】 TLV解析 Ⅱ (js)

从第三个字节开始因此 const msg "0F04ABABABAB"; const msg1 "0F04ABABABAB10001FF"; function solution(msg, tags) {const tagObj {};for (let i 0; i 3 < msg.length; ) {const tag parseInt(msg.slice(i, i 2), 16);const len parseInt(m…

漏洞复现--SysAid On-premise远程代码执行(CVE-2023-47246)

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

Unity3D对TXT文件的操作

系列文章目录 Unity工具 文章目录 系列文章目录前言一、读取txt文档1-1、TextAsset类读取1-2、代码实现1-2、打印结果 二、使用File类读取2-1.使用ReadAllText读取代码如下&#xff1a;2-2、结果如下2-3、使用ReadAllLines读取代码如下&#xff1a;2-4、读取结果 三、文件流读…

【深度学习】序列生成模型(二):束搜索

文章目录 序列生成束搜索理论基础算法步骤python实现 序列生成 在进行最大似然估计训练后的模型 p θ ( x ∣ x 1 : ( t − 1 ) ) p_\theta(x | \mathbf{x}_{1:(t-1)}) pθ​(x∣x1:(t−1)​)&#xff0c;我们可以使用该模型进行序列生成。生成的过程是按照时间顺序逐步生成序…

adb: error: cannot create file/directory ‘d:/1.png‘: No such file or directory

将文件从设备读取到PC 由于权限问题&#xff0c;不能直接pull到电脑磁盘根目录&#xff0c;否则会报错&#xff1a; adb pull <remote> <local> eg: C:\Users\admin>adb pull /sdcard/server.log C:\Users\admin\Desktop /sdcard/server.log: 1 file pulled.…

LeedCode刷题---二分查找类问题

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、二分查找 题目链接&#xff1a;二分查找 题目描述 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一…

基于STC89C51单片机实现的森林防火系统源码+仿真+原理图+设计报告,含视频讲解

森林防火 摘要 森林防火是非常必要的,火灾对森林的破坏是具有毁灭性的,有着很大的危害,在春秋季节森林火灾高发期,若发生火灾,对人民生活带来极大危害,不仅危害人们生产生活,而且对地球环境产生影响.本课题研究的内容是以单片机STC89C51为控制核心&#xff0c;以MQ-2型半导体电…

Android hilt使用

一&#xff0c;添加依赖库 添加依赖库app build.gradle.kts implementation("com.google.dagger:hilt-android:2.49")annotationProcessor("com.google.dagger:hilt-android:2.49")annotationProcessor("com.google.dagger:hilt-compiler:2.49"…

关于前端学习的思考-浮动元素嵌套块级元素12.18

1、块级元素嵌套浮动元素 先摆图片&#xff0c;当橘色的盒子高度减少的时候&#xff0c;NK AD TB PK NN并不会减少。如何解决呢&#xff1f; 加一个overflow&#xff1a;clip或者hidden 2、浮动元素嵌套块级元素 加一个overflow&#xff1a;clip或者hidden 综上所述&#xff0…

2020 年网络安全应急响应分析报告

2020 年全年奇安信集团安服团队共参与和处置了全国范围内 660起网络安全应急响应事件。2020 年全年应急响应处置事件行业 TOP3 分别为:政府部门行业(146 起)医疗卫生行业(90 起)以及事业单位(61 起&#xff0c;事件处置数分别占应急处置所有行业的 22.1%、13.6%、9.2%。2020 年…

修改npm源码解决服务端渲染环境中localstorage报错read properties of undefined (reading getItem)

现象&#xff1a; 这个问题是直接指向了我使用的第三方库good-storage&#xff0c;这是一个对localStorage/sessionStorage做了简单封装的库&#xff0c;因为项目代码有一个缓存cache.ts有用到 原因分析&#xff1a; 从表象上看是storage对象找不到getItem方法&#xff0c; 但…

Vue3使用Three.js导入gltf模型并解决模型为黑色的问题

背景 如今各类数字孪生场景对三维可视化的需求持续旺盛&#xff0c;因为它们可以用来创建数字化的双胞胎&#xff0c;即现实世界的物体或系统的数字化副本。这种技术在工业、建筑、医疗保健和物联网等领域有着广泛的应用&#xff0c;可以帮助人们更好地理解和管理现实世界的事…

Selenium框架的使用心得(一)

最近使用selenium框架实现业务前端的UI自动化&#xff0c;在使用selenium时&#xff0c;有一些心得想要和大家分享一下~ Selenium是一款用于web应用程序测试的工具&#xff0c;常用来实现稳定业务的UI自动化。这里&#xff0c;不想对其发展历史做介绍&#xff0c;也不想用官方…

EXCEL SUM类函数

参考资料 万能函数SUMPRODUCT超实用的10种经典用法 目录 一. SUM二. SUMIF2.1 统计贾1的销售额2.2 > 900 的销售总额2.3 计算贾1和贾22的销售总额2.4 多区域计算 三. SUMIFS3.1 统计苹果&#xff0c;在第一季度的总数量3.2 统计苹果&#xff0c;在第一季度&#xff0c;>…

智能家居和智能家居控制设备有什么区别?

智能家居和智能家居控制设备在功能和用途伤的区别&#xff1a; 智能家居是一种整体的概念&#xff0c;它涵盖了整个家庭环境的智能化&#xff0c;包括智能家电、智能照明、智能安防等设备的互联互通和协同工作。智能家居的目标是通过中央控制器或智能音箱等设备&#xff0c;实现…

Python内置函数一览表

为了提高程序员的开发效率&#xff0c;Python 提供了很多可以直接拿来用的函数&#xff08;初学者可以先理解为方法&#xff09;&#xff0c;每个函数都可以帮助程序员实现某些具体的功能。 举个例子&#xff0c;在 Python 2.x 中 print 只是一个关键字&#xff0c;但在 Pytho…