DRM(1) -- DRM internals

DRM Internals Driver Initialization driver 首先需要静态初始化一个 struct drm_driver 结构体,然后调用 drm_dev_alloc() 来 创建一个 struct drm_device 结构体,初始化必要的 fields 后,最后调用 drm_dev_register() 注册 drm_device. Driver Information 在 struct drm_driver 结构体中的.major, .minor, .patchlevel, .name, .desc .date 字段用于描述 driver 的基本信息。 通过 DRM_IOCTL_VERSION 和 DRM_IOCTL_SET_VERSION 两个 ioctl 可以获取和设置 driver 基本信息。 Module Initialization 在 drm_module.h 中提供了一些封装的 api 来注册 module platform/pci driver: drm_module_pci_driver(__pci_drv); drm_module_platform_driver(__platform_drv); Device Instance and Driver Handling 这里有一个 driver 的 template, 具体查看官方文档。 如果需要支持热插拔 drm 设备,比如 USB, DT overlay unload, 需要使用 drm_dev_unplug() 代替 drm_dev_unregister()....

2025-04-15 · 5 min

DRM(11) -- Bridge

Overview struct drm_bridge 代表挂在 encoder 后面的设备。当 drm_encoder 不能完全代表整个 encoder chain 的时候, drm_bridge 就有用了。 Encoder –> Bridge A –> Bridge B drm bridge 和 drm panel 一样,不是 drm_mode_object, 对 userspace 是不可见的。他们只是用来提供额外的 hooks 来得到 encoder chain 最终的理想输出。 Display driver 负责把 encoder link 到第一个 bridge,通过devm_drm_of_get_bridge()获取 bridge,再通过drm_bridge_attach()将 bridge attach 到 encoder 上。 Bridge driver 负责把自己 link 到下一级 bridge,通过在 drm_bridges_funcs.attach 中调用drm_bridge_attach()。 最后一级 Bridge driver 还参与实现 drm connector, 通过drm_bridge_connector_init() helper 来创建 drm_connector. 或者通过 bridge 暴露出来的 connector 相关操作函数来手动实现 connector....

2025-04-15 · 4 min

V4L2 -- ioctl

ioctls 根据 determine_valid_ioctls() 函数,video rx 设备支持的 ioctl 有: VIDIOC_QUERYCAP // 要定义 ops->vidioc_querycap VIDIOC_G_PRIORITY VIDIOC_S_PRIORITY VIDIOC_G_FREQUENCY // ops->vidioc_g_frequency VIDIOC_S_FREQUENCY // ops->vidioc_s_frequency VIDIOC_LOG_STATUS // ops->vidioc_log_status VIDIOC_DQEVENT // ops->vidioc_subscribe_event VIDIOC_SUBSCRIBE_EVENT // ops->vidioc_subscribe_event VIDIOC_UNSUBSCRIBE_EVENT // ops->vidioc_unsubscribe_event 在定义了 vdev->ctrl_handler 的情况下: VIDIOC_QUERYCTRL // ops->vidioc_queryctrl VIDIOC_QUERY_EXT_CTRL // ops->vidioc_query_ext_ctrl VIDIOC_G_CTRL // ops->vidioc_g_ctrl || ops->vidioc_g_ext_ctrls VIDIOC_S_CTRL // ops->vidioc_s_ctrl || ops->vidioc_s_ext_ctrls VIDIOC_G_EXT_CTRLS // ops->vidioc_g_ext_ctrls VIDIOC_S_EXT_CTRLS // ops->vidioc_s_ext_ctrls VIDIOC_TRY_EXT_CTRLS // ops->vidioc_try_ext_ctrls VIDIOC_QUERYMENU // ops->vidioc_querymenu VIDIOC_ENUM_FMT // ops->vidioc_enum_fmt_vid_cap || ops->vidioc_enum_fmt_vid_overlay VIDIOC_G_FMT // vidioc_g_fmt_vid_cap || vidioc_g_fmt_vid_cap_mplane || vidioc_g_fmt_vid_overlay VIDIOC_S_FMT // 同上 VIDIOC_TRY_FMT // 同上 VIDIOC_OVERLAY VIDIOC_G_FBUF VIDIOC_S_FBUF VIDIOC_G_JPEGCOMP VIDIOC_S_JPEGCOMP VIDIOC_G_ENC_INDEX VIDIOC_ENCODER_CMD VIDIOC_TRY_ENCODER_CMD VIDIOC_DECODER_CMD VIDIOC_TRY_DECODER_CMD VIDIOC_ENUM_FRAMESIZES VIDIOC_ENUM_FRAMEINTERVALS VIDIOC_G_CROP // vidioc_g_selection VIDIOC_CROPCAP // // vidioc_g_selection VIDIOC_S_CROP // vidioc_s_selection VIDIOC_G_SELECTION VIDIOC_S_SELECTION VIDIOC_REQBUFS VIDIOC_QUERYBUF VIDIOC_QBUF VIDIOC_EXPBUF VIDIOC_DQBUF VIDIOC_CREATE_BUFS VIDIOC_PREPARE_BUF VIDIOC_STREAMON VIDIOC_STREAMOFF VIDIOC_ENUMSTD VIDIOC_S_STD VIDIOC_G_STD VIDIOC_QUERYSTD Video for Linux API static void rtsisp_hw_free_vreg(struct rtsisp_dev_info *dev_info) { struct rtsisp_hw *hw = dev_info->hw; struct rtsisp_dev_hw_info *hw_info = &hw->hw_info[dev_info->dev_id]; if (hw_info->vregs) { vfree(hw_info->vregs); hw_info->vregs = NULL; } if (hw->dev_num == 1 && hw->vregs_bitmap) { bitmap_free(hw->vregs_bitmap); hw->vregs_bitmap = NULL; } } 1....

