dmaengine
[toc] drivers/dma/dmaengine.hstruct dma_chan / struct dma_chan_dev: DMA 通道对象与其 sysfs 设备包装对象的语义建模 struct dma_chan:DMAengine 框架中“可被客户端申请与提交事务”的通道抽象,承载运行期状态(cookie、完成度、客户端引用计数、路由信息等)以及与上层可见性的关联(sysfs/debugfs 相关字段)。 struct dma_chan_dev:把通道映射为 Linux 设备模型中的一个 struct device,用于 sysfs 节点呈现与生命周期管理;同时保存 dma_chan * 的反向指针(也就是你前面讨论的 chan->dev->chan 这一条关键可见性路径)。 这两个结构体之所以分开,是因为 DMAengine 需要同时满足: 运行期快速访问与调度(dma_chan) 设备模型可见性、热插拔/解绑生命周期、sysfs 目录树一致性(dma_chan_dev + struct d...
dmaengine
[toc] [mm/dmapool.c] [DMA 池分配器(dma_pool)] [为指定 device 提供“小块、一致性(coherent)可 DMA”的池化分配/释放接口]介绍dma_pool 的目标很明确:给驱动提供固定大小的小块 DMA 一致性内存,避免频繁用 dma_alloc_coherent() 做“小块分配”带来的浪费与开销;实现方式是:先用 dma_alloc_coherent() 一次拿一段(通常至少一页)一致性内存,然后切成等大小 block,用空闲链表管理。源码文件开头注释把这个设计讲得很直接:从页分配器拿 coherent page,再拆分成 blocks,并用跨页的单链表跟踪空闲块。 历史与背景这项技术是为了解决什么问题而诞生的?驱动里常见“很多很小、但必须设备可直接 DMA 访问且无需显式 cache flush”的对象(例如描述符、队列元素等)。直接 dma_alloc_coherent() 去分配这些小对象会导致: 粒度偏大:coherent 分配往往以页或更大粒度管理,小对象会产生明显内部碎片; 频繁分配/...
core
[TOC] drivers/base/core.c 设备核心(Device Core) 设备模型的运转中枢drivers/base/core.c 是Linux内核统一设备模型的心脏。它不是一个孤立的功能,而是整个设备模型框架的中央实现和调度器。文件中包含了设备注册与注销、设备与驱动的绑定与解绑、设备生命周期管理、sysfs 核心接口以及电源管理回调等最核心的逻辑。可以说,内核中任何设备的任何状态变化,都离不开core.c中代码的直接或间接执行。 历史与背景这项技术是为了解决什么特定问题而诞生的?在统一设备模型被构想出来时,需要一个集中的地方来实现所有设备和驱动都必须遵循的通用规则和流程。core.c正是为了这个目的而创建的,它解决了以下核心问题: 通用设备管理:提供一个单一、标准的接口(device_register, device_unregister)来处理系统中所有类型设备的添加和移除,避免每个子系统(PCI, USB等)重复造轮子。 驱动绑定协调:建立一个通用的机制,在设备或驱动被添加时,主动触发匹配过程,并在匹配成功后,以标准的顺序调用驱动的...
map
[toc] drivers/base/map.ckobj_map: 一个通用的设备号到内核对象的映射引擎本代码片段是Linux内核中一个相对底层但非常关键的通用映射子系统——kobj_map。其核心功能是提供一个可扩展的、基于回调的哈希表,用于将一个设备号(dev_t)高效地映射到一个内核对象(kobject)。这个机制是cdev(字符设备)、bdev(块设备)等许多与设备号相关的子系统的基础引擎。它通过一种链式哈希表和回调函数的设计,实现了设备注册、注销和查找的核心逻辑。 实现原理分析如代码开头的注释所言,这是一个历史悠久的设计,虽然性能可能不是最优,但其设计思想非常精巧。 核心数据结构 (kobj_map): probes[255]: 这是一个哈希表。它的大小是固定的255个桶(bucket)。 哈希函数: MAJOR(dev) % 255。它使用设备号的主设备号(Major number)对255取模,来决定一个设备应该被放入哪个桶中。 struct probe: 这是哈希表中的节点。它不是直接存储kobject,而是存储一个**“探测器”**...
gpiolib
[toc] 的内核对象gdev,并完成以下三件关键事情: 初始化设备对象: 确保gdev中的struct device成员被正确初始化。 创建字符设备: 在/dev目录下创建对应的gpiochipN字符设备节点,使用户空间程序可以通过文件I/O操作来访问GPIO。 创建sysfs接口: 在/sys/class/gpio目录下创建对应的gpiochipN目录和属性文件,提供一种基于文件的、用于管理和调试GPIO的接口。 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768...
simple-pm-bus
[toc] drivers/bus/simple-pm-bus.c 简单电源管理总线(Simple PM Bus) 通用的、轻量级的设备电源管理协调器历史与背景这项技术是为了解决什么特定问题而诞生的?simple-pm-bus 的诞生是为了解决在复杂的片上系统(SoC)中一个常见的、但缺乏标准化解决方案的问题:如何以一种通用、有序的方式管理一组相互关联的、但又不属于任何标准总线(如I2C, SPI)的设备的电源状态(主要是休眠与唤醒)。 在许多SoC设计中,存在大量简单的、直接挂在内存映射I/O(MMIO)上的设备。这些设备可能在逻辑上属于一个功能单元(例如,一个视频处理流水线上的多个IP核),它们需要按照特定的顺序进入休眠(suspend)或从中恢复(resume)。 在simple-pm-bus出现之前,处理这种情况通常依赖于: 平台代码中的硬编码:在板级支持文件(board file)中硬编码休眠/唤醒的调用顺序,这使得代码难以移植和维护。 驱动间的隐式依赖:驱动程序之间通过msleep等脆弱的方式来猜测和等待其他设备的状态。...
sysrq
[toc] drivers/tty/sysrq.c 内核魔法键(Magic SysRq Key) 系统的终极应急与调试工具历史与背景这项技术是为了解决什么特定问题而诞生的?Magic SysRq Key(魔法系统请求键)是为了解决一个系统管理员和内核开发者面临的终极难题:当系统完全冻结,无法通过网络(SSH)或本地终端响应时,如何进行诊断或安全地重启? 在系统严重死锁或负载极高的情况下,用户空间的程序、Shell、甚至内核的调度器都可能停止工作。然而,内核的底层部分,如键盘中断处理,可能仍然在运行。SysRq机制就是利用这个“一线生机”,提供了一个直接与内核底层进行通信的“后门”。它允许操作员通过一个特殊的键盘组合键,绕过所有上层软件栈,直接向内核发送预定义的命令,从而: 获取调试信息:在系统崩溃的瞬间,抓取任务状态、内存使用情况等快照。 执行应急操作:如同步磁盘、以只读方式重新挂载文件系统。 安全地重启系统:在别无选择时,执行一个比直接按电源键(硬重启)更安全的重启序列,最大限度地减少数据损坏的风险。 它的发展经历了哪些重要的里程碑或版本迭代? 源自...
sys
[toc] kernel/sys.c 系统信息与控制接口(System Information and Control) 内核的通用系统调用集合历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/sys.c 是Linux内核中历史最悠久、最基础的文件之一。它不是为了解决某一个单一、特定的技术问题而生,而是扮演着一个内核“工具箱”的角色。它实现了一大批杂项但至关重要的系统调用,这些系统调用为用户空间提供了一个与内核进行全局性、管理性和信息性交互的标准化接口。 这些系统调用解决的问题包括: 获取系统状态:如何让 top, free, uptime 等工具知道系统的负载、内存使用情况和运行时间?(sysinfo) 识别系统身份:程序如何知道自己运行在哪个操作系统版本、哪个硬件架构上?(uname) 控制系统生命周期:管理员如何安全地重启或关闭计算机?(reboot) 配置系统标识:系统启动时如何设置自己的主机名?(sethostname) 调整进程行为和资源:如何设置进程的调度优先级 (setpriority) 或资源限制 (setrlimit)? 细粒度...
bfq-iosched
[toc] block/bfq-iosched.c BFQ I/O调度器(Budget Fair Queueing) 追求极致公平与交互响应的重量级调度器历史与背景这项技术是为了解决什么特定问题而诞生的?BFQ(Budget Fair Queueing)I/O调度器的诞生是为了解决一个长期困扰Linux用户,尤其是桌面用户的核心问题:I/O密集型任务对系统交互响应能力的严重破坏。 在BFQ出现之前,当一个后台进程(如大型文件复制、软件更新、文件索引)开始疯狂读写磁盘时,用户会明显感觉到整个系统变得卡顿:启动应用程序变慢、窗口响应迟钝、甚至鼠标指针都会跳动。这是因为后台任务产生的海量I/O请求“淹没”了存储设备,导致前台交互式应用(如浏览器、文本编辑器)的关键读写请求必须排很长的队。 BFQ的核心目标就是实现进程间的I/O公平性,并优先保障交互式应用的低延迟。它不仅仅是调度I/O请求,更是在管理不同进程对I/O带宽的访问权,确保没有任何一个进程可以霸占整个存储设备。 它的发展经历了哪些重要的里程碑...
kyber-iosched
[toc] block/kyber-iosched.c Kyber I/O调度器 基于延迟目标的现代I/O调度器历史与背景这项技术是为了解决什么特定问题而诞生的?Kyber I/O调度器的诞生是为了解决一个在超高速存储设备(如NVMe SSD)上日益凸显的问题:传统的I/O调度器(如Deadline, CFQ)主要优化吞吐量或公平性,但在现代硬件上,软件排队本身成为了延迟的主要来源。 当存储设备快到可以在微秒级完成I/O时,如果内核软件栈中排队了过多的请求(即高队列深度),那么一个新到来的、关键的读请求可能会排在几百个已提交的请求之后,导致其总延迟变得很高。Kyber的设计目标是转变优化思路:不再间接地追求低延迟,而是直接将延迟作为一个可配置的、必须达成的目标。 它旨在回答这样一个问题:我们如何向设备施加恰到好处的压力,既能获得足够的吞吐量,又能确保绝大多数请求的完成延迟都低于一个预设的目标值? 它的发展经历了哪些重要的里程碑或版本迭代? Facebook (Meta) 的创新:Kyber最初由Facebook的工...







