当前位置: 首页 > news >正文

MTK Linux DRM分析(三)- drm_drv.c分析

Linux DRM (Direct Rendering Manager) 子系统是内核图形框架的核心,drm_drv.c 文件负责 DRM 设备的注册、初始化和注销等通用驱动逻辑。它不直接实现 plane、CRTC、connector 或 encoder 的具体功能,这些功能分别在 drm_plane.c、drm_crtc.c、drm_connector.c 和 drm_encoder.c 中定义。drm_drv.c 通过调用 drm_mode_config.c 中的辅助函数(如 drm_mode_config_reset 和 drm_mode_config_cleanup)来间接调用这些文件中的函数。

调用关系主要发生在 DRM 设备注册 (drm_dev_register) 和注销 (drm_dev_unregister) 过程中。这些调用通常是间接的:

  • 直接调用:drm_drv.c 会直接调用 drm_connector.c 中的函数(如 drm_connector_register_all)。
  • 间接调用:通过 drm_mode_config.c 的函数循环遍历 plane、CRTC、encoder 和 connector 列表,调用各自文件中的函数或驱动提供的回调函数(funcs,如 reset、disable_plane、destroy 等)。这些 funcs 由硬件驱动实现,但结构体(如 struct drm_plane、struct drm_crtc 等)定义在相应文件中。
  • drm_drv.c 本身不直接初始化 plane 等组件;这是由硬件驱动在 probe/load 阶段调用 drm_plane_init_new、drm_crtc_init_new、drm_encoder_init 和 drm_connector_init 等函数完成的(这些 init 函数分别在 drm_plane.c、drm_crtc.c、drm_encoder.c 和 drm_connector.c 中定义)。
主要函数分析
  • drm_dev_register (drm_drv.c): 注册 DRM 设备到系统。调用 drm_mode_config_reset 重置模式配置,调用 drm_connector_register_all 注册所有 connector。
  • drm_dev_unregister (drm_drv.c): 注销 DRM 设备。调用 drm_mode_config_cleanup 清理模式配置。
  • 其他函数如 drm_dev_alloc/drm_dev_init 用于分配设备结构体,但不涉及直接调用目标文件。

分析方法

  1. 主要函数识别
    • drm_drv.c 的核心函数包括设备初始化(drm_dev_init、devm_drm_dev_alloc)、注册(drm_dev_register)、注销(drm_dev_unregister)等。
    • 这些函数通过调用 drm_mode_config.c 和其他文件(如 drm_connector.c)中的函数,间接或直接与 drm_plane.c、drm_crtc.c、drm_connector.c 和 drm_encoder.c 交互。
  2. 调用路径
    • 直接调用:drm_dev_register 直接调用 drm_modeset_register_all(drm_mode_config.c),后者调用 drm_connector.c 中的 drm_connector_register_all。
    • 间接调用:通过 drm_mode_config.c 的循环函数(如 drm_for_each_plane、drm_for_each_crtc 等),调用 drm_plane.c、drm_crtc.c 等中的函数。
    • 回调调用:通过硬件驱动提供的 funcs 结构体(如 struct drm_plane_funcs、struct drm_crtc_funcs 等),调用硬件驱动实现的函数,这些结构体的定义在 drm_plane.c、drm_crtc.c 等文件中。
  3. 调用图生成
    • 以下图表以 drm_drv.c 中的函数为起点,展示其如何调用到目标文件。
    • 箭头表示调用方向,括号中注明调用类型(直接、间接或回调)及目标文件