2025-03-26 · 7 min

xv6_lecture2 C in xv6

经典的一道指针和数组题: 假设 x 的地址为 0x7fffdfbf7f00, 打印出来的值分别是多少? #include <stdio.h> int main() { int x[5]; printf("%p\n", x); printf("%p\n", x+1); printf("%p\n", &x) printf("%p\n", &x+1); return 0; } 0x7fffdfbf7f00 # 打印的数组的地址 0x7fffdfbf7f04 # 打印的是数组第二个元素的地址 0x7fffdfbf7f00 # &x也是数组的地址 0x7fffdfbf7f14 # x + sizeof(x)的地址

2024-12-26 · 1 min

DRM(13) -- Memory Management

Introduction DRM 核心包括两个内存管理器,分别是 Translation Table Manager(TTM) 和 Graphics Execution Manager(GEM). TTM 是第一个被开发的 DRM 内存管理器。它提供了一个单一的用户空间 API 来满足所有硬件的需求,支持统一内存体系结构 (Unified Memory Architecture,UMA) 设备和具有专用视频 RAM (即大多数离散显卡) 的设备。这导致了一大段复杂的代码,结果很难用于驱动程序开发。 由于 TTM 的复杂性,GEM 最初是由英特尔 (Intel) 赞助的一个项目。GEM 没有提供每个图形内存相关问题的解决方案,而是确定了驱动程序之间的公共代码,并创建了一个支持库来共享它。GEM 的初始化和执行要求比 TTM 简单,但没有视频 RAM 管理功能,因此仅限于 UMA 设备。 GEM Initialization 在 struct drm_driver driver feature 中设置 DRIVER_GEM bit. 中间层会自动调用drm_gem_init()来完成 GEM 的初始化。 GEM Objects Creation GEM object 由结构体 struct drm_gem_object表示,通过drm_gem_oject_init()初始化,利用 shmem 来分配 anonymous pageable memory. 如果 hardware 需要 physical contiguous system memory(通常是嵌入式设备需求), 那么可以不需要使用 shmem, 而是通过drm_gem_private_object_init()初始化。...

2024-12-10 · 3 min

Professional CMake: A Practical Guide Part III The Bigger Picture

