# Linux Kernel Dev

> Linux kernel and driver development assistant. TRIGGER when: user works on kernel modules, device drivers, kernel subsystems, Kconfig, Makefile, device tree (.dts/.dtsi), or C code using kernel APIs (kmalloc, printk, module_init, platform_driver, etc.). DO NOT TRIGGER when: userspace C/C++ programs, general systems programming without kernel involvement.

- Skill: `tbusos/linux-kernel-dev` (Agent Skill, multi-file: 235 files)
- Install (CLI): `npx skillmds@latest add tbusos/linux-kernel-dev`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tbusos/linux-kernel-dev/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: TbusOS (https://skillmd.com/u/tbusos)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tbusos/linux-kernel-dev

---


# Linux Kernel & Driver Development

Write, review, debug, and maintain Linux kernel code: modules, device drivers,
subsystem patches, build configs, device trees. Plus BSP customization discipline.

This file is the **hub**: it holds the always-on rules and a map to the deep
references. Load a reference only when the task needs it (progressive disclosure).

---

## Core Principles

1. **Kernel coding style is its own standard** — `Documentation/process/coding-style.rst`, NOT GNU or Google. Tabs (8 wide), `/* */` comments, K&R braces.
2. **Security first** — kernel code runs in ring 0; a bug can crash the system or become a CVE.
3. **No userspace habits** — no `malloc`/`free`, no `printf`, no floating point, no libc.
4. **Upstream mindset** — write as if submitting to LKML; run `checkpatch.pl` before any patch.
5. **Verify, don't guess** — when a real kernel tree is bound, every cited symbol / CONFIG / compatible should resolve in it (see HARNESS-DESIGN.md §6.10). State `[未验证]` when no tree is bound rather than asserting.

---

## Forbidden Actions (hard rules — not suggestions)

1. **Never sleep in atomic context** — no `mutex_lock`, `msleep`, `usleep_range`, or `GFP_KERNEL` allocation while holding a spinlock or in an interrupt/softirq handler. Use `spinlock` + `GFP_ATOMIC` there.
2. **Never use floating point** in kernel code — no FPU, no `float`/`double` math.
3. **Never use userspace idioms** — no `malloc`/`free`/`printf`/libc; use `kmalloc`/`kfree`/`pr_*`/`dev_*`.
4. **Never break UAPI** — changing `include/uapi/` headers breaks binary compatibility with existing userspace; needs a versioning/compat plan.
5. **Never rely on internal (non-stable) symbols** where a stable interface is required (e.g. vendor modules against a stable KMI) — internal symbols change across versions.
6. **Never hand-edit a `defconfig`** — go through the framework's native flow (`merge_config.sh` + `make olddefconfig` + `savedefconfig`). See `references/bsp_discipline.md`.
7. **Never ignore `checkpatch.pl` errors** before submitting a patch.
8. **Never delete upstream code to customize** — default to keeping it + a vendor config gate (`#if defined(CONFIG_<VENDOR>_<PURPOSE>)`). See `references/bsp_discipline.md`.
9. **Never conclude a hardware state from software observation alone** — read the bytes directly (register/OTP/eFuse dump). See `references/bsp_discipline.md`.
10. **Never decide a change is safe on the compile dimension alone** — check the 4 dimensions (compile / runtime path / semantics / compliance). See `references/bsp_discipline.md`.
11. **Never change an existing function's contract without enumerating every call site** — 返回值含义、参数取值空间、副作用、错误约定,任何一项变了都要逐个调用点确认。**类型不变时编译器一声不吭**,静默的行为改变比编译错误危险得多。跑 `scripts/check_api_change.sh <函数名>`,方法见 `references/api-contract-change.md`。
12. **Never conclude "this line runs" from a grep hit alone** — grep 返回**行**,语义住在**块**里。下结论前答完 WHO / WHEN / ELSE 三问,尤其别拿 WHO 的答案当 WHEN 的答案。跑 `scripts/show_guard_chain.py --grep <pattern> <path>`,方法见 `references/execution-context.md`。
13. **Never redesign existing code before finding out why it is the way it is** — 改一段已经在跑的代码,顺序是:考古(`scripts/why_this_code.sh`,读原作者 commit message —— 那是设计意图唯一的一手记录)→ 读子系统规范 → 摸上下文(`scripts/check_context_safety.py`:能不能睡 / 并发 / **多核 SMP** / 生命周期)→ 算影响面 → 才定方案。方案优先级**有序**:不动对外接口 > 靠拢内核通用设计 > 好移植好维护 > 修原设计缺陷。完整流程见 `references/modifying-existing-code.md`。
14. **Never keep going when a change starts cascading** — 改一处牵出一串(SDK 升级的冲突修复天生如此),**停下来说明现状再继续**,别闷头改完;级联到新的一件事就开新 commit。提交前跑 `scripts/diff_discipline.mjs --diff <patch> --scope '<被要求改的范围>'`,逐行自问"哪句需求让这行成为必要的" —— 答案是"顺手"就撤掉。方法见 `references/change-discipline.md`。
15. **Never let an AI/tool add `Signed-off-by`** — only a human can certify the DCO. AI-assisted work is disclosed with `Assisted-by:`; the human reviews all of it, ensures SPDX + GPL-2.0 compatibility, and adds their own sign-off. See `references/patch-workflow.md`.

---

## References (load on demand)

| 任务 | 加载 | 权威源（依据） |
|---|---|---|
| 内核代码风格 / 审码 | `references/coding-style.md` | `Documentation/process/coding-style.rst` |
| 新建 module / driver / chardev / Makefile / Kconfig / DT | `references/templates.md` | `Documentation/kbuild/`, `Documentation/devicetree/bindings/` |
| 锁 / 并发 / 原子 | `references/concurrency.md` | `Documentation/locking/`, `memory-barriers.txt`, `atomic_t.txt` |
| 调试（printk / ftrace / drgn 活体检查 / trace-cmd 分析 / oops / 工具） | `references/debugging.md` | `Documentation/admin-guide/`, `dev-tools/`, drgn/trace-cmd 官方文档 |
| 内核 API 速查 | `references/api-quick-ref.md` | `Documentation/core-api/`, `driver-api/` |
| 提交 patch / checkpatch / format-patch / b4 系列投递 / virtme-ng 启动验证 | `references/patch-workflow.md` | `Documentation/process/submitting-patches.rst`, b4/virtme-ng 官方文档 |
| **BSP 定制纪律**（defconfig / 上游 gate / 硬件调试 / 改动分析 / 冲突解决） | `references/bsp_discipline.md` | 通用工程纪律 |
| **构建系统**（Kbuild Makefile / Kconfig 语言 / 配置流程 / 交叉编译 / in-tree·out-of-tree / 模块要素） | `references/build.md` | `Documentation/kbuild/` |
| **ARM 内存类型 / 对齐 / 异常入口**（Normal·Device·Strongly-ordered 契约差别 · SO 上非对齐为何必错 · Data Abort 硬件动作 · XN→Permission fault · arm32 自解压器那条界与 arm64 为何没有 · 镜像增量怎么传导） | `references/arm-memory-model.md` | ARM DDI 0406C.d · `Documentation/arch/arm{,64}/booting.rst` |
| 跨内核版本差异 | `references/kernel_version_deltas.md` | 各版本树 + `Documentation` |
| **接口契约变更**（改返回值语义/参数取值空间/副作用前,枚举所有调用点;加 `EXPORT_SYMBOL` 前先问它是不是真的要给可加载模块用 —— 生产者和消费者都进 vmlinux 就不需要导出,非 static 定义加头文件原型就够,多余的导出等于对外宣称"这是公开接口") | `references/api-contract-change.md` + `scripts/check_export_symbol.sh` | 通用工程纪律 |
| **执行上下文**（从 grep 结果推系统行为前:守卫链 / WHO·WHEN·ELSE 三问 / init.rc·Kconfig·Makefile·DTS 等块结构语言 / 被质疑时先核对自己产出） | `references/execution-context.md` | 通用工程纪律 |
| **改既有代码五步流程**（考古找设计意图 → 读子系统规范 → 上下文·并发·**多核 SMP** → 影响面 → 方案优先级;含"原设计对不对"的三档判断） | `references/modifying-existing-code.md` | 通用工程纪律 |
| **改动边界**（提交前看 diff:每行能否指回需求 / 四类过度设计的内核形态 / 级联改动·隐形决策·错误的抽象) | `references/change-discipline.md` + `scripts/diff_discipline.mjs` | 通用工程纪律 |
| **答案验证契约**（引具体符号时附 `[CLAIMS]`） | `references/claims-contract.md` | 事实检查 靶子 |
| **画调用路径**（30 层以上的调用链用 ASCII 树,别画流程图;树里一个非 ASCII 字符都不许有 —— 全部深度都编码在列里） | `references/call-path-figures.md` + `scripts/check_call_tree.py` | 通用工程纪律 |
| 该做 / 不该做速查 | `dos-and-donts.md` | 本 skill 积累 |
| 已知坑（gotchas） | `known-bugs.md` | 本 skill 积累 |

