ext4
[toc] fs/ext4/super.c Ext4文件系统核心(Ext4 Filesystem Core) 文件系统的挂载与生命周期管理历史与背景这项技术是为了解决什么特定问题而诞生的?fs/ext4/super.c 是Ext4文件系统驱动的核心,它的诞生是为了解决一个根本性的问题:如何将一个原始的块设备(如硬盘分区)解释并初始化为一个可供操作系统使用的、有组织的文件系统实例。 这个文件中的代码是内核与一个具体Ext4文件系统进行首次“握手”的地方。它负责的任务包括: 引导(Bootstrap):当用户执行 mount 命令时,super.c 中的代码负责从块设备的预定位置读取超级块(Superblock)。超级块是文件系统的“元数据之母”,记录了该文件系统的所有宏观信息(如总大小、块大小、inode数量、魔数等)。 验证与初始化:验证读取到的超级块是否合法(例如,通过检查魔数),并根据其中描述的特性(如是否启用日志、扩展属性等)在内存中建立起管理该文件系统所需的所有数据结构。 生命周期管理:它不仅处理挂载(mount),还负责卸载(unmount)...
mbcache
[toc] fs/mbcache.c 扩展属性块缓存(Extended Attribute Block Cache) 加速文件系统元数据访问历史与背景这项技术是为了解决什么特定问题而诞生的?fs/mbcache.c 实现了一个通用的、基于内存的缓存,其核心目标是加速对存储在独立磁盘块中的文件系统元数据的访问。它专门为**扩展属性(Extended Attributes, xattrs)**的性能优化而设计。 在许多文件系统(如Ext3, Ext4)中,扩展属性(例如,SELinux的安全上下文、POSIX ACLs、用户自定义的元数据)并不总是与文件的inode存储在一起。当一个文件的xattrs过多或过大时,它们会被存储在一个或多个独立的磁盘块中。如果没有缓存,每次需要读取或写入这些xattrs时,文件系统都必须执行一次额外的、独立的磁盘I/O操作。对于元数据密集型的操作(例如,在一个包含大量文件的目录上运行 ls -Z),这会导致显著的性能下降。 mbcache 通过在内存中缓存这些扩展属性块,解决了这个问题。当文件系统需要访问一个xattr块时,它首...
hweight
[toc] include/asm-generic/bitops/const_hweight.hlib/hweight.c软件汉明权重计算:__sw_hweight 系列函数本代码片段提供了一组用于计算不同位宽整数(8、16、32、64位)汉明权重(Hamming Weight)的纯软件实现。汉明权重,又称“置位比特计数”(population count),指的是一个二进制数中 ‘1’ 的总个数。这些函数是内核中需要进行位操作统计时的基础工具,其实现采用了高效的、不依赖特定处理器指令的“分治”并行算法。 实现原理分析这些函数的核心是采用了一种经典的分治算法(Divide and Conquer),在对数时间内完成计算,远比逐位检查的方法高效。以 __sw_hweight32 为例,其算法步骤如下: 两比特分组求和:w -= (w >> 1) & 0x55555555; 0x55555555 的二进制表示为 01010101...。 (w >> 1) & 0x55555555 的作用是分离出...
fcntl
[toc] fs/fcntl.c 文件控制(File Control) 管理文件锁和文件描述符属性 历史与背景这项技术是为了解决什么特定问题而诞生的?fs/fcntl.c 实现的 fcntl() 系统调用是为了解决一个基本问题:在文件被打开之后,如何查询和修改其属性及状态。标准的 open(), read(), write(), close() 提供了对文件内容的基本I/O操作,但现实世界的应用程序需要更精细的控制能力,主要包括: 并发访问控制:当多个进程同时访问同一个文件时,如何防止数据损坏?这就需要一种机制来协调访问,即文件锁(File Locking)。 修改描述符行为:如何将一个阻塞的文件描述符(File Descriptor, FD)变为非阻塞的?如何防止一个打开的FD被子进程继承?这就需要对FD的属性进行管理。 复制文件描述符:如何创建一个新的FD,使其指向与现有FD相同的打开文件实例(struct file),例如用于重定向标准输入/输出。 fcntl() 被设计成一个多功能的“瑞士军刀”,通过一个单一的系统调用入口,提供了对上...
workingset
[toc] mm/workingset.c 工作集检测(Working Set Detection) 提升页面回收效率的热点内存识别机制历史与背景这项技术是为了解决什么特定问题而诞生的?mm/workingset.c 中的代码是为了解决传统页面回收算法(如vmscan.c中的两阶段LRU)的一个核心痛点:无法精确区分真正的“工作集”和短暂的、非核心的内存使用。 工作集(Working Set)指的是一个进程在当前阶段为了高效运行而需要频繁访问的内存页面集合。传统LRU算法通过active/inactive链表来近似这个集合,但存在以下问题: 抖动(Thrashing):当内存压力增大时,一个暂时不活动的进程(例如,用户切换到了另一个窗口),其工作集页面可能会被从active链表老化到inactive链表,并最终被回收。当用户切回该进程时,进程会遭遇大量的缺页中断(page faults),需要从磁盘或交换空间重新读取其工作集,导致系统响应缓慢,磁盘I/O飙升。workingset.c 的核心目标就是识别并保护这些被错误回收的工作集页面,从而抑...
vmscan
[toc] mm/vmscan.c 页面回收(Page Reclaim) 内核内存管理的核心压力调节器历史与背景这项技术是为了解决什么特定问题而诞生的?mm/vmscan.c 中的代码是为了解决计算机科学中最基本的问题之一:物理内存是一种有限资源。当系统运行的应用程序和内核本身需要的内存总量超过了可用的物理RAM时,操作系统必须有一种机制来释放一些当前已分配但“不那么重要”的内存,以便为新的、更紧迫的内存请求腾出空间。 如果没有页面回收机制,系统在内存耗尽时唯一的选择就是拒绝新的内存分配请求,这将导致应用程序崩溃或系统完全停止响应。vmscan.c 实现的页面回收(Page Reclaim)算法,其核心目标是在内存压力(Memory Pressure)下,智能地选择并回收内存页面,从而保证系统的持续运行和响应能力。 它的发展经历了哪些重要的里程碑或版本迭代?Linux的页面回收算法经历了重大的演进,以适应不断变化的硬件和工作负载: 早期的LRU:最初的Linux内核使用了相当简单的“最近最少使用”(Least Recently Used, LRU)算法。 两阶...
utsname_sysctl
[TOC] kernel/utsname_sysctl.c UTS命名空间与Sysctl接口 管理和暴露系统标识信息历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了提供一个标准化的、可在运行时动态查询和修改系统核心标识信息的机制而诞生的。这些标识信息,统称为UTS(UNIX Time-sharing System)名称,包括: 主机名 (Hostname) 和 域名 (Domainname):在网络中唯一标识一台机器。 操作系统发布版本 (OS Release) 和 版本号 (Version):允许软件检查其运行的内核版本,以确定兼容性或是否存在特定功能/错误。 硬件架构 (Machine):指明系统运行的CPU架构(如 x86_64, aarch64)。 utsname_sysctl.c 的核心任务是: 提供访问接口:允许用户空间程序和管理员通过 uname(2) 系统调用和 /proc/sys/kernel/ 文件系统接口来读取这些信息。 提供配置能力:尤其是对于主机名和域名,系统必须提供一种在运行时进行修改的方法,而无需重启...
seccomp
[toc] kernel/seccomp.c 安全计算模式(Secure Computing Mode) 系统调用防火墙历史与背景这项技术是为了解决什么特定问题而诞生的?Seccomp(Secure Computing Mode)是为了解决一个核心的安全问题而诞生的:如何安全地运行不可信的代码。 在复杂的软件环境中,一个进程被赋予了访问数百个系统调用(syscall)的能力,这些系统调用是用户空间程序与内核交互的接口。 然而,大多数程序在其整个生命周期中只需要使用这些系统调用中的一小部分。 如果一个程序(例如,一个处理外部输入的Web浏览器渲染进程)被恶意代码攻陷,攻击者就可以利用那些该程序本不需要、但内核依然暴露给它的系统调用来进一步攻击和破坏整个系统。 Seccomp通过提供一种机制来限制一个进程可以调用的系统调用集合,从而减少内核的攻击面。 它的核心思想是实施“最小权限原则”:只授予程序执行其核心功能所必需的最小权限集合。 这样,即使程序被攻破,攻击者能造成的损害也因为其可用的系统调用极其有限而受到严格控制。 这对于构建应用程序沙箱(sandbox)至关重要...
Linux内核kallsyms符号压缩的完整构建流程
@[toc] Linux内核kallsyms符号压缩的完整构建流程 1. 引言Linux内核的kallsyms机制是其自省(Introspection)和调试能力的核心基石。它允许内核在运行时将内存地址解析为可读的符号名称,这对于错误追踪(Oops messages)、性能分析和内核调试至关重要。然而,在一个现代内核中,符号数量可达数十万之多,直接以字符串形式存储将消耗数兆字节的宝贵内存。 为了解决这一问题,内核构建系统采用了一套精巧的多趟链接(Multi-pass Linking)和符号压缩(Symbol Compression)流程。此流程由scripts/link-vmlinux.sh脚本调度,并使用一个专门的宿主工具scripts/kallsyms来执行核心的压缩算法。本文将完整地、分步骤地剖析这一流程,从构建脚本的宏观调度到压缩工具的微观算法实现。 2. 宏观调度:scripts/link-vmlinux.sh的多趟链接整个kallsyms数据的生成过程并非一次完成,而是通过一个迭代收敛的过程,以确保最终嵌入内核的符号地址是完全准确的。这个过程巧妙地解决了“测量行为...
link-vmlinux
[toc] scripts/Makefile.vmlinux输出文件 .tmp_vmlinux2.kallsyms.S .tmp_vmlinux2.kallsyms.o .tmp_vmlinux2.syms 123-rw-rw-r-- 1 embedsky embedsky 285K Oct 5 10:38 .tmp_vmlinux2.kallsyms.o-rw-rw-r-- 1 embedsky embedsky 2.9M Oct 5 10:38 .tmp_vmlinux2.kallsyms.S-rw-rw-r-- 1 embedsky embedsky 625K Oct 5 10:38 .tmp_vmlinux2.syms .tmp_vmlinux2.syms截取一点的内容如下所示 12345678910111213141516171819202122232400000000 A cpu_v7m_suspend_sizec0008000 T _textc0008000 T stextc0008028 t __vet_atagsc0008...








