修复 Git 仓库损坏全记录
[toc] Git紧急救援:如何用最快方法回退上万个文件修改?一、问题的场景:当工作区陷入混乱想象一下这个场景:你正在一个庞大的项目中工作,不小心执行了一个全局查找替换命令,或者一个代码格式化工具“美化”了整个代码库,亦或是一次失败的合并操作…… 当你运行 git status 时,屏幕被密密麻麻的红色和绿色文字淹没,提示你有超过10000个文件被修改。 手动撤销是不可能的。此时,你需要一个快速、可靠且彻底的方法来“一键还原”,放弃所有不想要的本地修改,让你的代码仓库恢复到上一次提交时的干净状态。 本文将为你介绍三种不同级别的Git回退方案,并重点推荐一个最快、最彻底的“核弹级”操作,专门用于应对这种极端情况。 123456graph TD A["干净的工作区 (HEAD)"] --> B["一次错误的批量操作"]; B --> C["<b>灾难现场</b><br/>- 10000+ 文件被修改<br/>- 新增了大量临时文件<br/>- gi...
scatterlist
[toc] lib/scatterlist.c Scatter-Gather Lists 衔接虚拟内存与硬件DMA的桥梁历史与背景这项技术是为了解决什么特定问题而诞生的?scatterlist(分散/聚集列表)机制的诞生是为了解决现代操作系统中一个根本性的矛盾:软件(CPU)看到的内存视图与硬件(特别是DMA控制器)看到的内存视图之间的不匹配。 软件的视图:虚拟内存 在Linux中,无论是用户空间 (malloc) 还是内核空间 (kmalloc, vmalloc),程序申请到的一块看起来连续的大内存缓冲区,其底层的物理内存几乎总是不连续的。它是由许多个分散的、不相邻的物理页面(Page)拼凑而成的。 硬件的视图:物理内存 DMA(Direct Memory Access)控制器是一种硬件,它可以在没有CPU干预的情况下,直接在内存和I/O设备之间传输数据。为了工作,最简单的DMA控制器需要知道两件事:一个物理内存起始地址和一个长度。它假定这整块内存的物理地址是连续的。 核心矛盾:当驱动程序想让DMA硬件去处理一块由kmallo...
manage
[toc] kernel/irq/manage.c 中断请求管理(Interrupt Request Management) 内核中断线路的生命周期控制历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/irq/manage.c 内的代码是为了解决操作系统中一个基础且关键的硬件资源管理问题:如何对数量有限的硬件中断线(IRQ Lines)进行仲裁、抽象和生命周期管理。 在没有一个集中化管理机制的情况下,会面临诸多问题: 资源冲突:两个不同的设备驱动程序可能尝试使用同一个硬件中断号,导致中断信号无法被正确地分发,引发不可预测的系统行为。 缺乏抽象:驱动程序需要编写与具体中断控制器(如x86的APIC,ARM的GIC)高度耦合的代码来使能(enable)、禁用(disable)、屏蔽(mask)中断。这使得驱动代码变得不可移植。 动态性差:在不支持可加载模块和热插拔设备的早期系统中,中断的分配是静态的。但在现代系统中,当中断的属主(驱动模块)被加载和卸载时,系统必须有能力动态地分配和回收中断资源。 manage.c提供了一个中央管理器,它强制...
serial_core
[toc] include/linux/serial_core.hstruct uart_port: UART硬件端口的终极抽象本代码片段展示了Linux串行核心层(Serial Core)中最核心、最重要的数据结构——struct uart_port。这个结构体是内核中对一个物理串口硬件(如STM32上的一个USART外设)的完整软件抽象。它像一个“中央档案室”,汇集了描述和操作一个物理串口所需的所有信息:硬件资源(IO地址、中断号)、配置参数(时钟频率、FIFO大小)、状态变量(调制解调器线状态)、操作函数集(.ops指针)以及与其他内核子系统的链接(console, TTY state等)。任何一个串口驱动(如stm32-usart)的核心工作,就是在驱动probe阶段,正确地填充这个结构体的一个实例。 实现原理分析uart_port结构体的设计体现了Linux驱动模型的两大核心思想:数据驱动和抽象分层。 数据驱动: 结构体的大部分成员都是数据,而非代码。例如iobase, membase, irq, uartclk, fifosize等。驱动...
stm32-usart
[toc] drivers/tty/serial/stm32-usart.c涉及的寄存器及其作用12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970/* Register offsets */static struct stm32_usart_info __maybe_unused stm32f4_info = { .ofs = { .isr = 0x00, .rdr = 0x04, .tdr = 0x04, .brr = 0x08, .cr1 = 0x0c, .cr2 = 0x10, .cr3 = 0x14, .gtpr = 0x18, .rtor = UNDEF_REG, .rqr = UNDEF_REG, .icr = UNDEF_REG, .presc = UND...
stm32-dma
[toc] drivers/dma/stm32/stm32-dmamux.cSTM32 DMAMUX (DMA多路复用器) 驱动此代码片段是STM32 DMAMUX的完整平台驱动程序。它的核心作用是充当一个硬件”路由交换机”的软件抽象层。在复杂的STM32微控制器(如STM32H7系列)中, 有大量的外设(如SPI, I2C, UART)可以发起DMA请求, 但实际的DMA控制器(DMA1, DMA2)通道数量是有限的。DMAMUX就是处在这两者之间的一个硬件单元, 它能将任意一个外设的请求信号连接到任意一个空闲的DMA通道上。 这个驱动的根本原理是实现内核DMA框架中的dma_router(DMA路由)模式。当一个外设驱动(如SPI驱动)请求一个DMA通道时, 它并不知道DMAMUX的存在。它在设备树中的dmas属性指向的是DMAMUX设备, 而不是最终的DMA控制器。内核的DMA框架看到这个dmas属性后, 会识别出这是一个DMA路由, 于是它不会直接与DMA控制器驱动交互, 而是调用这个DMAMUX驱动注册的route_allocate回...
dmapool
[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 分配往往以页或更大粒度管理,小对象会产生明显内部碎片; 频繁分配...
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...
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,而是存储一个**“探测器”**...