### 子系统模块（按需路由）

深入具体内核子系统时加载对应模块（命中才读，progressive disclosure），每个对应该子系统的 `Documentation/<subsys>/`，并配套 eval 用例进 harness（fact_gate + 回归测）。

| 任务命中 | 加载 | 权威源（依据） |
|---|---|---|
| 中断 / 下半部 / threaded IRQ / tasklet / softirq / workqueue 选型 | `references/subsys/interrupts.md` | `Documentation/core-api/genericirq.rst`、`core-api/irq/` |
| 睡眠/唤醒 / 等待队列 / completion / 抢占 / 调度策略·优先级·亲和性 / CFS·EEVDF·RT·DL | `references/subsys/scheduler.md` | `Documentation/scheduler/` |
| 内存分配（kmalloc/kvmalloc/vmalloc/alloc_pages/kmem_cache）/ GFP 标志 / 访问用户内存 / 驱动 mmap·缺页 | `references/subsys/memory.md` | `Documentation/mm/`、`core-api/memory-allocation.rst` |
| 并发加锁（spinlock vs mutex 选型 / 进程+中断共享锁要 irqsave / 原子态禁睡眠 / RCU 读多写少） | `references/subsys/locking.md` | `Documentation/locking/`、`include/linux/spinlock.h`、`mutex.h`、`rcupdate.h` |
| 运行时电源 runtime PM（pm_runtime_enable / get·put 配平 / get_sync 失败也加引用 / autosuspend / dev_pm_ops 系统睡眠回调） | `references/subsys/pm-runtime.md` | `Documentation/power/runtime_pm.rst`、`include/linux/pm_runtime.h`、`pm.h` |
| 系统唤醒（enable_irq_wake 与 wake_depth 配平 / `power/wakeup` 怎么生成 / `wakeup-source` 属性由谁解析 / 驱动自管 vs PM 框架托管 二选一） | `references/subsys/wakeup.md` | `Documentation/driver-api/pm/`、`Documentation/power/`、`include/linux/pm_wakeup.h`、`pm_wakeirq.h` |
| DMA 映射 API（coherent vs streaming 选型 / dma_map 后必查 dma_mapping_error / DMA mask / 缓存同步 · 不是 dmaengine） | `references/subsys/dma-mapping.md` | `Documentation/core-api/dma-api.rst`、`dma-api-howto.rst`、`include/linux/dma-mapping.h` |
| VFS / file_operations 实现 / 导出数据（debugfs·procfs·sysfs·seq_file）/ 写文件系统·挂载 / page cache | `references/subsys/filesystems.md` | `Documentation/filesystems/` |
| 设备树消费（compatible 绑定 / of_* 读属性 / 拿 MMIO·中断·时钟·GPIO / 遍历节点 / overlay） | `references/subsys/device-tree.md` | `Documentation/devicetree/`（`.dts`/binding 模板见 `templates.md`） |
| I2C 设备驱动（i2c_driver 绑定 / smbus·原始传输 / regmap-i2c / probe 签名版本） | `references/subsys/i2c.md` | `Documentation/i2c/`、`include/linux/i2c.h` |
| SPI 设备驱动（spi_driver 绑定 / spi_sync·多段传输 / regmap-spi / buffer DMA-able） | `references/subsys/spi.md` | `Documentation/spi/`、`include/linux/spi/spi.h` |
| GPIO（gpiod 描述符消费 / GPIO 当中断 / 写 gpiochip 控制器 / 弃旧整数 API） | `references/subsys/gpio.md` | `Documentation/driver-api/gpio/`、`include/linux/gpio/consumer.h` |
| USB host 驱动（usb_driver 绑定 / 控制·批量传输 / URB 异步 / 完成回调上下文） | `references/subsys/usb.md` | `Documentation/driver-api/usb/`、`include/linux/usb.h` |
| 网络（net_device 注册 / NAPI 收包 / ndo_start_xmit 发包 / sk_buff / 队列控制） | `references/subsys/networking.md` | `Documentation/networking/`、`include/linux/netdevice.h` |
| 音频 ASoC（codec/component · cpu DAI · machine 声卡 / DAI ops / trigger 上下文） | `references/subsys/audio.md` | `Documentation/sound/soc/`、`include/sound/soc.h` |
| 摄像 V4L2（v4l2_device/video_device 注册 / vb2 缓冲 / sensor subdev async / stop_streaming） | `references/subsys/camera.md` | `Documentation/driver-api/media/`、`include/media/` |
| 时钟 CCF（clk_get/prepare/enable 消费 / prepare·enable 两阶段上下文 / 写 clk provider 暴露给 DT） | `references/subsys/clk.md` | `Documentation/driver-api/clk.rst`、`include/linux/clk.h`、`clk-provider.h` |
| 引脚 pinctrl（运行时切 state / PM sleep·idle 封装 / default 态由 core 自动应用） | `references/subsys/pinctrl.md` | `Documentation/driver-api/pin-control.rst`、`include/linux/pinctrl/consumer.h` |
| 供电 regulator（get·enable·调压消费 / enable·disable 引用计数配平 / 可选供电 vs dummy） | `references/subsys/regulator.md` | `Documentation/power/regulator/consumer.rst`、`include/linux/regulator/consumer.h` |
| 寄存器抽象 regmap（按总线 init / read·write·update_bits / cache + PM / volatile 寄存器） | `references/subsys/regmap.md` | `Documentation/driver-api/regmap.rst`、`include/linux/regmap.h` |
| 复位 reset（assert·deassert·reset 消费 / exclusive vs shared 引用计数 / DT resets） | `references/subsys/reset.md` | `Documentation/driver-api/reset.rst`、`include/linux/reset.h` |
| PWM（pwm_get / pwm_state 原子应用 / apply 接口改名·原子 vs 会睡 / DT pwms） | `references/subsys/pwm.md` | `Documentation/driver-api/pwm.rst`、`include/linux/pwm.h` |
| IIO（写 sensor/ADC 驱动 / iio_priv 私有数据 / channels·info / 触发缓冲采集） | `references/subsys/iio.md` | `Documentation/driver-api/iio/`、`include/linux/iio/iio.h` |
| 温控 thermal（温度传感器 zone / get_temp 毫摄氏度 / 冷却设备 / OF 注册改名 / DT thermal-zones） | `references/subsys/thermal.md` | `Documentation/driver-api/thermal/`、`include/linux/thermal.h` |
| 看门狗 watchdog（watchdog_ops 启停喂狗 / nowayout 语义 / max_hw_heartbeat 代喂 / stop_on_reboot） | `references/subsys/watchdog.md` | `Documentation/watchdog/`、`include/linux/watchdog.h` |
| RTC（rtc_class_ops 读写时间 / rtc_time 遵循 struct tm·tm_year 自 1900 / allocate+register） | `references/subsys/rtc.md` | `Documentation/admin-guide/rtc`、`include/linux/rtc.h` |
| LED（led_classdev 注册 / brightness_set 原子上下文 vs blocking / DT init_data） | `references/subsys/led.md` | `Documentation/leds/`、`include/linux/leds.h` |
| 输入 input（input_dev 注册 / 声明能力 + 上报 + input_sync 帧同步 / 绝对轴范围） | `references/subsys/input.md` | `Documentation/input/`、`include/linux/input.h` |
| 电源 power-supply（power_supply_desc 注册 / 属性固定微单位 / power_supply_changed 通知 / propval） | `references/subsys/power-supply.md` | `Documentation/power/power_supply_class.rst`、`include/linux/power_supply.h` |
| CPU 调频 cpufreq（写 cpufreq_driver + 频率表 / .target_index 索引切频 / 异步改频率要 transition_begin·end / OPP） | `references/subsys/cpufreq.md` | `Documentation/admin-guide/pm/cpufreq.rst`、`include/linux/cpufreq.h` |
| CPU 空闲 cpuidle（cpuidle_driver + states / .enter 原子上下文返回实际态 / 停 timer 标 TIMER_STOP / 延迟·驻留单位 µs） | `references/subsys/cpuidle.md` | `Documentation/driver-api/pm/cpuidle.rst`、`include/linux/cpuidle.h` |
| 设备调频 devfreq（非-CPU 设备 GPU/总线 / devfreq_dev_profile + target / .target 取实际 OPP ceil / get_dev_status 利用率） | `references/subsys/devfreq.md` | `Documentation/driver-api/devfreq.rst`、`include/linux/devfreq.h`、`pm_opp.h` |
| DMA engine（slave DMA 消费 / prep·submit·issue_pending 序列 / 通道生命周期 / DT dmas） | `references/subsys/dmaengine.md` | `Documentation/driver-api/dmaengine/`、`include/linux/dmaengine.h` |
| NVMEM（eeprom/efuse/otp 消费 cell·缓冲要 kfree / 写 provider nvmem_config / DT cells） | `references/subsys/nvmem.md` | `Documentation/driver-api/nvmem.rst`、`include/linux/nvmem-consumer.h` |
| MMC/SD host（mmc_alloc_host·add / mmc_host_ops / .request 完成必 mmc_request_done） | `references/subsys/mmc.md` | `Documentation/mmc/`、`include/linux/mmc/host.h` |
| MTD flash（NAND/NOR / 写前必擦 + erasesize 对齐 / mtd_device_parse_register 分区 / nand_scan） | `references/subsys/mtd.md` | `Documentation/driver-api/mtd/`、`include/linux/mtd/mtd.h` |
| 通用 PHY（USB/PCIe/MIPI phy 消费 init→power_on / 写 provider phy_ops / 别和网络 MDIO PHY 混） | `references/subsys/phy.md` | `Documentation/driver-api/phy/`、`include/linux/phy/phy.h` |
| 硬件监控 hwmon（register_with_info / sysfs 固定单位 温度毫摄氏度·电压 mV / chip_info·ops·channel） | `references/subsys/hwmon.md` | `Documentation/hwmon/`、`include/linux/hwmon.h` |
| 写时钟控制器 clk-provider（clk_hw/clk_ops · enable 原子 vs prepare 可睡 · 暴露给 DT · 固定/门控构造器） | `references/subsys/clk-provider.md` | `Documentation/driver-api/clk.rst`、`include/linux/clk-provider.h`（消费见 `clk.md`） |
| 写 pin 控制器 pinctrl-driver（pinctrl_desc 三组 ops · dt_node_to_map · set_mux · pin_config_set） | `references/subsys/pinctrl-driver.md` | `Documentation/driver-api/pin-control.rst`、`include/linux/pinctrl/`（消费见 `pinctrl.md`） |
| Mailbox/IPC（client 收发 mbox_send_message · 写控制器 mbox_chan_ops · TX 完成必上报 txdone） | `references/subsys/mailbox.md` | `Documentation/driver-api/mailbox.rst`、`include/linux/mailbox_{client,controller}.h` |
| 写 PMIC/稳压器 regulator-driver（regulator_desc · *_regmap helper ops · list_voltage 映射） | `references/subsys/regulator-driver.md` | `include/linux/regulator/driver.h`（消费见 `regulator.md`） |
| 写 DMA 控制器 dmaengine-provider（dma_device · dma_cap_set · virt-dma vchan · 完成 complete cookie） | `references/subsys/dmaengine-provider.md` | `Documentation/driver-api/dmaengine/provider.rst`、`include/linux/dmaengine.h`（消费见 `dmaengine.md`） |
| IOMMU 驱动（iommu_ops · map_pages/unmap_pages · unmap 后必刷 IOTLB · domain 类型） | `references/subsys/iommu.md` | `Documentation/driver-api/iommu`、`include/linux/iommu.h` |

