serial
[toc] drivers/serial 串行驱动核心(Serial Driver Core) 内核与UART硬件通信的统一框架历史与背景这项技术是为了解决什么特定问题而诞生的?Serial(串行)驱动框架的诞生是为了解决一个在计算机历史上长期存在的核心问题:如何为各种不同的UART(通用异步收发器)硬件提供一个统一、标准、可移植的软件接口。 UART是实现串行通信(如RS-232标准)的基础硬件,但不同厂商、不同年代的UART芯片,其寄存器布局、功能特性(如FIFO深度)和编程方式都存在差异。如果没有一个统一的框架: 驱动代码无法复用:内核开发者需要为每一种新的UART芯片编写一个完全独立的、从头到尾的驱动程序。 上层接口不统一:每个驱动可能会向上层(TTY子系统)暴露不同的行为,或者需要上层进行特殊的处理。 设备驱动与硬件强耦合:应用程序或内核的其他部分会与特定的硬件实现绑定,降低了整个系统的可移植性。 Serial驱动框架的核心目标就是创建一个抽象层,将这些硬件差异隐藏起来。它定义了一套标准的接口和数据结构,使得具体的UART硬件驱动(如经典的8250&...
tty
[TOC] drivers/tty TTY子系统(TTY Subsystem) Linux终端和串口的核心框架历史与背景这项技术是为了解决什么特定问题而诞生的?TTY子系统是Linux/Unix系统中历史最悠久、最核心的子系统之一。它的诞生是为了解决一个根本性的问题:如何为用户进程与各种文本输入/输出设备(即“终端”)之间提供一个统一、抽象的交互接口。 它主要解决了以下几个核心问题: 硬件的抽象:早期的计算机通过物理的电传打字机(Teletypewriter, TTY)进行交互。后来出现了各种串行终端(Serial Terminal)。TTY子系统将这些五花八门的硬件抽象成一个标准的字符设备,使得用户进程可以用同样的方式(read, write)与它们交互。 输入处理与行编辑:用户在终端上输入时,难免会打错字。TTY子系统引入了“线路规程”(Line Discipline)的概念,提供了一套通用的输入处理逻辑,包括行缓冲、退格(Backspace)删除、擦除整行(Ctrl+U)等编辑功能。这使得应用程序(如Shell)无需自己实现这些复杂的编...
chained_irq
[toc] include/linux/irqchip/chained_irq.hchained_irq_enter 链式中断进入123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869/* * 用于链式处理器的入口/出口函数,其中主IRQ芯片可能实现 * fasteoi或电平触发流控。 *//* * 这是一个静态内联函数,作为链式中断处理器的标准入口点。 * @chip: 指向顶层(父)中断的中断控制器芯片结构体。 * @desc: 指向顶层(父)中断的中断描述符。 */static inline void chained_irq_enter(struct irq_chip *chip, struct irq_desc *desc){ /* * 注释:FastEOI控制器在入口处无需任何操作。 * * 原理:检查...
drivers
[toc] drivers/irqchip/irqchip.cirqchip_init 初始化函数12345678910//.lds__irqchip_of_table = .; KEEP(*(__irqchip_of_table)) KEEP(*(__irqchip_of_table_end)) . = ALIGN(8);extern struct of_device_id __irqchip_of_table[];void __init irqchip_init(void){ of_irq_init(__irqchip_of_table); acpi_probe_device_table(irqchip);} drivers/irqchip/irq-nvic.cnvic_irq_init 初始化函数1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575...
irq_work
[toc] include/linux/irq_work.h__IRQ_WORK_INIT1234567#define __IRQ_WORK_INIT(_func, _flags) (struct irq_work){ \ .node = { .u_flags = (_flags), }, \ .func = (_func), \ .irqwait = __RCUWAIT_INITIALIZER(irqwait), \}#define IRQ_WORK_INIT(_func) __IRQ_WORK_INIT(_func, 0) kernel/irq_work.c IRQ上下文延迟工作(IRQ Context Deferred Work) 在安全时机执行来自中断的紧急任务历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/irq_work.c 实现的irq_work机制是为了解决一个非常特殊且棘手的内核同步问题:如何从一个“硬中断(Hard IRQ)”上下文中,安全地执行一个需要...
debug_locks
[TOC] debug_locks 各种锁的常用调试工具的通用位置: 自旋锁、rwlocks、mutex 和 rwsems。 debug_locks 的介绍debug_locks 是 Linux 内核中用于调试各种锁(如自旋锁、自读写锁、互斥锁和读写信号量)的工具。它提供了一种机制,用于检测锁的使用错误,并在发现问题时记录或报告相关信息。 特点 全局控制:通过全局标志 debug_locks,可以一次性启用或禁用所有锁的调试功能。 静默模式:支持通过 debug_locks_silent 实现“静默失败”,即在检测到锁错误时不打印任何信息到控制台。 原子操作:使用 xchg 等原子操作确保在多线程环境中安全地切换调试状态。 减少噪声:在检测到第一个锁错误后,可以关闭后续的调试输出,避免日志被大量错误信息淹没。 使用场景 锁错误检测: 在开发和调试阶段,用于检测锁的使用错误,例如死锁、锁未正确释放等问题。 适用于调试自旋锁(spinlock)、读写锁(rwlock)、互斥锁(mutex)和读写信号量(rwsem)等。 内核模块开发: 在开发内核模块时,debu...
local_lock
[toc] include/linux/local_lock.h Per-CPU数据锁(Lock for Per-CPU Data) 一种为保护Per-CPU数据而生的超轻量级锁历史与背景这项技术是为了解决什么特定问题而诞生的?local_lock是一种高度特化的、以性能为首要目标的锁,它的诞生是为了解决一个非常具体的问题:如何以最低的开销来保护Per-CPU(每CPU)数据。 Per-CPU数据是指内核为每个CPU都创建了一个独立副本的数据。理论上,一个CPU上的代码应该只访问自己的那份数据副本。在这种理想情况下,并发访问的来源只有两种: 抢占(Preemption):当前任务在访问Per-CPU数据时被一个更高优先级的任务抢占,而这个新任务也访问了同一个Per-CPU变量。 中断(Interrupts):一个硬中断或软中断在当前CPU上发生,其中断处理程序访问了同一个Per-CPU变量。 传统的解决方案是使用spinlock。但是,spinlock是为解决多CPU(SMP)间的并发而设计的,它涉及到昂贵的原子操作和可能导致缓存行争用的内存总线流量。...
rwlock
[toc] include/linux/rwlock.h 读写锁(Read-Write Lock) 允许多读者并发访问的同步原语历史与背景这项技术是为了解决什么特定问题而诞生的?读写锁(Read-Write Lock, rwlock)是为了解决一个非常普遍的并发访问模式的性能问题:对共享数据的访问是“读多写少”。 在使用简单的互斥锁(mutex)或自旋锁(spinlock)时,任何时候都只允许一个任务进入临界区,无论它是读取还是写入。这对于读操作来说是过度限制的,因为读操作本身不会修改数据,允许多个读者同时读取是安全的。如果一个数据结构被内核中成百上千个地方频繁地读取,而只被少数几个地方偶尔写入,那么使用互斥锁会导致所有读者被迫串行执行,极大地降低了系统的并发性能。 rwlock的诞生就是为了优化这种场景。它提供了一种更精细的锁定机制: 读锁(共享锁):允许多个读者同时持有读锁。 写锁(排他锁):与互斥锁一样,任何时候只允许一个写者持有写锁。 互斥规则:当有任何读者持有读锁时,写者必须等待;当有写者持有写锁时,所有读者和其他写者都必须等待。 它的发展...
softirq
[toc] kernel/softirq.c 内核中断下半部(Interrupt Bottom-Half) 核心实现历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/softirq.c 实现的软中断(softirq)机制是为了解决一个操作系统内核设计中的核心矛盾:中断处理程序的执行时间必须极短,但中断所触发的工作任务可能很耗时。 中断处理的紧迫性:硬件中断发生时,CPU会立即暂停当前工作,跳转到中断处理程序(Interrupt Service Routine, ISR,也称“上半部”/“Top Half”)。在执行ISR期间,通常会屏蔽掉当前CPU上的同级甚至所有中断,以保证处理的原子性和快速性。如果ISR执行时间过长,会导致系统无法响应其他新的硬件中断,增加系统延迟(Latency),甚至丢失中断事件。 任务的复杂性:然而,中断事件所触发的后续处理可能很复杂。例如,网卡收到一个数据包的中断,其后续处理包括解析协议栈、将数据包递交给上层应用等,这些都是耗时操作。 软中断机制就是为了将中断处理分割为两个部分而设计的: 上半部(Top H...
mutex
[toc] kernel/locking/mutex.c 互斥锁(Mutex) 内核中基本的睡眠锁实现历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/locking/mutex.c 实现的互斥锁(Mutex,Mutual Exclusion)是为了解决多任务内核中一个最基础、最普遍的并发控制问题:如何确保一段代码(临界区)在任何时刻最多只能被一个执行绪(线程或进程)执行,从而保护共享数据的完整性。 在没有互斥机制的情况下,如果多个CPU上的任务同时访问和修改同一个共享数据(如一个链表),就会导致数据损坏、状态不一致、内存泄漏等各种灾难性的后果。 mutex被设计为一种睡眠锁(Sleeping Lock),专门用于解决**进程上下文(Process Context)**中的互斥问题。它的诞生是为了与另一种锁——**自旋锁(Spinlock)**形成互补: 自旋锁适用于中断上下文或保护极短的、不容许睡眠的临界区。获取不到锁的任务会“自旋”(忙等待),浪费CPU。 如果临界区比较长,或者在临界区内需要调用可能导致睡眠的函数(如kmalloc(...








