cred
[TOC] kernel/cred.c 凭证管理(Credential Management) 内核中任务身份与权限的核心历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术以及其核心数据结构struct cred,是为了解决在现代多用户、多进程操作系统中一个根本性的安全问题:如何安全、高效、无竞争地管理和访问一个任务(进程或线程)的身份和权限集合。 集中化身份信息:一个任务的“身份”是复杂的,它包含了用户ID(UID)、组ID(GID)、补充组列表、安全标签(如SELinux上下文)、权能(Capabilities)等一系列信息。在struct cred出现之前,这些信息分散地存储在task_struct(进程描述符)中。 解决竞态条件与锁争用:直接修改task_struct中的权限字段是一个巨大的安全隐患。例如,如果一个线程正在修改自己的UID,而另一个线程同时在检查这个UID以决定是否允许某个操作,就会产生严重的竞态条件。为了保护这些字段,task_struct需要一个锁,但这在高并发系统(如大型Web服务器)中会成为严重的性能瓶颈,因为权限检查是内...
async
[toc] kernel/async.c 内核异步函数调用(Asynchronous Function Calls) 一个简单的“发后即忘”式内核执行框架历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术以及其实现的异步函数调用(async)框架,是为了解决内核中一个特定的并发需求:以最简单的方式,将一个函数的执行推迟到一个独立的上下文中,而调用者无需等待其完成。 优化启动时间:这是async框架诞生的最主要驱动力。在内核启动过程中,有大量的初始化调用(initcalls)。如果严格按照顺序依次执行,会非常耗时。async框架允许内核将那些没有严格依赖关系的、耗时的初始化函数“并行化”,将它们提交到后台异步执行,而主启动流程可以继续进行。这显著缩短了系统的总启动时间。 降低关键路径延迟:在某些性能敏感的代码路径中(例如一个设备驱动的.probe函数),可能会有一些耗时但非必需的初始化步骤。通过async,可以将这些步骤“发后即忘”(fire-and-forget)地交由后台处理,使得关键路径函数可以更快地返回,提高系统响应速度。 提供比工作队列更简单的接...
exit
[TOC] kernel/exit.c 进程终结与资源回收(Process Termination and Resource Reclamation)历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/exit.c 内的代码是为了解决操作系统中最基本和最核心的问题之一:如何安全、彻底地终结一个正在运行的进程,并确保其占用的所有系统资源都被完全回收。 一个进程在运行时会占用各种系统资源,包括: 内存:进程地址空间(代码、数据、堆、栈)、页表。 文件描述符:打开的文件、套接字、管道等。 CPU时间:进程作为被调度的实体。 内核数据结构:如 task_struct、信号处理器、定时器等。 子进程关系:作为其他进程的父进程。 如果没有一个健壮、集中的退出机制,当进程结束时: 资源泄漏:内存、文件句柄等资源将无法被释放,随着时间推移会耗尽系统资源,导致系统崩溃。 产生僵尸进程:父进程需要一种机制来获知其子进程的退出状态。如果子进程直接消失,父进程将无法进行后续处理。 孤儿进程问题:如果一个父进程先于其子进程退出,这些子进程将成为“孤儿”,必须有一个机制来“...
cpu
[toc] include/linux/cpumask.hcpumask_check 验证当前cpu数量是否超过了配置的最大cpu数量,并返回cpu1234567891011121314151617// 验证当前cpu数量是否超过了配置的最大cpu数量static __always_inline void cpu_max_bits_warn(unsigned int cpu, unsigned int bits){#ifdef CONFIG_DEBUG_PER_CPU_MAPS WARN_ON_ONCE(cpu >= bits);#endif /* CONFIG_DEBUG_PER_CPU_MAPS */}/* verify cpu argument to cpumask_* operators *///验证当前cpu数量是否超过了配置的最大cpu数量static __always_inline unsigned int cpumask_check(unsigned int cpu){ //small_cpuma...
fork
[TOC] kernel/fork.c 进程创建(Process Creation) Unix/Linux的基石历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/fork.c 是Linux内核的心脏之一,它实现了进程创建的机制。这项技术是为了解决多任务操作系统中的一个根本问题:如何动态地创建新的、独立的执行流(即进程)。 在单任务系统中,整个系统只有一个执行上下文。为了实现并发和多用户,系统必须有能力创建新的进程。Unix的设计者为此提出了一个极其优雅且强大的模型:fork()。 克隆与变形(Fork-and-Exec):fork()的核心思想不是从零开始创建一个空进程,而是克隆(Clone)当前进程。子进程在创建的瞬间,几乎是父进程的一个完美副本(拥有相同的内存映像、打开的文件等)。然后,子进程通常会通过exec()系统调用来加载并执行一个新的程序,从而“变形”为一个完全不同的进程。 上下文继承:这种模型的强大之处在于子进程可以继承父进程的上下文(如环境变量、文件描述符),这使得像Shell中的管道(|)和I/O重定向(>...
ksysfs
[TOC] kernel/ksysfs.c Sysfs 内核对象接口(Sysfs Kernel Object Interface) 将内核对象(kobject)层次结构展现为文件系统的核心实现历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/ksysfs.c 是实现 sysfs 文件系统的核心。sysfs 的诞生是为了解决在它之前的 /proc 文件系统所面临的结构混乱和信息冗余问题,并为Linux 2.6内核中引入的全新**统一设备模型(Unified Device Model)**提供一个干净、结构化的视图。 ksysfs.c 旨在解决以下核心问题: 反映内核内部结构:内核的设备模型是一个层次化的树状结构(设备连接在总线上,驱动绑定到设备上)。需要一种机制能将这种内在的、面向对象的层次关系精确地反映到用户空间的文件系统中。 提供稳定的ABI:用户空间工具(最著名的是udev)需要一个稳定、可预测的接口来发现设备、查询其属性并响应设备的热插拔事件。/proc 中杂乱无章的文件和格式使得这项工作非常脆弱。 机制与策略分离:ksysfs.c 提供“机...
iomem
[TOC] include/linux/ioport.hIORES_DESC: I/O 内存资源描述符枚举此代码片段定义了一个名为 IORES_DESC 的枚举类型。它的核心作用是为内核中不同类型的物理内存区域 (I/O Memory Resource) 提供一个标准化的、唯一的分类标识符 (即描述符)。这些描述符使得内核代码 (例如 region_intersects() 函数) 不仅可以按地址范围搜索内存区域, 还可以按其特定用途进行搜索和识别。 在单核无MMU的STM32H750平台上的原理与作用 在STM32H750这样的嵌入式系统中, 物理内存映射相对简单, 但内存区域的划分和用途管理依然至关重要。虽然该枚举中定义的许多描述符与PC架构相关 (如ACPI, CXL), 在STM32平台上不会被使用, 但其中有几个对嵌入式系统是核心且非常重要的: IORES_DESC_RESERVED 和 IORES_DESC_SOFT_RESERVED: 这两个描述符在基于设备树的嵌入式系统中至关重要。当在设备树 (.dts 文件) ...
memory_barrier
[TOC] 内存屏障(Memory Barrier) 确保并发编程中的内存操作顺序历史与背景这项技术是为了解决什么特定问题而诞生的?内存屏障(Memory Barriers),也被称为内存栅栏(Memory Fences),它的诞生是为了解决在多处理器(多核)系统上并发编程时,由编译器和处理器为了提升性能而引入的**指令重排序(Instruction Reordering)**所导致的程序执行结果不确定性问题。 具体来说,它要解决以下两个层面的重排序问题: 编译器重排序:在编译期间,编译器为了优化代码,可能会在不改变单线程程序最终结果的前提下,调整指令的执行顺序。 处理器重排序:在运行时,现代CPU为了最大化指令流水线的效率,普遍采用**乱序执行(Out-of-Order Execution)**技术。 此外,多核CPU各自拥有独立的缓存(Cache)和存储缓冲区(Store Buffer),导致一个核心对内存的写入操作,不会立即对其他核心可见,从而造成内存可见性问题。 在单线程程序中,这些优化通常是透明且无害的。 但在多线程并发环境中,一个线程依赖于另一线程的操作顺序...
nsproxy
[TOC] kernel/nsproxy.c 命名空间代理(Namespace Proxy) 管理进程的命名空间视图历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/nsproxy.c 及其关联的 struct nsproxy 结构是为了解决在 Linux 内核中**高效、集中地管理一个进程所处的多个命名空间(Namespace)**的问题而诞生的。 在命名空间机制引入之前,所有进程共享一个全局的系统视图(单一的文件系统树、进程ID空间、网络协议栈等)。为了实现操作系统级的虚拟化(即容器技术),Linux 逐步引入了多种类型的命名空间,允许进程拥有自己独立的系统资源视图,实现进程间的隔离。 随着命名空间种类的增加(mount, UTS, IPC, PID, network, user, cgroup等),一个进程的“上下文”变得复杂,它由其所属的一组命名空间共同定义。这就带来了新的管理问题: 管理复杂性:task_struct(进程描述符)中如果为每种命名空间都保存一个单独的指针,会使得结构体膨胀,并且在进程创建、复制、销毁时需要对众多指针进行单独...
notifier
[TOC] kernel/notifier.c 内核通知链(Kernel Notifier Chains) 实现内核子系统间的解耦通信历史与背景这项技术是为了解决什么特定问题而诞生的?内核通知链(Notifier Chains)机制的诞生,是为了解决在 Linux 这样一个庞大而复杂的单体内核(Monolithic Kernel)中,不同子系统之间低耦合的异步通信问题。 在内核中,一个子系统发生的事件(如网络设备状态变化、CPU上线/下线、模块加载/卸载)往往需要通知其他多个、在编译时甚至不知道存在的子系统。 如果采用直接函数调用的方式,将会导致子系统之间产生紧密的耦合关系,使得代码难以维护和扩展。例如,网络设备子系统在网卡注册时不应硬编码去调用IP层、桥接层等所有可能关心此事件的模块代码。 为了避免这种情况,内核引入了通知链机制,它采用了一种**发布-订阅(Publish-Subscribe)**的设计模式。 发布者(Publisher):事件发生的子系统,它只管向一个“事件通道”(即通知链的头部)发布通知。 订阅者(Subscriber)...