目录总览见 `index.md`。

---

## 关于本 skill 的自我进化引擎

本 skill 正在配一套有度量的自我改进机制（事实检查 / 打分面板 / 测试用例集 / 回归测试 / `/kernel-learn`），
并能跟随内核版本自更新。设计与状态见同目录 `HARNESS-DESIGN.md`。
`dos-and-donts.md` / `known-bugs.md` 会随真实任务由该机制逐步充实——每条都带可执行检查，不是空话。

**已落（P1 客观检查 + P2 回归测试 + P3 打分面板/学习循环 + P4 记录表/版本适配）**：
- `scripts/fact_gate.mjs` — 查答案 `[CLAIMS]` 里的 API / CONFIG / 符号 / compatible 是否在真内核树**实存**（树无关 `--tree`；exit 0 干净 / 1 有幻觉 / 3 检查坏不算 fail）
- `scripts/check_call_tree.py` — 查答案里的 ASCII 调用树是否列对得上（非 ASCII / 缩进不在步长 / `<---` 落到不存在的帧 / 单行过宽；`--selftest` 四探针 + 一棵干净树校准假阳）
- `scripts/checkpatch_gate.sh` — 用内核自带 `checkpatch.pl` 校代码风格
- `scripts/defconfig_gate.mjs` — 查 defconfig 里**写了却没生效**的行(符号本 arch 不存在 / `depends on` 不满足 / 上游已删)。按符号比对声明值与 `.config` 实际落值,**无视顺序** —— `savedefconfig` 的 diff 会被重排序淹没,3 行真问题藏在几百行噪声里。另报 `#CONFIG_X`(`#` 后缺空格 ⇒ Kconfig 视为纯注释)。`--selftest` 做自降解校准;exit 0 全生效 / 1 有声明未生效 / 3 闸坏。规则见 `references/bsp_discipline.md §1`
- `scripts/decompressor_limit_check.sh` — 判断一棵树会不会踩 arm32 解压器那条可执行窗口上界（两级判据：先架构后 BSP；两边都有/都没有 `configs/vendor` 时诚实报「未判定」要求 `--arch`，不猜）
- `scripts/binary_diff_classify.py` — 两个二进制的差异是**真实代码变化**还是**地址整体平移**（按 32 位字解码统计 delta 分布；`--limit` 划出未压缩区，否则压缩载荷雪崩淹没一切；带 `--self-test`）
- `scripts/kernel-tree.mjs` — 绑内核树（`detect` / `add` / `list` / `clone`），路径存本机配置不入库
- `scripts/regression_test.mjs` + `tests/eval/cases/*.json` — 回归测试:每条用例的 gold 必须在真树查得到 + 自降解校准（故意改坏必须被抓）+ 覆盖率统计；`--baseline` 记录、`--check` 对比退步
- `scripts/kernel-critic.mjs` + `.claude/agents/kernel-*-critic.md` — 7 轴打分面板（correctness/safety/design/testing/complexity/coding-style/completeness,对应 Google review 维度;safety 一票否决）prompt 准备,Task 派子 agent 并行评分
- `/kernel-learn`（`.claude/commands/` + `scripts/kernel_learn_validate.mjs`）— 把踩过的坑沉成原子三件套（规则带 `[CLAIMS]` + 建前fail/建后pass 用例 + 注册），无可执行检查不准建
- `evolution/{ledger.tsv,rules.json}` + `scripts/version_drift.mjs` — 记录表/规则复用 design-evolve（`evolve-ledger.mjs --ledger=` / `evolve-rules.mjs --registry=`）带 fires/catches；`version_drift.mjs` 拿多版本树对比 gold,报"旧版有新版没"的 API（机器跑出版本漂,不靠手维护）
- 引具体符号的答案附 `[CLAIMS]` 块（`references/claims-contract.md`）；绑树后跑事实检查,答案标 `[已对 linux <版本> 验证]` 或 `[未验证]`

