dma
[TOC] drivers/dma DMA引擎与映射(DMA Engine & Mapping) 内核统一的直接内存访问框架历史与背景这项技术是为了解决什么特定问题而诞生的?DMA(Direct Memory Access,直接内存访问)框架的诞生是为了解决一个根本性的性能瓶颈问题,并为内核提供一个统一、可移植的解决方案。 解决CPU性能瓶颈:在没有DMA的系统中,当外设(如网卡、磁盘)需要与内存交换大量数据时,CPU必须亲自担当“搬运工”的角色。这种方式被称为PIO(Programmed I/O),CPU需要逐字节或逐字地从设备读取数据再写入内存,或者反之。对于高速设备,这会消耗大量的CPU周期,导致CPU无暇处理其他计算任务,严重影响系统整体性能。DMA技术通过引入一个专门的硬件控制器(DMAC),允许外设在没有CPU干预的情况下直接与内存进行数据传输,从而将CPU解放出来。 抽象硬件差异:不同的CPU架构和SoC平台,其DMA控制器的设计和编程接口千差万别。如果没有一个统一的软件框架,设备驱动程序的开发者将不得不为每一种不同的DMAC编写特定的...
gpio
[TOC] drivers/gpio GPIO子系统(General Purpose Input/Output) 内核与硬件I/O引脚交互的通用框架历史与背景这项技术是为了解决什么特定问题而诞生的?GPIO(通用输入/输出)子系统是为了在Linux内核中创建一个统一、抽象、可移植的框架来管理和控制硬件的GPIO引脚而诞生的。 在此框架出现之前,对GPIO的操作是混乱且与平台高度绑定的。每个SoC(片上系统)或主板都有自己独特的GPIO控制方式,驱动程序必须编写大量特定于硬件的代码才能操作一个引脚。 该子系统的诞生解决了以下核心问题: 消除平台特定代码:为内核提供一个标准的API,使得驱动程序(称为“消费者”)可以不用关心底层GPIO控制器(称为“提供者”或gpio_chip)的具体实现,就能请求、配置和读写一个GPIO引脚。 资源管理与冲突避免:一个GPIO引脚在系统中是独占性资源。 该框架提供了一套请求(request)和释放(free)机制,确保一个引脚在同一时间只能被一个驱动程序使用,从而避免了硬件冲突。 抽象硬件差异:不同的GPI...
iio
[toc] drivers/iio 工业I/O子系统(Industrial I/O) 统一的传感器数据采集框架历史与背景这项技术是为了解决什么特定问题而诞生的?IIO(Industrial I/O)子系统的诞生是为了解决Linux内核中一个长期存在的混乱问题:缺乏一个标准的、统一的框架来处理各种传感器和数据转换器(ADC/DAC)。 在此框架出现之前,这类设备的驱动程序散落在内核的各个角落,缺乏一致性: 滥用其他子系统:一些加速度计驱动程序为了方便,将自己伪装成一个input设备(如摇杆),但这在语义上是不正确的。input子系统是为用户输入事件(如按键、鼠标移动)设计的,而不是为了测量物理世界的数据。 使用私有的字符设备:许多驱动创建自己独特的字符设备接口,使用自定义的ioctl命令。这导致用户空间的应用程序必须为每一种不同的传感器编写特定的支持代码,无法通用。 滥用sysfs:一些驱动直接通过sysfs文件来暴露连续的数据流。Sysfs的设计初衷是用于传递少量、低频的配置信息或状态值(“一文件一值”),用它来读取高速的数据流...
i2c
[TOC] drivers/i2c I2C总线子系统(I2C Bus Subsystem) 管理I2C总线控制器与设备历史与背景这项技术是为了解决什么特定问题而诞生的?drivers/i2c 目录中的代码实现了Linux内核的I2C(Inter-Integrated Circuit)总线子系统。这项技术的诞生是为了解决在Linux系统中管理和访问大量通过I2C总线连接的外设时面临的代码冗余、缺乏抽象和可移植性差的问题。 I2C是一种简单、低速的两线(SDA -串行数据线, SCL -串行时钟线)串行总线,广泛用于连接微控制器和各种外围芯片(如传感器、EEPROM、RTC、PMIC等)。在没有统一子系统的情况下: 驱动与硬件耦合:每个需要访问I2C设备的驱动程序,都必须包含直接操作特定I2C控制器硬件(即“总线主控器”)的代码。这意味着为一个I2C传感器编写的驱动,在更换了主控芯片(如从NXP的SoC换到Broadcom的SoC)后就无法工作,必须重写。 代码重复:访问I2C总线的基本协议(起始/停止信号、发送地址、读写数据、ACK/NACK)是标准...
通用数学与位操作宏
[toc] include/asm-generic/div64.h : 提供64位除法操作的通用实现# arch/arm/include/asm/div64.h1234567891011121314151617181920212223242526272829/* * __div64_32() 的语义是: * * uint32_t __div64_32(uint64_t *n, uint32_t base) * { * uint32_t remainder = *n % base; * *n = *n / base; * return remainder; * } * * 换句话说,一个 64 位的被除数和一个 32 位的除数产生 64 位的结果和 32 位的余数。 为了以最佳方式实现这一点,我们覆盖了 lib/div64.c 中的通用版本,以使用完全非标准参数和结果调用约定的 __do_div64 程序集实现(当心)。 */static inline uint32_t __div64_32(ui...
input
[toc] drivers/input/input.c 输入子系统核心(Input Subsystem Core) 统一所有输入设备的事件处理框架历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术以及它所构建的整个输入子系统,是为了解决在Linux早期一个极其混乱的问题:缺乏一个统一的、标准化的方式来处理各种各樣的输入设备。 接口不统一:在输入子系统出现之前,每一种输入设备(PS/2鼠标、串口鼠标、AT键盘等)都有其自己独特的驱动程序,这些驱动会创建各自不同的设备文件(如/dev/psaux, /dev/mouse),并使用自己私有的数据协议。 应用程序复杂性:这意味着用户空间的应用程序(尤其是X Window System)必须编写大量复杂的、针对特定硬件的代码,才能从这些不同的设备文件中读取和解析输入数据。更换一个鼠标,就可能需要重新配置X Window。 可扩展性差:每当出现一种新的输入设备,不仅需要编写内核驱动,还需要修改上层的应用程序才能支持它。 输入子系统(由Vojtech Pavlik创建)的诞生,就是为了彻底解决这个乱局。...
leds
[TOC] drivers/leds LED子系统(LED Subsystem) 内核统一的LED设备控制框架历史与背景这项技术是为了解决什么特定问题而诞生的?LED子系统的诞生是为了解决在Linux内核中缺乏一个统一、抽象的LED管理方式的问题。在此框架出现之前,对LED的控制是零散且混乱的: 驱动代码重复:每个需要控制LED的驱动程序(例如,网卡驱动、SD卡驱动)都必须自己去实现操作GPIO或特定硬件寄存器的代码,导致大量功能相似的代码被重复编写。 缺乏统一的用户接口:用户无法以一种标准的方式来查看系统中有哪些LED,也无法在运行时改变它们的行为。控制LED的逻辑被硬编码在各自的驱动中。 逻辑与硬件强耦合:LED的“物理”控制(如何点亮它)和“逻辑”行为(为什么点亮它,例如因为网络活动)被混杂在一起。这使得更换LED硬件或改变其用途变得非常困难。 LED子系统的核心目标就是创建一个清晰的框架,将LED的物理控制与触发其亮灭的系统事件彻底解耦,并为用户空间提供一个标准的控制接口。 它的发展经历了哪些重要的里程碑或版本迭代?LED子系统的发展核心是触发器(Trigg...
mmc
[toc] drivers/mmc 多媒体卡(MultiMediaCard)子系统 SD/eMMC/SDIO设备驱动框架历史与背景这项技术是为了解决什么特定问题而诞生的?drivers/mmc 子系统是为了给Linux内核提供一个统一的、可扩展的框架来支持一整类基于**多媒体卡(MultiMediaCard)**规范及其衍生协议的设备而诞生的。这些设备包括: MMC (MultiMediaCard):一种早期的闪存卡标准。 SD (Secure Digital) Card:在MMC基础上发展而来的、目前最普及的移动存储卡,增加了安全特性和更高的性能。 eMMC (embedded MMC):将MMC控制器和NAND闪存封装在同一个BGA芯片中,作为一种“嵌入式”存储解决方案,被广泛用作智能手机、平板电脑和许多嵌入式设备的“硬盘”。 SDIO (Secure Digital Input/Output):一种扩展规范,允许SD插槽除了支持存储卡外,还能连接I/O设备,如Wi-Fi模块、蓝牙模块、GPS接收器等。 在没有这个统一框架...
OF
[TOC] OF在 Linux 内核中,of 通常是 Open Firmware 的缩写。Open Firmware 是一种硬件设备描述标准,用于描述设备树(Device Tree)。设备树是一种数据结构,用于以树状层次结构描述硬件的布局和配置,特别是在嵌入式系统和 ARM 架构中广泛使用。 of 表示与设备树(Device Tree)相关的驱动代码。 fdt.c 表示与 Flat Device Tree(FDT,扁平设备树)相关的实现。 设备树的作用设备树的主要作用是将硬件信息从内核代码中分离出来,使得内核可以通过解析设备树来获取硬件配置,而无需硬编码。这种方式提高了内核的可移植性和灵活性。 在 Linux 内核中,fwnode 和 node 是两种不同的结构体,分别用于描述硬件设备的固件信息和设备树节点信息。它们的主要区别在于用途和适用场景。 fwnode和node的区别1. fwnode_handlefwnode_handle 是一个通用的固件节点(firmware node)抽象,用于描述硬件设备的固件信息。它可以适配多种固件接口,例如设备树(Device Tree...
regmap
[TOC] regmapRegmap 简介Regmap 是 Linux 内核中的一个子系统,用于抽象和管理设备寄存器的访问。它为驱动程序提供了统一的接口,支持多种总线(如 I2C、SPI、MMIO 等)上的寄存器操作,同时提供了缓存、锁机制和调试功能。Regmap 的设计目标是简化驱动开发,减少重复代码,并提高寄存器访问的效率和安全性。 工作原理1. 核心概念 寄存器映射 (Register Map):Regmap 将设备的寄存器抽象为一个统一的映射,屏蔽了底层总线的差异。 寄存器缓存:Regmap 提供了可选的寄存器缓存机制,用于减少总线访问次数,提高性能。 寄存器访问控制:通过配置文件(struct regmap_config),可以定义哪些寄存器是可读、可写或易失的。 总线适配器:Regmap 支持多种总线(如 I2C、SPI、MMIO 等),通过总线适配器实现具体的读写操作。 2. 数据结构 struct regmap:表示寄存器映射的核心数据结构,包含寄存器的地址、值、缓存等信息。 struct regmap_config:配置寄存器映射的结构体,用于定义...