devres
[TOC] lib/devres.cdevm_ioremap_resource: 安全、自动管理的IO内存映射此函数是Linux内核中用于设备驱动程序开发的一个至关重要的辅助函数。它的核心作用是将一个从设备树(Device Tree)或平台数据中获取的、描述硬件寄存器物理地址的资源(struct resource), 安全地映射到内核可以访问的虚拟地址空间, 并且这个过程是完全由设备资源管理(devm)框架自动管理的。 该函数将一个典型的三步操作封装成了一个单一的、原子的API调用: 验证与请求: 它首先检查传入的资源是否是一个有效的内存区域(IORESOURCE_MEM)。然后, 它调用devm_request_mem_region向内核的资源仲裁系统”宣告”:”本驱动将要使用这段物理内存”。这可以防止两个不同的驱动程序意外地同时操作同一块硬件寄存器区域, 从而避免冲突。 内存映射: 在成功”占有”该物理内存区域后, 它调用底层的__devm_ioremap函数, 将这段物理地址映射为内核虚拟地址。这个返回的虚拟地址(类型为void __iomem *)就是驱动程序...
faux
[TOC] drivers/base/faux.c 虚拟设备总线(Faux Bus) 简化虚拟设备驱动的创建历史与背景这项技术是为了解决什么特定问题而诞生的?drivers/base/faux.c 文件所实现的 “Faux Bus”(虚拟总线)是一项较新的内核技术,在 Linux 6.14 内核中被合并。它的诞生主要是为了解决一个长期存在的内核开发“滥用”问题:将平台总线(Platform Bus)用于不属于平台设备(Platform Device)的场景。 内核维护者 Greg Kroah-Hartman 指出,多年来,许多开发者为了利用设备模型的便利性(如自动的驱动-设备绑定、probe/remove回调机制),会将一些纯粹的虚拟设备或简单的逻辑设备注册为“平台设备”。 这种做法在功能上可行,但从设计哲学上看是不正确的,因为平台设备本意是指那些在SoC(片上系统)上,无法通过正常总线(如PCI, USB)枚举发现的、有固定内存地址或硬件资源的设备。将纯虚拟设备(例如一个用于测试的dummy regulator)注册为平台设备,是一种概念上的滥用,...
dd
[TOC] drivers/base/dd.c 驱动延迟探测(Driver Deferred Probing) 管理设备依赖和初始化顺序drivers/base/dd.c 是Linux内核驱动核心(Driver Core)的一个关键文件,它实现并管理着**驱动延迟探测(Deferred Probing)**机制。这个机制是现代Linux内核设备模型正常运转的基石,其核心功能是解决设备驱动初始化过程中的依赖顺序问题。当一个设备的驱动在尝试“探测”(probe,即初始化)时,如果它所依赖的其他资源(如时钟、电源、GPIO等)尚未准备就绪,该机制允许该驱动的探测操作被安全地推迟,并在稍后合适的时机自动重试。 历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了解决在复杂的片上系统(SoC)中普遍存在的设备依赖和初始化顺序问题而诞生的。 复杂的硬件依赖:现代硬件中,一个设备(如一个I2C音频解码器)的正常工作通常依赖于多个其他硬件模块。例如,它需要一个时钟控制器为其提供时钟信号,需要一个电源管理芯片(PMIC)为其提供稳定的电压,还可能需要一个GPIO控...
firmware
[TOC] drivers/base/firmware 固件加载器核心(Firmware Loader Core) 内核与用户空间固件交互的桥梁历史与背景这项技术是为了解决什么特定问题而诞生的?drivers/base/firmware 目录中的代码实现了Linux内核的固件加载器(Firmware Loader)框架。这项技术的诞生是为了解决现代硬件驱动程序面临的几个核心问题: 许可(Licensing)问题:许多硬件设备(如Wi-Fi、GPU、网络适配器)需要运行一段专有的、非开源的“固件”代码才能正常工作。根据GPLv2许可证,这些二进制“固件块”(blobs)不能直接编译进开源的Linux内核镜像中。固件加载器提供了一种机制,将这些非开源固件与开源的驱动程序分离开来。 灵活性和可更新性:将固件硬编码到驱动程序中是一种非常僵硬的设计。当固件需要更新以修复bug或添加新功能时,用户将不得不重新编译并安装整个内核。固件加载器允许固件作为普通文件存放在文件系统中(通常在 /lib/firmware),使得更新固件就像替换一个文件一样简单,无需触及内核本身。 ...
platform
[TOC] drivers/base/platform.c 平台设备模型(Platform Device Model) 描述SoC内部设备历史与背景这项技术是为了解决什么特定问题而诞生的?drivers/base/platform.c 文件实现了Linux内核中的“平台设备模型”(Platform Device Model)。这项技术是为了解决嵌入式系统(特别是基于ARM等SoC的设备)中如何描述和管理那些不通过标准总线(如PCI, USB, I2C, SPI)枚举,而是直接由系统集成商(SoC厂商)通过内存映射地址或其他固定方式连接到CPU总线上的设备的问题。 在没有平台设备模型之前,这些SoC内部的设备(如GPIO控制器、UART控制器、时钟控制器、中断控制器、DMA控制器等)的驱动程序通常是零散地被编写的,并且管理方式非常底层和不统一。开发者需要手动解析设备树(Device Tree)或其他平台数据,获取设备的基地址、长度、中断号等信息,然后手动映射内存、申请中断,并将这些信息传递给驱动。这种方式存在以下问题: 代码冗余:每种类型的设备驱动都需要重复实...
regmap
[TOC] drivers/base/regmap Register Map API (Register Map API) 统一硬件寄存器访问接口历史与背景这项技术是为了解决什么特定问题而诞生的?drivers/base/regmap 目录中的代码实现了内核的“寄存器映射”(Register Map)API。这项技术的诞生是为了解决设备驱动程序中一个普遍存在的代码冗余和缺乏抽象的问题,特别是在通过I2C、SPI或内存映射I/O(MMIO)等简单总线访问硬件寄存器时。 在regmap出现之前,每个驱动程序都需要手动编写自己的底层I/O函数来与硬件通信。这导致了以下问题: 大量代码重复:几乎每个I2C/SPI设备驱动都包含着几乎相同的逻辑来构造消息、执行传输、检查错误。例如,通过I2C读取一个16位寄存器的代码在无数个驱动中被重复实现。 缺乏总线无关性:如果一个芯片(如音频编解码器)同时有I2C和SPI两种接口版本,开发者往往需要为它们编写两个几乎独立但I/O部分完全不同的驱动程序,或者在一个驱动中用大量的 if/else...
syscore
[toc] drivers/base/syscore.c 系统核心操作(System Core Operations) 管理核心系统组件的休眠与关闭历史与背景这项技术是为了解决什么特定问题而诞生的?drivers/base/syscore.c 文件实现了内核的“系统核心操作”(System Core Operations)框架。这项技术的诞生是为了解决一个非常底层且关键的问题:在系统范围的电源状态转换(如休眠、恢复、关闭)期间,如何以正确的顺序管理那些比普通设备更基础、更核心的系统组件。 常规的设备驱动程序通过其 .suspend 和 .resume 回调函数参与电源管理。然而,系统中存在一些组件,它们: 不是标准的“设备”:它们可能没有 struct device 实例,因此无法使用标准的设备电源管理(Device PM)框架。 具有严格的顺序依赖:它们的休眠和唤醒操作必须在所有普通设备之前或之后执行。 最典型的例子就是中断控制器(如ARM GIC)。在系统休眠时,必须在所有使用中断的设备都已经被挂起之后,才能挂起中断控制器本身。反之,在系统唤醒时,必须...
topology
[TOC] driver/base/topology.c CPU拓扑(CPU Topology) 通过sysfs导出CPU物理布局与亲和性信息本代码文件的核心功能是通过Linux的sysfs虚拟文件系统,向用户空间导出CPU的拓扑结构信息。这些信息包括物理封装ID(physical_package_id)、核心ID(core_id)、Die ID等,以及与当前CPU相关的“兄弟”CPU集合,例如共享同一个物理核心的其他线程(thread_siblings)或共享同一个物理封装的所有核心(package_cpus)等。用户和应用程序可以通过读取/sys/devices/system/cpu/cpuX/topology/目录下的文件,来获取处理器的硬件布局,从而进行性能优化、任务调度等高级操作。 实现原理分析该文件的实现严重依赖于宏定义(define_id_show_func, define_siblings_read_func)来自动化地生成大量功能相似的sysfs属性文件所需的回调函数。其基本工作流程如下: 宏定义生成函数:通过宏自动生成用于读取特定拓扑ID...
bus
[TOC] 全面解析Linux设备模型的核心枢纽:drivers/base/bus.cdrivers/base/bus.c 是Linux内核设备模型中负责实现**总线(Bus)**这一核心概念的代码文件。它提供了一套通用的API和数据结构,用于管理系统中的各种总线类型,其最核心的职责是充当设备(Device)和驱动(Driver)之间的“撮合者”(Matchmaker),建立它们之间的连接。 历史与背景这项技术是为了解决什么特定问题而诞生的? 在统一设备模型(详见drivers/base的解析)被引入之前,不同类型的总线(如PCI、USB)各自为政,都有一套自己独立的逻辑来注册设备、注册驱动,并进行匹配。这导致了以下问题: 代码冗余:每种总线都需要重复实现相似的设备列表管理、驱动列表管理以及遍历匹配的逻辑。 缺乏统一性:没有一个统一的接口来查询系统中所有的总线类型,或者在不同总线之间建立关联。 管理复杂:向系统中添加一种全新的总线类型,需要从头编写大量的管理和匹配代码,而非复用现有框架。 drivers/base/bus.c 的诞生,正是为了将这种通用的“...
base
[TOC] drivers/basedrivers/base 是Linux内核源代码中的一个核心目录,它并非一项独立的技术,而是内核设备模型(Linux Device Model)的基础实现。这个模型是一个统一的、抽象的框架,用于管理系统中的所有设备、驱动程序以及它们之间的关系。理解drivers/base就是理解现代Linux内核如何看待和管理硬件。 历史与背景这项技术是为了解决什么特定问题而诞生的? 在Linux内核2.5版本之前,内核中没有一个统一的结构来表示设备和驱动程序。驱动程序的编写和管理方式较为混乱,存在诸多问题: 电源管理困难:没有统一的设备层级结构,很难以正确的顺序对设备进行挂起(suspend)或恢复(resume)操作。例如,USB主控制器必须在USB设备之前被挂起。 代码冗余:每个子系统(如PCI, USB)都需要自己实现一套管理设备和驱动的机制,导致了大量的重复代码,尤其是在对象生命周期管理(如引用计数)和列表管理方面。 系统信息不透明:缺乏一种简洁、一致的方式从用户空间查看系统中所有设备的拓扑结构和状态。当时的 /proc 文件系统虽然提供...