Chapter 23. Finding Things 中等规模以上的项目除了本身的项目之外, 可能还依赖于其他东西. 比如 a particular library or tool, location of a specific configuration file or a header for a library. 甚至项目可能需要找一个 package, 其中定义了一系列内容, 包括 targets, functions, variables… find_...命令提供了搜索 file、library 或 progaram,甚至 package 的能力. 23.1 Finding Files and Paths find_file(outVar name | NAMES name1 [name2...] [HINTS path1 [path2...] [ENV var]...] [PATHS path1 [path2...] [ENV var]...] [PATH_SUFFIXES suffix1 [suffix2 ...]] [NO_DEFAULT_PATH] [NO_PACKAGE_ROOT_PATH] [NO_CMAKE_PATH] [NO_CMAKE_ENVIRONMENT_PATH] [NO_SYSTEM_ENVIRONMENT_PATH] [NO_CMAKE_SYSTEM_PATH] [CMAKE_FIND_ROOT_PATH_BOTH | ONLY_CMAKE_FIND_ROOT_PATH | NO_CMAKE_FIND_ROOT_PATH] [DOC "description"] ) 搜索顺序按如下表格:...

2024-11-30 · 5 min

Professional CMake: A Practical Guide Part II Builds In Depth

Chapter 13. Build Type 13.1 Build Type Basics cmake 有以下几种 build type, 不同的 tpye 会导致 compiler 和 linker flags 不同: Debug: no optimization and full debug information. Release: typically full optimization and no debug information. RelWithDebInfo: 有优化 + debug info. MinRizeRel: 优化 size. 13.1.1 Single Configuration Generators 像 make, ninja, 每个 build directory 只支持一种 build type, 需要在编译时指定 cache variable CMAKE_BUILD_TYPE: cmake -G Ninja -DCMAKE_BUILD_TYPE:STRING=Debug ../source cmake --build . 一种可能的文件布局方式: 13.1.2 Multiple Configuration Generators 类似 Xcode and Visual Studio, 不关注, 跳过....

2024-11-29 · 13 min

Professional CMake: A Practical Guide Part I Fundamentals

Reference Professional CMake A Practical Guide version 1.0.0 2018 年出版, 基于 cmake 3.12 版本(2018-7-17). 目前该书出到了 19th Edition, 支持到 cmake 3.30, 不断更新中. Chapter 1. Introduction From Wikipedia: CMake is a free, cross-platform, software development tool for building applications via compiler-independent instructions. It also can automate testing, packaging and installation. It runs on a variety of platforms and supports many programming languages. Build 部分由其他不同的 build tool 负责, 比如 make, ninja, Visual Studio, XCode…...

2024-11-20 · 14 min

GNU Linker Script

Reference 官方文档: https://sourceware.org/binutils/docs/ld.pdf 2. Invocation 讲了 command line ld 的各种选项。 3. Linker Script 3.1 Basic Linker Script Concepts loadable section and allocatable section A section may be marked as loadable, which means that the contents should be loaded into memory when the output file is run. A section with no contents may be allocatable, which means that an area in memory should be set aside, but nothing in particular should be loaded there (in some cases this memory must be zeroed out)....

2024-11-12 · 3 min

DRM(12) -- Panel

Panel and Bridge 对于 dpi, mipi dsi connector, DRM core 提供了 struct drm_panel 来简化流程。 情况 1:设备树存在 panel 节点 imx6ull-dhcom-pdk2.dts 中的存在 panel 节点,对应 panel-simple.c: &lcdif { status = "okay"; port { display_out: endpoint { remote-endpoint = <&panel_in>; }; }; }; panel { compatible = "auo,g101evn010"; power-supply = <&ldo4_ext>; backlight = <&lcd_backlight>; port { panel_in: endpoint { remote-endpoint = <&display_out>; }; }; }; 这种情况比较简单,在底层 driver 中调用drm_of_find_panel_or_bridge找到设备树中的 panel 节点,和 panel driver 匹配,找到 panel driver 注册的 drm_panel 结构体。...

2024-10-15 · 3 min