ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DRM PLANE 初始化流程对不上?把 drm_universal_plane_init 交给走 TaoToken 的 Codex 对照

DRM PLANE 初始化流程对不上?把 drm_universal_plane_init 交给走 TaoToken 的 Codex 对照 从 modetest 输出反推 DRM PLANE 初始化用走 TaoToken 的 Codex 对照drm_universal_plane_init调 DRM 显示通路时最让人卡壳的不是编译报错而是参数看不懂modetest打印出来的 plane 属性表里CRTC_W/CRTC_H和SRC_W/SRC_H两组 W/H 到底谁管剪裁、谁管缩放zpos的叠层顺序又是在哪一处代码里被写死的dmesg里atomic_set_planes()打出Added [PLANE:32:plane-0] state回头对着drm_universal_plane_init()的调用和那一长串drm_object_attach_property()很容易分不清哪个 property 对应哪一行输出。这篇不打算改任何内核逻辑只把翻源码硬啃这一步换成先打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 注册并创建一把 Key再把 Codex 的base_url填成https://taotoken.net/api、Key 填刚创建的那把让走 TaoToken 的 Codex 对着drm_universal_plane_init()的初始化调用与attach_property列表逐行核把plane_configs字段、property 列表和modetest输出对成一张对照表。TaoToken 在这条链路里只负责两件事发 Key、给统一 Base URL坐标换算、剪裁缩放和多图层合成依旧由内核 DRM 侧完成与它无关。一、原问题与场景三组参数对不上号以 exynos 驱动为例plane_configs[MIXER_WIN_NR]用三个条目分别描述 PRIMARY、CURSOR、OVERLAY 三层 plane 的zpos、pixel_formats与capabilitiesstatic const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] { { .zpos 0, .type DRM_PLANE_TYPE_PRIMARY, .pixel_formats mixer_formats, .num_pixel_formats ARRAY_SIZE(mixer_formats), .capabilities EXYNOS_DRM_PLANE_CAP_DOUBLE | EXYNOS_DRM_PLANE_CAP_ZPOS, }, { .zpos 1, .type DRM_PLANE_TYPE_CURSOR, .pixel_formats mixer_formats, .num_pixel_formats ARRAY_SIZE(mixer_formats), .capabilities EXYNOS_DRM_PLANE_CAP_DOUBLE | EXYNOS_DRM_PLANE_CAP_ZPOS, }, { .zpos 2, .type DRM_PLANE_TYPE_OVERLAY, .pixel_formats vp_formats, .num_pixel_formats ARRAY_SIZE(vp_formats), .capabilities EXYNOS_DRM_PLANE_CAP_SCALE | EXYNOS_DRM_PLANE_CAP_ZPOS | EXYNOS_DRM_PLANE_CAP_TILE, }, };初始化阶段驱动通过drm_object_attach_property()把 FB_ID、CRTC_X/Y/W/H、SRC_X/Y/W/H 等属性挂到 plane 上drm_object_attach_property(plane-base, config-prop_fb_id, 0); drm_object_attach_property(plane-base, config-prop_crtc_id, 0); drm_object_attach_property(plane-base, config-prop_crtc_x, 0); drm_object_attach_property(plane-base, config-prop_crtc_y, 0); drm_object_attach_property(plane-base, config-prop_crtc_w, 0); drm_object_attach_property(plane-base, config-prop_crtc_h, 0); drm_object_attach_property(plane-base, config-prop_src_x, 0); drm_object_attach_property(plane-base, config-prop_src_y, 0); drm_object_attach_property(plane-base, config-prop_src_w, 0); drm_object_attach_property(plane-base, config-prop_src_h, 0);而modetest打印出来的属性表长这样截取 plane id 32Planes: id crtc fb CRTC x,y x,y gamma size possible crtcs 32 36 78 0,0 0,0 0 0x00000001 formats: XR15 RG16 RG24 XR24 AR24 props: 7 type: flags: immutable enum enums: Overlay0 Primary1 Cursor2 value: 1 16 FB_ID: flags: object value: 78 17 IN_FENCE_FD: flags: signed range values: -1 2147483647 value: -1 19 CRTC_ID: flags: object value: 36 12 CRTC_X: flags: signed range values: -2147483648 2147483647 value: 0 13 CRTC_Y: flags: signed range values: -2147483648 2147483647 value: 0 14 CRTC_W: flags: range values: 0 2147483647 value: 800 15 CRTC_H: flags: range values: 0 2147483647 value: 600 8 SRC_X: flags: range values: 0 4294967295 value: 0 9 SRC_Y: flags: range values: 0 4294967295 value: 0 10 SRC_W: flags: range values: 0 4294967295 value: 52428800 11 SRC_H: flags: range values: 0 4294967295 value: 39321600再配合dmesg里atomic_set_planes()打出的Added [PLANE:32:plane-0] state问题就集中成三句话CRTC_W/CRTC_H与SRC_W/SRC_H分别对应显示管道的哪一段谁决定剪裁、谁决定缩放zpos的叠层顺序是在plane_configs里写死的还是在attach_property阶段动态挂上去的modetest里type的value: 1Primary和plane_configs里.type DRM_PLANE_TYPE_PRIMARY是怎么对应上的这类问题靠肉眼在drm_plane.c、exynos_drm_plane.c、drm_atomic.c之间来回跳效率很低。把这一步交给能读代码、能逐行对照的 Codex前提是先把它的请求通道配通。二、TaoToken 前置发 Key、给统一 Base URLTaoToken 在这条链路里只做两件事先说清楚边界发一把 API Key供 Codex 调用时鉴权给一个统一的 Base URLhttps://taotoken.net/apiCodex 的请求都往这里发。它不参与 DRM 的任何计算drm_universal_plane_init()怎么初始化、attach_property挂了哪些属性、zpos怎么排序、SRC_W/SRC_H怎么换算成像素全部由内核 DRM 侧完成。TaoToken 只是把Codex 读内核 DRM PLANE 驱动代码这条请求链路打通。操作顺序打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 注册账号进入控制台创建一把 Key形如YOUR_API_KEY先复制保存记住 Base URL 是https://taotoken.net/api不加/v1不加其它后缀把这两项填进 Codex 的配置里下一节给可复制配置。如果你还没装 Codex CLI可以用 npm 全局安装npm i -g taotoken/taotoken装完后用一条命令把 Key、Base URL、模型 ID 一起传进去taotoken cc -k YOUR_API_KEY -u https://taotoken.net/api -m MODEL_ID其中-u后面就是统一 Base URL-m后面填你在控制台选定的模型 ID。这条命令只是把 Codex 的请求指向 TaoToken不改变 Codex 读代码、分析代码的行为。三、可复制配置Codex 的 base_url 与 KeyCodex 的配置核心是两处base_url和api_key。把base_url填成https://taotoken.net/apiapi_key填刚创建的那把 Key。下面给一份可直接复制的配置片段以 Codex 常见的 TOML 配置为例字段名以你本地 Codex 版本为准# Codex 配置走 TaoToken 的统一 Base URL model MODEL_ID base_url https://taotoken.net/api api_key YOUR_API_KEY # 可选请求超时与重试 request_timeout 120 max_retries 2如果你用的是环境变量方式对应设置export OPENAI_BASE_URLhttps://taotoken.net/api export OPENAI_API_KEYYOUR_API_KEY注意两点base_url结尾不要带/v1也不要带/chat/completions之类的路径Codex 会自己拼接Key 只填一次不要在多处重复配置导致覆盖。配置完成后Codex 发出的每一次代码分析请求都会经过https://taotoken.net/api由 TaoToken 转发到对应模型。DRM 代码本身仍然在你本地仓库里Codex 读的是你本地的drivers/gpu/drm/目录。四、验证请求与成功结果把三组参数对成一张表配置好之后先做一次最小验证让 Codex 读drm_universal_plane_init()的调用点并列出attach_property挂载的属性清单。可以这样提问请阅读 drivers/gpu/drm/exynos/exynos_drm_plane.c 中 plane 初始化部分 找出 drm_universal_plane_init() 的调用并列出紧随其后的所有 drm_object_attach_property() 调用按属性名、默认值、对应 modetest 字段 整理成一张表。如果通道配通Codex 会返回类似下面的对照结果示意attach_property 属性默认值modetest 字段作用prop_fb_id0FB_ID指定该 plane 使用的 framebufferprop_crtc_id0CRTC_ID指定该 plane 绑定到哪个 CRTCprop_crtc_x/y0CRTC_X/CRTC_Yplane 在 CRTC 坐标系中的左上角位置prop_crtc_w/h0CRTC_W/CRTC_Hplane 在 CRTC 上占用的显示宽高缩放后的目标尺寸prop_src_x/y0SRC_X/SRC_Y从 framebuffer 中取图的起始坐标16.16 定点prop_src_w/h0SRC_W/SRC_H从 framebuffer 中取图的宽高剪裁区域16.16 定点这张表把之前的三组疑问一次性对齐剪裁由SRC_X/SRC_Y/SRC_W/SRC_H决定即从 framebuffer 里取哪一块缩放由SRC_W/SRC_H与CRTC_W/CRTC_H的比值决定前者是源尺寸后者是目标尺寸叠层顺序zpos在plane_configs里静态声明PRIMARY0、CURSOR1、OVERLAY2初始化时通过EXYNOS_DRM_PLANE_CAP_ZPOS能力位暴露给上层modetest里看到的type枚举值Overlay0、Primary1、Cursor2与plane_configs的.type字段一一对应。再让 Codex 对照dmesg日志dmesg 里有 Added [PLANE:32:plane-0] state 请解释这条日志是在 drm_atomic_get_plane_state() 的哪个阶段打印的 以及它和 modetest 里 plane id 32 的对应关系。Codex 会指出drm_atomic_get_plane_state()在 atomic 提交路径中为 plane 创建或获取 state日志里的PLANE:32就是modetest中id 32的 planeplane-0是该 plane 在驱动内部的命名。这样dmesg和modetest就通过 plane id 串起来了。验证成功的标志Codex 能准确列出attach_property的属性清单且与modetest字段对得上能解释SRC_W/SRC_H的 16.16 定点格式例如52428800对应800 16能说明zpos的静态声明位置与type枚举的对应关系。五、本篇常见错排查错误 1base_url多写了/v1现象Codex 请求返回 404 或路径拼接错误。原因base_url填成了https://taotoken.net/api/v1。修正改成https://taotoken.net/api不要带/v1。错误 2Key 填错或未生效现象返回 401 未授权。排查确认 Key 是从控制台复制的那把没有多余空格确认配置里没有旧 Key 覆盖。可到 API Keys 页面重新创建一把。错误 3Codex 读不到本地 DRM 代码现象Codex 回答泛泛而谈没有引用具体文件行号。原因提问时没有指定文件路径或 Codex 的工作目录不在内核源码根目录。修正在提问中明确给出drivers/gpu/drm/exynos/exynos_drm_plane.c这类路径并确认 Codex 的工作目录。错误 4把SRC_W/SRC_H当成像素值现象对照modetest时发现SRC_W是52428800与CRTC_W的800对不上。原因SRC_W/SRC_H是 16.16 定点格式需要右移 16 位才是像素值。52428800 16 800正好等于CRTC_W说明该 plane 没有缩放1:1 显示。错误 5zpos找不到挂载点现象在attach_property列表里找不到zpos。原因zpos不是通过drm_object_attach_property()挂的而是在drm_universal_plane_init()内部根据capabilities里的EXYNOS_DRM_PLANE_CAP_ZPOS自动创建。修正让 Codex 读drm_universal_plane_init()的实现确认zposproperty 的创建条件。错误 6dmesg日志级别没开现象dmesg里看不到atomic_set_planes()相关日志。原因DRM debug 未开启。修正echo 0xf /sys/module/drm/parameters/debug再重新跑modetest。六、语义一致 CTA这条链路的目标很明确把翻源码硬啃 DRM PLANE 初始化换成让走 TaoToken 的 Codex 逐行对照。如果你在配置base_url、填 Key、或对照attach_property与modetest字段时卡住先去 API Keys 页面确认 Key 状态再对照接入文档检查base_url是否写成了https://taotoken.net/api不带/v1。需要验证模型是否能正常读代码可以到模型对话页面发一条最小请求试跑。如果你打算长期用 Codex 读内核 DRM 代码、做驱动层的持续排查Coding Plan 更适合这种长期编码与 Agent 场景。通道跑通之后再继续排查 CRTC 与 plane 的参数关系会顺很多。
返回列表