drm_drv.c
|
+-- drm_dev_init (初始化 DRM 设备)|+-- drmm_add_action (drm_managed.c, 直接调用, 注册释放回调)|+-- drm_dev_init_release (drm_drv.c, 回调)|+-- drm_fs_inode_free (drm_drv.c, 直接调用)+-- drm_legacy_ctxbitmap_cleanup (drm_legacy.h, 直接调用)+-- drm_legacy_remove_map_hash (drm_legacy.h, 直接调用)
|
+-- devm_drm_dev_init (设备初始化,devres 管理)|+-- drm_dev_init (drm_drv.c, 直接调用)+-- devm_add_action_or_reset (driver core, 直接调用)|+-- devm_drm_dev_init_release (drm_drv.c, 回调)|+-- drm_dev_put (drm_drv.c, 直接调用)|+-- drm_dev_release (drm_drv.c, 回调)|+-- drm_managed_release (drm_managed.c, 直接调用)
|
+-- drm_dev_register (注册 DRM 设备)|+-- drm_mode_config_validate (drm_mode_config.c, 直接调用, 如果 !driver->load)+-- drm_minor_register (drm_drv.c, 直接调用, 注册 PRIMARY 和 RENDER minor)+-- create_compat_control_link (drm_drv D.c, 直接调用)+-- drm_modeset_register_all (drm_mode_config.c, 直接调用, 如果 DRIVER_MODESET)|+-- drm_mode_config_reset (drm_mode_config.c, 直接调用)|+-- drm_for_each_plane (drm_mode_config.c, 间接调用)|+-- plane->funcs->reset (回调, struct drm_plane 定义在 drm_plane.c)+-- drm_for_each_crtc (drm_mode_config.c, 间接调用)|+-- crtc->funcs->reset (回调, struct drm_crtc 定义在 drm_crtc.c)+-- drm_for_each_encoder (drm_mode_config.c, 间接调用)|+-- encoder->funcs->reset (回调, struct drm_encoder 定义在 drm_encoder.c)+-- drm_for_each_connector (drm_mode_config.c, 间接调用)|+-- connector->funcs->reset (回调, struct drm_connector 定义在 drm_connector.c)|+-- drm_connector_register_all (drm_connector.c, 直接调用)|+-- drm_for_each_connector (drm_mode_config.c, 间接调用)|+-- drm_connector_register (drm_connector.c, 直接调用)|+-- connector->funcs->late_register (回调, struct drm_connector 定义在 drm_connector.c)+-- driver->load (回调, 硬件驱动实现, 如果存在)
|
+-- drm_dev_unregister (注销 DRM 设备)|+-- drm_lastclose (drm_file.c, 直接调用, 如果 DRIVER_LEGACY)+-- drm_client_dev_unregister (drm_client.c, 直接调用)+-- drm_modeset_unregister_all (drm_mode_config.c, 直接调用, 如果 DRIVER_MODESET)|+-- drm_mode_config_cleanup (drm_mode_config.c, 直接调用)|+-- drm_for_each_plane (drm_mode_config.c, 间接调用)|+-- drm_plane_force_disable (drm_plane.c, 直接调用)|+-- plane->funcs->disable_plane (回调, struct drm_plane 定义在 drm_plane.c)+-- drm_plane_cleanup (drm_plane.c, 直接调用)|+-- plane->funcs->destroy (回调, struct drm_plane 定义在 drm_plane.c)+-- drm_for_each_crtc (drm_mode_config.c, 间接调用)|+-- drm_crtc_cleanup (drm_crtc.c, 直接调用)|+-- crtc->funcs->destroy (回调, struct drm_crtc 定义在 drm_crtc.c)+-- drm_for_each_encoder (drm_mode_config.c, 间接调用)|+-- drm_encoder_destroy_internal (drm_encoder.c, 直接调用)|+-- encoder->funcs->destroy (回调, struct drm_encoder 定义在 drm_encoder.c)+-- drm_for_each_connector (drm_mode_config.c, 间接调用)|+-- drm_connector_cleanup (drm_connector.c, 直接调用)|+-- connector->funcs->destroy (回调, struct drm_connector 定义在 drm_connector.c)+-- drm_legacy_pci_agp_destroy (drm_legacy.h, 直接调用, 如果 DRIVER_LEGACY)+-- drm_legacy_rmmaps (drm_legacy.h, 直接调用)+-- remove_compat_control_link (drm_drv.c, 直接调用)+-- drm_minor_unregister (drm_drv.c, 直接调用, 注销 PRIMARY 和 RENDER minor)+-- driver->unload (回调, 硬件驱动实现, 如果存在)
|
+-- drm_dev_put (释放 DRM 设备引用)|+-- drm_dev_release (drm_drv.c, 回调)|+-- driver->release (回调, 硬件驱动实现, 如果存在)+-- drm_managed_release (drm_managed.c, 直接调用)

