debug
[TOC] arch/arm/include/debug/stm32.Saddruart 添加debug串口地址1234.macro addruart, rp, rv, tmp ldr \rp, =CONFIG_DEBUG_UART_PHYS @ physical base ldr \rv, =CONFIG_DEBUG_UART_VIRT @ virt base.endm CONFIG_DEBUG_UART_PHYS 和 CONFIG_DEBUG_UART_VIRT1234567891011121314151617//arch/arm/Kconfig.debugconfig DEBUG_UART_VIRT default DEBUG_UART_PHYS if !MMUconfig DEBUG_UART_PHYS default 0x40011000 if STM32F4_DEBUG_UART || STM32F7_DEBUG_UART || \ STM32H7_DEBUG_UARTconfig STM32H7_DEBUG_UART b...
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失败,循环会重新尝试加载...
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...
kernel
[TOC] arch/arm/kernel/: Linux 32位ARM内核的体系结构特定实现arch/arm/kernel/ 目录是 Linux 内核中专门负责 32 位 ARM 架构体系结构相关代码实现的核心区域。它包含了将通用内核代码与 ARM 处理器及其外围硬件紧密结合的底层逻辑。简单来说,它是 Linux 内核在 ARM 平台上运行的“神经中枢和硬件适配器”。 一、 核心职责arch/arm/kernel/ 目录下的代码负责 Linux 内核在 ARM 架构上运行的所有关键底层功能,包括: 早期 CPU 初始化: 在主内核 C 代码开始执行后,进行更详细的 CPU 模式设置、缓存和 MMU (内存管理单元) 的初始化。 内存管理设置: 建立虚拟内存与物理内存的映射(页表),这是所有后续内存访问的基础。 异常与中断处理: 定义和处理 ARM 处理器产生的各种异常(如数据中止、预取中止、未定义指令、软件中断等)和中断请求。这是内核响应硬件事件和系统调用的核心机制。 系统调用分发: 提供用户空间应用程序通过软件中断(SWI/SVC ...
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中的函数指针就会被更新为指向基于这个硬件定时器的延迟实现。这种实现方式会读取当前定时器计数值...
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...
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代码层面进...
i2c
[TOC] drivers/i2c I2C总线子系统(I2C Bus Subsystem) 管理I2C总线控制器与设备历史与背景这项技术是为了解决什么特定问题而诞生的?drivers/i2c 目录中的代码实现了Linux内核的I2C(Inter-Integrated Circuit)总线子系统。这项技术的诞生是为了解决在Linux系统中管理和访问大量通过I2C总线连接的外设时面临的代码冗余、缺乏抽象和可移植性差的问题。 I2C是一种简单、低速的两线(SDA -串行数据线, SCL -串行时钟线)串行总线,广泛用于连接微控制器和各种外围芯片(如传感器、EEPROM、RTC、PMIC等)。在没有统一子系统的情况下: 驱动与硬件耦合:每个需要访问I2C设备的驱动程序,都必须包含直接操作特定I2C控制器硬件(即“总线主控器”)的代码。这意味着为一个I2C传感器编写的驱动,在更换了主控芯片(如从NXP的SoC换到Broadcom的SoC)后就无法工作,必须重写。 代码重复:访问I2C总线的基本协议(起始/停止信号、发送地址、读写数据、ACK/NACK)...
bus
[TOC] 全面解析Linux设备模型的核心枢纽:drivers/base/bus.cdrivers/base/bus.c 是Linux内核设备模型中负责实现**总线(Bus)**这一核心概念的代码文件。它提供了一套通用的API和数据结构,用于管理系统中的各种总线类型,其最核心的职责是充当设备(Device)和驱动(Driver)之间的“撮合者”(Matchmaker),建立它们之间的连接。 历史与背景这项技术是为了解决什么特定问题而诞生的? 在统一设备模型(详见drivers/base的解析)被引入之前,不同类型的总线(如PCI、USB)各自为政,都有一套自己独立的逻辑来注册设备、注册驱动,并进行匹配。这导致了以下问题: 代码冗余:每种总线都需要重复实现相似的设备列表管理、驱动列表管理以及遍历匹配的逻辑。 缺乏统一性:没有一个统一的接口来查询系统中所有的总线类型,或者在不同总线之间建立关联。 管理复杂:向系统中添加一种全新的总线类型,需要从头编写大量的管理和匹配代码,而非复用现有框架。 drivers/base/bus.c 的诞生,正是为了将这种...







