V4L2 -- Video Device

2.2 Structure of a V4L driver device instances | +-sub-device instances | \-V4L2 device nodes | \-filehandle instances 2.4 Video device video device 用于抽象系统注册的 v4l2 /dev 设备节点,以便用户空间可以进行交互。 可以通过 video_device_alloc() 分配,也可以嵌入在更大的结构体中,这样则需要自定义 release 函数。 如果是嵌入在更大的结构体中,并且没有要释放的资源,可以使用 video_device_release_empty()。 最后通过 video_register_device() 注册。 struct video_device { #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity entity; struct media_intf_devnode *intf_devnode; struct media_pipeline pipe; #endif const struct v4l2_file_operations *fops; u32 device_caps; /* sysfs */ struct device dev; struct cdev *cdev; struct v4l2_device *v4l2_dev; struct device *dev_parent; struct v4l2_ctrl_handler *ctrl_handler; struct vb2_queue *queue; struct v4l2_prio_state *prio; /* device info */ char name[64]; enum vfl_devnode_type vfl_type; enum vfl_devnode_direction vfl_dir; int minor; u16 num; unsigned long flags; int index; /* V4L2 file handles */ spinlock_t fh_lock; struct list_head fh_list; int dev_debug; v4l2_std_id tvnorms; /* callbacks */ void (*release)(struct video_device *vdev); const struct v4l2_ioctl_ops *ioctl_ops; DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); struct mutex *lock; }; entity:...

2025-06-19 · 4 min

DMA Buf

Data Structure struct dma_buf { size_t size; struct file *file; struct list_head attachments; const struct dma_buf_ops *ops; unsigned vmapping_counter; struct iosys_map vmap_ptr; const char *exp_name; const char *name; spinlock_t name_lock; struct module *owner; void *priv; struct dma_resv *resv; wait_queue_head_t poll; struct dma_buf_poll_cb_t { struct dma_fence_cb cb; wait_queue_head_t *poll; __poll_t active; } cb_in, cb_out; #endif } struct dma_buf_ops { bool cache_sgt_mapping; int (*attach)(struct dma_buf *, struct dma_buf_attachment *); void (*detach)(struct dma_buf *, struct dma_buf_attachment *); int (*pin)(struct dma_buf_attachment *attach); void (*unpin)(struct dma_buf_attachment *attach); struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *, enum dma_data_direction); void (*unmap_dma_buf)(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); void (*release)(struct dma_buf *); int (*begin_cpu_access)(struct dma_buf *, enum dma_data_direction); int (*end_cpu_access)(struct dma_buf *, enum dma_data_direction); int (*mmap)(struct dma_buf *, struct vm_area_struct *vma); int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map); void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map); }; cache_sgt_mapping, ....

2025-04-24 · 3 min

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

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