详细说明

  1. drm_dev_init
    • 初始化 DRM 设备结构体,设置引用计数、互斥锁、资源列表等。
    • 调用 drm_minor_alloc 分配 primary 和 render minor 设备。
    • 如果支持 GEM(DRIVER_GEM),调用 drm_gem_init(drm_gem.c)。
    • 注册释放回调 drm_dev_init_release,清理匿名 inode 和 legacy 资源。
    • 不直接调用 drm_plane.c 等文件,plane/CRTC 等初始化由硬件驱动在 probe 阶段调用(如 drm_plane_init_new)。
  2. drm_dev_register
    • 核心注册函数,调用 drm_minor_register 注册 minor 设备。
    • 如果支持 modesetting(DRIVER_MODESET),调用 drm_modeset_register_all,后者调用:
      • drm_mode_config_reset:通过 drm_for_each_* 循环,调用 reset 回调(定义在 drm_plane.c、drm_crtc.c 等)。
      • drm_connector_register_all:直接调用 drm_connector.c 的注册函数。
    • 如果驱动定义了 driver->load,调用硬件驱动的 load 函数(通常初始化硬件特定资源)。
  3. drm_dev_unregister
    • 注销设备,逆转注册过程。
    • 调用 drm_modeset_unregister_all,后者调用 drm_mode_config_cleanup,清理 plane、CRTC、encoder 和 connector:
      • drm_plane.c:调用 drm_plane_force_disable 和 drm_plane_cleanup。
      • drm_crtc.c:调用 drm_crtc_cleanup。
      • drm_encoder.c:调用 drm_encoder_destroy_internal。
      • drm_connector.c:调用 drm_connector_cleanup。
    • 每个清理函数可能触发硬件驱动提供的 destroy 回调。
  4. drm_dev_put
    • 减少引用计数,若计数为零,调用 drm_dev_release,触发 drm_managed_release 和 driver->release(如果存在)。
    • 不直接涉及 drm_plane.c 等,但释放过程可能间接清理相关资源。
  5. 与目标文件的交互
    • drm_plane.c:通过 drm_mode_config_reset(reset 回调)和 drm_mode_config_cleanup(disable_plane 和 destroy 回调)调用。
    • drm_crtc.c:通过 drm_mode_config_reset(reset 回调)和 drm_mode_config_cleanup(destroy 回调)调用。
    • drm_encoder.c:通过 drm_mode_config_reset(reset 回调)和 drm_mode_config_cleanup(destroy 回调)调用。
    • drm_connector.c:直接调用 drm_connector_register_all 和 drm_connector_cleanup,以及通过 drm_mode_config_reset(reset 回调)调用。
    • 硬件驱动提供的 funcs(如 struct drm_plane_funcs)定义在这些文件中,但实现由驱动提供。

http://www.dtcms.com/a/341645.html

相关文章:

  • 【智能体记忆】记忆如何塑造我们:深入探究记忆的类型
  • yolov8检测实时视频流,裁剪出未戴头盔的头部方案
  • HarmonyOS相对布局 (RelativeContainer) 基本概念
  • ODPS 十五周年实录 | 为 AI 而生的数据平台
  • 大数据毕业设计选题推荐-基于Hadoop的电信客服数据处理与分析系统-Spark-HDFS-Pandas
  • 文本智能抽取:如何用NLP从海量文本中“炼“出真金?-告别无效阅读,让AI成为你的“信息炼金师
  • OceanBase DBA实战营2期--SQL 关键字限流学习笔记
  • ae复制合成后修改里面图层相互影响问题
  • uos(类linux)系统 打印机自定义打印尺寸
  • MySQL分库分表与MyCAT
  • open webui源码分析5-Tools
  • 基于单片机水质检测系统/污水监测系统/水情监测
  • ansible中roles角色是什么意思?
  • 详解flink table api基础(三)
  • 【网络】使用 DNAT 进行负载均衡时,若未配置配套的 SNAT,回包失败
  • 猫头虎开源AI分享|基于大模型和RAG的一款智能text2sql问答系统:SQLBot(SQL-RAG-QABot),可以帮你用自然语言查询数据库
  • Three.js 初级教程大全
  • 分享|财务大数据实验室建设方案
  • 机器学习(Machine Learning, ML)
  • Web网站的运行原理2
  • Ubuntu实现程序开机自动运行
  • AI每日需求进度分析总结(附实战操作)
  • 云原生环境下的ITSM新趋势:从传统运维到智能化服务管理
  • 政务网站与新媒体自查情况的报告怎么写?
  • 【ssh】ssh免密登录配置【docker】
  • STM32_0001 KEILMDK V5.36 编译一个STM32F103C8T6说core_cm3.h文件找不到以及编译器版本不匹配的解决办法
  • 25_基于深度学习的行人检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • 详解ThreadLocal<HttpServletRequest> requestThreadLocal
  • Kernel Study
  • 关联规则挖掘1:Apriori算法