本节摘要:发布是驱动从代码变成产品的仪式,维护是发布之后的长跑。本节讲清版本号策略、变更说明的写法、发布清单的执行、文档的随行义务,以及与内核社区协作的路线——把"扔出一个压缩包"升级为"承担一份持续责任"。
一个驱动写完那天,工作只完成了一半;另一半从发布开始。发布不是打个包上传的动作,而是一套让用户"敢用、会装、能修、可退"的承诺体系;维护则是让这份承诺在数年内持续兑现的日常。这两件事做得好坏,决定一个驱动是"昙花一现的演示"还是"产品线上跑了五年的部件"。
驱动版本号建议采用三段式:主版本、次版本、修订号。三段各有明确语义,用户看到号码就知道这次升级意味着什么:
版本号只在发布时打,不在开发中途改——开发中的每一次构建都能追溯到某个版本加代码仓库修订号,7.4 节的"翻译链归档"正是按这个对应关系管理:每个发布版本配一套模块、符号文件、调试信息与构建清单,缺一样,现场崩溃就翻译不回去。
变更说明(发布说明)是发布里最容易被敷衍、事后最被需要的文件。合格的变更说明回答用户升级前会问的全部问题:
board-led 驱动 1.4.0 发布说明 新增 - 闪烁周期支持运行中调整,无需重装模块(设备树新增可选属性) - 唤醒源注册:深睡下可由按键唤醒系统 修复 - 修正并发配置时日志与实际状态不一致的问题(高负载下偶发) 行为变化 - 控制命令对非法参数统一返回参数错误(此前部分命令静默忽略) —— 自动化脚本如依赖旧行为需适配 已知问题 - 极低温环境下上电首毫秒的首次写入可能需要重试一次 升级要求 - 内核 5.15 及以上;5.10 需使用 1.3.x 分支
注意"行为变化"与"已知问题"两节——不写它们,用户遇到时的第一反应是"驱动坏了",写了它们,第一反应是"符合说明,按预案处理"。这两节的诚实程度,就是维护者与用户之间信任的全部基础。
把发布动作固化成清单,逐项打勾执行——清单防的不是低级失误,而是"赶发布那天恰好忘掉的重要小事":
| 环节 | 检查项 |
|---|---|
| 代码冻结 | 全部计划内变更已合入;矩阵构建全绿;7.3 节压测短版通过 |
| 文档同步 | 变更说明、设备树绑定说明、接口文档与本版一致 |
| 产物归档 | 模块、签名、符号与调试信息、构建清单哈希成套入库 |
| 版本留痕 | 版本号、仓库修订号、构建时间与产物一一对应登记 |
| 回滚预案 | 上一版本产物与回滚步骤确认可用 |
| 公告 | 发布渠道通知:新版本号、升级要点、已知问题 |
清单里"回滚预案"最常被省略,也最关键:没有回滚预案的发布,本质是拿用户当测试。升级失败路径(怎么退回旧版、退回后配置是否兼容)在发布前就要演练过。
驱动文档分三层,各有读者。用户文档面向使用者与运维:怎么编入系统、设备树怎么写、接口语义是什么、常见故障怎么处置——写得越清楚,售后问题越少。接口文档面向上层软件开发者:每个回调与命令的参数、返回值、并发语义、错误码清单,这份文档就是 6.4 节校验设计的对外镜像。维护文档面向未来的自己(或接手者):设计取舍、已知陷阱、为什么当年这么写——一年后的你会感谢现在写下"为什么"的你。
设备树绑定说明值得一提:它描述"这个驱动的设备树节点长什么样、哪些属性必填、取值范围如何",既是用户文档的一部分,也是走向主线化的必备材料(社区要求绑定说明先行评审)。
发布之后进入维护节奏:安全漏洞响应(最优先级,影响面评估与修复时限要有内部约定)、内核版本跟进(8.2 节矩阵的常态化运行)、用户问题分诊(区分缺陷、使用错误、需求)。维护的最大成本不是修缺陷,而是保持驱动的"可维护性":及时清理过时兼容代码(不再支持的版本分支果断删除)、拒绝无节制的配置项增殖、保持与主线同类驱动的同步。
维护的高阶形态是主线化:把驱动分批合入内核主线——先是绑定说明与核心代码,再是特性和优化。合入后的节奏变为"跟着内核社区走":接口变更由维护者协同更新、你的代码获得持续审查与安全响应。厂商驱动的常见路径是"外挂两年、主线三年、最终完全交由社区",驱动的一生,最好以不再需要专门维护它为圆满。
💡 关键直觉:发布与维护的本质是管理预期。版本号管理升级预期、变更说明管理行为预期、文档管理使用预期、回滚预案管理最坏预期——预期都被妥善管理的驱动,才配得上"产品"二字。
把发布流程沙盘化。假设 LED 驱动 1.4.0 定于周五发布,周三起按清单推进:代码冻结——计划内变更全部合入,兼容矩阵全绿,7.3 节回归脚本通过;文档同步——变更说明按模板写就"行为变化"一节如实登记非法参数处理的变化;产物归档——模块、调试信息、构建清单哈希成套入库,设备树绑定说明更新到新属性;回滚演练——在测试机上装 1.4.0 再退回 1.3.2,退回后配置兼容性确认;公告发布——升级要点与已知问题随版本号一起送达用户渠道。周五当天只剩最后一个动作:把归档目录标记为正式版。
演练的价值在周四暴露:回滚测试发现 1.4.0 的设备树新属性在 1.3.2 上会告警——于是变更说明里补上一句"回滚前需移除新增属性"。这一句话的价值,等某位运维深夜回滚时才会兑现。发布工程没有高深技术,全是这种"提前替未来的别人着想"的琐碎。
难题一:客户报告了一个无法复现的问题,怎么处理? 先分类——按 7.1 节的思路判断它更像竞态(每次现象随机)还是状态残留(偶发但固定形态);再取证——请客户提供完整日志与出现频率,无法复现的故障靠"缩小条件集合"推进:让客户开关某些功能组合,观察故障是否随之消失。永远不要用"无法复现"关单——那是把维护成本转嫁给用户。难题二:要不要为一个老客户长期维护一个过时的内核分支? 算三笔账:维护成本(分支偏离主线越远成本越高)、安全风险(旧分支收不到主线的修复)、客户的真实生命周期。多数情况下更划算的方案是把客户迁到受支持的长期版本,而不是让自己成为"活的化石馆"。
💡 关键直觉:发布与维护的全部技巧,都指向同一条原则——你交付的不是一份二进制,而是一条可持续的信任链。版本号是承诺的格式,变更说明是承诺的内容,回滚预案是承诺的兜底,文档是承诺的说明书。任何一个环节含糊,用户都会用"不敢升级"来投票,而驱动作者要为此在深夜的工单里偿还利息。
至此内核态驱动的工程化全流程闭环。最后一节打开两个新世界:把驱动搬进用户态,以及用更安全的语言重写——出厂之旅的终点,恰是新路线的起点。