lds
[TOC] arch/arm/Makefile: 32位ARM架构的构建总指挥arch/arm/Makefile 是 Linux 内核 Kbuild 系统中专门为 32 位 ARM 架构服务的顶级 Makefile。它不是一个独立的可执行脚本,而是被主 Makefile 包含(include)进去的。它的核心职责是定义 ARM 架构独有的构建规则、配置编译选项,并将 Kconfig 中选择的平台配置转化为实际的构建命令。 可以将其视为一个“总指挥官”,它接收来自 .config 文件的战略指令,然后向编译器、链接器等“部队”下达精确的战术命令,以确保最终能为特定的 ARM 平台构建出正确、高效的内核。 一、 核心角色与职责 定制化主构建流程: 内核的主 Makefile 定义了通用的构建目标(如 vmlinux, modules)。arch/arm/Makefile 则对这些目标进行“重载”或“定制”,添加 ARM 架构特有的依赖和命令。 配置翻译官: 将 .config 文件中由 Kconfig 系统生成的高层配置选项(例如 CONFIG_ARCH_BC...
mm
[TOC] arch/arm/mm: 解剖Linux的NOMMU内存模型arch/arm/mm 目录包含了 ARM 架构的内存管理代码。在典型的带 MMU 的系统中,它的主要职责是处理虚拟内存、页表、TLB 管理等。但是,当内核被配置为在没有 MMU 的处理器(如 ARM Cortex-M 系列)上运行时,这个目录的功能会发生根本性的变化。 在 NOMMU 模式下,arch/arm/mm 的核心任务不再是管理复杂的虚拟地址空间,而是直接管理一个扁平的、统一的物理地址空间。 一、 NOMMU 的核心概念在深入代码之前,必须理解 NOMMU 环境下的几个基本事实: 单一扁平地址空间: 内核、所有用户进程、I/O 内存都共享同一个物理地址空间。不存在虚拟地址到物理地址的转换。一个指针的值就是它在物理内存中的真实地址。 无内存保护: 由于没有 MMU,处理器无法在硬件层面阻止一个进程访问另一个进程或内核的内存。任何一个有缺陷的应用程序都可以直接读写内核内存,导致整个系统崩溃。 受限的进程模型: 传统的 fork() 系统调用(它依赖于写时复制技术,而这又...
process
[TOC] processarch/arm/include/asm/current.h 返回__current的值,__current是一个全局变量,在arch/arm/kernel/process.c中定义 __current是一个指向当前进程的指针,在内核中,每个进程都有一个task_struct结构体,该结构体包含了该进程的所有信息 12345678910111213141516171819202122//arch/arm/kernel/process.casmlinkage struct task_struct *__current;EXPORT_SYMBOL(__current);static __always_inline __attribute_const__ struct task_struct *get_current(void){ struct task_struct *cur;#if __has_builtin(__builtin_thread_pointer) && defined(CON...
lib
[TOC] arch/arm/include/asm/delay.h该文件的核心原理是提供一个可插拔的、分层的延迟实现机制。它设计了一个抽象的arm_delay_ops操作函数集, 允许在系统启动时根据可用的硬件资源来选择并注册最优的延迟方法。 对于没有精确硬件定时器的旧系统: 它会回退到一种基于”每秒循环数”(loops_per_jiffy)的校准循环方法。内核在启动时会测量在一个系统时钟节拍(jiffy)内, CPU能执行多少次空循环, 从而计算出一个近似值。udelay的实现会根据这个校准值来计算需要执行多少次循环才能达到指定的微秒延迟。 对于拥有高精度硬件定时器的新系统(如STM32H750): 系统启动代码(通常是特定于板卡的平台代码)可以使用register_current_timer_delay函数来注册一个高精度的定时器(例如ARM Cortex-M内核自带的DWT周期计数器CYCCNT)。一旦注册成功, arm_delay_ops中的函数指针就会被更新为指向基于这个硬件定时器的延迟实现。这种实现方式会读取当前定时器计数值...
sys_call_table
Linux内核ARM架构下sys_call_table的自动化生成机制剖析1. 引言在Linux操作系统内核中,系统调用(System Call)构成了用户空间与内核空间交互的基础接口。为了高效地将用户空间传递的系统调用号(System Call Number, SCN)映射至内核中相应的服务例程,内核在内部维护了一个核心数据结构——系统调用表。对于ARM架构,此表定义为sys_call_table,其本质是一个函数指针数组。 维护这样一个包含数百个条目,且需兼容多种应用程序二进制接口(Application Binary Interface, ABI)的数组,是一项复杂且易错的任务。任何手动的编辑都可能引入调用号与函数指针不匹配、ABI兼容性层实现错误或表大小同步失败等严重问题。为规避此类风险,Linux内核采用了一套高度自动化的代码生成机制。本文旨在以严谨的技术视角,对ARM架构下sys_call_table从源定义文件到最终二进制镜像中符号的全过程,进行深入、详尽的剖析。 2. sys_call_table 自动化生成流程sys_call_table的构建并非在C代码层面进...
boot
[TOC] arch/arm/boot: Linux 32位ARM架构的启动基石arch/arm/boot 目录是 Linux 内核源码中专门为 32 位 ARM 架构(AArch32)设计的启动代码所在地。它的核心使命是充当引导加载程序(Bootloader,如 U-Boot)与体系结构无关的通用内核代码之间的桥梁。这个目录下的代码负责处理内核启动最初始、最底层的阶段,为 C 语言环境的建立和主内核的执行做好万全准备。 一、 核心职责arch/arm/boot 目录下的代码和构建脚本共同完成了以下几项至关重要的任务: 生成可启动的内核镜像: 该目录下的 Makefile 是构建过程的核心,它负责将编译好的内核 vmlinux(一个 ELF 格式的文件)进行处理,最终生成 Bootloader 可以直接加载和执行的镜像格式,最常见的有 zImage 和 uImage。 内核解压缩: 为了减小存储体积和加快加载速度,内核镜像通常是经过压缩的。arch/arm/boot 包含了一个微型的、自解压的前端程序(Decompressor)。当 Bootloader...
include
[TOC] arch/arm/include/asm/cache.h__read_mostly 大多数读取 __read_mostly用于标记大多数读取的变量,在编译时会将该变量放到.data..read_mostly段中 1#define __read_mostly __section(".data..read_mostly") __read_mostly的作用是将变量放到.data..read_mostly段中,该段在内核启动时会被清零,所以该变量在内核启动时会被清零 arch/arm/include/asm/cmpxchg.harch_xchg_relaxed __arch_xchg 交换数据的逻辑都一样 使用ldrexb加载数据,它还会设置一个标志,表示该地址被标记为“独占访问”,以便后续的存储操作可以检查是否有其他处理器访问了该地址。 使用strexb存储数据,如果成功,返回0;如果失败,返回1,并且会清除“独占访问”标志。 如果strexb失败,循环会重新尝试加载...
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 初始化函数1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859...
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控制器在入口处无需任何操作。 * * 原理:检查irq...
softirq
[toc] kernel/softirq.c 内核中断下半部(Interrupt Bottom-Half) 核心实现历史与背景这项技术是为了解决什么特定问题而诞生的?kernel/softirq.c 实现的软中断(softirq)机制是为了解决一个操作系统内核设计中的核心矛盾:中断处理程序的执行时间必须极短,但中断所触发的工作任务可能很耗时。 中断处理的紧迫性:硬件中断发生时,CPU会立即暂停当前工作,跳转到中断处理程序(Interrupt Service Routine, ISR,也称“上半部”/“Top Half”)。在执行ISR期间,通常会屏蔽掉当前CPU上的同级甚至所有中断,以保证处理的原子性和快速性。如果ISR执行时间过长,会导致系统无法响应其他新的硬件中断,增加系统延迟(Latency),甚至丢失中断事件。 任务的复杂性:然而,中断事件所触发的后续处理可能很复杂。例如,网卡收到一个数据包的中断,其后续处理包括解析协议栈、将数据包递交给上层应用等,这些都是耗时操作。 软中断机制就是为了将中断处理分割为两个部分而设计的: 上半部(Top Half...