compiler
[toc] include/linux/build_bug.hstatic_assert 静态编译警告123456789101112131415161718/** * static_assert - 在构建时检查整数常量表达式 * * static_assert() 是 C11 _Static_assert的包装器,具有 * little 宏魔术使消息成为可选的(默认为 * 测试表达式的字符串化)。 * * 与 BUILD_BUG_ON() 相反,static_assert() 可以在 global * 范围,但要求表达式为整数常量 * 表达式(即,__builtin_constant_p() 是不够的 * true 表示 expr)。 * * 另请注意BUILD_BUG_ON,如果条件为 * true,而 static_assert() 如果表达式为 *假。 */#define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)#define __static_assert...
atomic
[TOC] include/asm-generic/bitops/generic-non-atomic.h generic_test_bit 和 const_test_bit 是两个用于测试位图中某个位是否被设置的函数。它们的实现方式略有不同,主要体现在对 volatile 关键字的使用上。generic_test_bit 函数使用了 volatile 关键字,这意味着它会读取内存中的值,而不是使用寄存器中的缓存值。这对于多线程或中断上下文中的位操作非常重要,因为它确保了读取的是最新的值。const_test_bit 函数则不使用 volatile 关键字,这意味着它可以在编译时进行优化,适用于编译时常量的测试。两者的实现都使用了位操作来确定指定的位是否被设置。这里仅进行了读取操作,没有进行写入操作.所以不需要进行原子操作 generic_test_bit 这里具有volatile会在每次读取时都从内存中读取值,而不是进行优化 1234567891011121314/** * generic_test_bit - 确定是否设置了位 * @nr:要...
内存管理与访问
[toc] include/linux/cache.h: 提供与CPU缓存行对齐相关的宏,如 ____cacheline_aligned__cacheline_aligned 缓存行对齐 这个修饰符确保变量在内存中对齐到缓存行的边界上。缓存行对齐可以减少缓存行冲突,提高缓存命中率,从而提高系统性能。在多处理器系统中,缓存行对齐尤为重要,因为多个处理器可能同时访问相同的内存区域。通过对齐,可以减少缓存一致性协议带来的开销。 在多处理器系统中,缓存行对齐可以减少缓存一致性协议带来的开销,主要原因如下: 缓存一致性协议:在多处理器系统中,每个处理器都有自己的缓存,用于存储频繁访问的数据。为了确保所有处理器看到的数据是一致的,系统使用缓存一致性协议(如MESI协议)。当一个处理器修改了某个缓存行中的数据,其他处理器必须更新或失效其缓存中的相应数据。这种一致性维护会带来额外的开销。 缓存行对齐的好处 减少伪共享:伪共享(False Sharing)是指多个处理器访问同一个缓存行中的不同数据项,导致频繁的缓存一致性操作。通过缓存行对齐,可以确保每个处理器访问的...
内核支持与数据
[toc] Makefile宏LINUX_ARM_ARCH12345678910111213141516//arch/arm/Makefile# Note that GCC does not numerically define an architecture version# macro, but instead defines a whole series of macros which makes# testing for a specific architecture or later rather impossible.cpp-$(CONFIG_CPU_32v7M) :=-D__LINUX_ARM_ARCH__=7cpp-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7cpp-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6# Only override the compiler option if ARMv6. The ARMv6K extensions are# always a...
代码补丁
[TOC] static_call 和 jump_label 的区别及异同点static_call 和 jump_label 都是 Linux 内核中的优化机制,旨在提高性能,减少运行时的分支判断和间接调用开销。尽管它们的目标相似,但它们的实现方式和应用场景有所不同。 相同点 动态修改代码路径: 两者都支持在运行时动态修改代码路径,从而实现功能的启用或禁用。 通过修改指令(代码补丁),避免了传统的条件分支或间接调用的性能开销。 性能优化: 两者都旨在减少分支预测失败或间接调用的开销,适用于性能敏感的代码路径。 运行时灵活性: 两者都允许在运行时动态切换功能或行为,而无需重新编译或重启系统。 代码补丁机制: 两者都依赖于代码补丁(code patching)技术,通过修改内存中的指令来实现动态行为。 不同点 特性 static_call jump_label 主要用途 用于优化函数调用,将间接调用替换为直接调用。 用于动态启用或禁用代码块,优化条件分支判断。 优化的内容 函数调用路径(间接调用 → 直接调用)。 条件分支路径(条件判...
底层CPU与体系结构宏
[toc] include/asm-generic/rwonce.h: 提供 READ_ONCE() 和 WRITE_ONCE() 宏,防止编译器优化,保证单次读写的原子性1234567/* * 阻止编译器合并或重新获取读取或写入。还禁止编译器对 READ_ONCE 和 WRITE_ONCE 的连续实例重新排序,但前提是编译器知道某些特定排序。使编译器了解 Sequences 的一种方法是将 READ_ONCE 或 WRITE_ONCE 的两次调用放在不同的 C 语句中。 * * 这两个宏也适用于聚合数据类型,如结构体或联合体。 * * 它们的两个主要用例是:(1) 调解进程级代码和 irq/NMI 处理程序之间的通信,所有处理程序都运行在同一个 CPU 上,以及 (2) 确保编译器不会折叠、纺锤或以其他方式破坏不需要排序或与提供所需排序的显式内存屏障或原子指令交互的访问。 */ compiletime_assert_rwonce_type __native_word 是一个宏,用于检查给定类型是否是本机字长(通常是 32 位或 64 位)。如果类型不...
通用数学与位操作宏
[toc] include/asm-generic/div64.h : 提供64位除法操作的通用实现# arch/arm/include/asm/div64.h1234567891011121314151617181920212223242526272829/* * __div64_32() 的语义是: * * uint32_t __div64_32(uint64_t *n, uint32_t base) * { * uint32_t remainder = *n % base; * *n = *n / base; * return remainder; * } * * 换句话说,一个 64 位的被除数和一个 32 位的除数产生 64 位的结果和 32 位的余数。 为了以最佳方式实现这一点,我们覆盖了 lib/div64.c 中的通用版本,以使用完全非标准参数和结果调用约定的 __do_div64 程序集实现(当心)。 */static inline uint32_t __div64_32(ui...
fdt
[TOC] fdtdec 扁平设备树解析 devicetree devicetree-specification devicetree-specification.pdf 设备树BLLOB结构 123456789101112131415161718struct fdt_header { fdt32_t magic; /* magic word FDT_MAGIC */ fdt32_t totalsize; /* total size of DT block */ fdt32_t off_dt_struct; /* offset to structure */ fdt32_t off_dt_strings; /* offset to strings */ fdt32_t off_mem_rsvmap; /* offset to memory reserve map */ fdt32_t version; /* format version */ fdt32_t last_comp_version; /* last compatible ver...
通用工具与错误处理宏
[toc] include/linux/once_lite.h: (一次性调用) 提供确保某段代码在多核环境下只被精确执行一次的宏 每个宏仅在第一次使用时,执行函数功能.通过静态变量来实现一次性调用的功能 12345678910111213141516171819202122232425262728/* 调用一次函数。类似于 DO_ONCE(),但不通过jump label使用跳转标签修补。 */#define DO_ONCE_LITE(func, ...) \ DO_ONCE_LITE_IF(true, func, ##__VA_ARGS__)//通过静态变量来实现一次性调用的功能#define __ONCE_LITE_IF(condition) \ ({ \ static bool __section(".data..once") __already_done; \ bool __ret_cond = !!(condition); \ bool __ret_once = false;...
amba
[TOC] drivers/amba: Linux的AMBA总线与SoC设备驱动核心drivers/amba 目录是 Linux 内核中用于管理和驱动基于 AMBA (Advanced Microcontroller Bus Architecture) 总线的外设的核心框架。在现代基于 ARM 的片上系统 (SoC) 中,几乎所有的片上外设(如 UART、GPIO、SPI、I2C、定时器等)都挂载在 AMBA 总线上。因此,这个目录是 ARM SoC 平台驱动程序的基石。 一、 历史与背景这项技术是为了解决什么特定问题而诞生的? 在嵌入式系统中,特别是 SoC 中,外设不是像 PCI 或 USB 设备那样可以在运行时动态发现的(即非“热插拔”或“可枚举”的)。它们是静态地集成在芯片上的,其物理地址和中断号在芯片设计时就已经固定。 早期的 Linux 内核通过在 C 代码(board-*.c 文件)中硬编码这些“平台设备”(platform devices)的信息来支持它们。这种方法导致了巨大的问题: 内核与硬件紧密耦合: 每支持一款新的开发板,就需要编写一个新的 b...







