shell命令
[TOC] 语法if 条件语句 if:用于执行一个命令并根据其退出状态码执行不同的操作。 $(if $(KBUILD_OUTPUT),, ...): 这是一个条件判断语句。(if ...) 函数的语法是 $(if condition, then-part, else-part)如果 condition 为真,则执行 then-part;否则,执行 else-part。 环境变量 shift 命令用于移动参数 shift 命令用于移动参数。它会将所有参数左移一个位置,即 $2 的值赋给 $1,$3 的值赋给 $2,以此类推。$1 的值会被丢弃,而 $0(脚本名称)不会受到影响。 local 命令用于声明局部变量${parameter+word} 用于检查变量是否已经定义 一种参数替换语法,用于检查变量是否已设置并根据结果返回不同的值。以下是对这种语法的详细解释: 1${parameter+word} 如果 parameter 已设置且不为空,则结果为 word。 如果 parameter 未设置或为空,则结果为空字符串。 标志$BASH 指向的 she...
linux_makefile
[TOC] 阅读技巧 使用make V=1来查看详细的编译过程 使用make -p来查看所有的变量和规则 顶层makefile判断GUN make 版本 检查当前的 Make 版本以确保满足条件 如果 output-sync 不在其中,这意味着当前使用的 GNU Make 版本低于 4.0,因此代码会触发一个错误,提示用户需要 GNU Make 4.0 或更高版本,并显示当前的 Make 版本 $(MAKE_VERSION)。 123ifeq ($(filter output-sync,$(.FEATURES)),)$(error GNU Make >= 4.0 is required. Your Make version is $(MAKE_VERSION))endif 检测内部变量是否被覆盖 检查 $(MAKECMDGOALS) 变量中是否包含以 __ 开头的目标。$(MAKECMDGOALS) 是一个特殊变量,包含了命令行中指定的所有目标。如果发现有以 __ 开头的目标,代码会触发一个错误,提示这些目标仅供内部使用。这种检查有助于防止用户意外调用内部目标,确保构...
构建说明
[TOC] art-pi 构建命令12345678910111213141516171819202122232425262728293031export CROSS_COMPILE=arm-none-eabi- ARCH=armmake stm32_defconfigmake menuconfig > General setup [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support > Device Drivers > Block devices [*] RAM block device support (1) Default number of RAM disks (2048) Default RAM disk size (kbytes) > System Type (0xC0000000) (S)DRAM Base Address (0x02000000) (...
block
[TOC] Linux 源码中的 block 目录:块设备 I/O 的核心中枢block 目录是 Linux 内核 I/O 栈的心脏。它负责管理所有块设备(如硬盘驱动器 HDD、固态硬盘 SSD、U 盘等)的数据交换。这一层的主要目标是提供一个通用的、高效的框架,将上层文件系统和应用程序的 I/O 请求,转化为底层具体硬件驱动程序可以执行的操作。 一、 历史与背景这项技术是为了解决什么特定问题而诞生的? block 层的诞生是为了解决两个核心问题: 抽象与解耦:如果没有一个通用的块设备层,每个文件系统(如 ext4, XFS)都需要自己编写直接与各种硬盘驱动(SATA, SCSI, NVMe)对话的代码。这会导致代码冗余、开发复杂且难以维护。block 层提供了一个标准的接口,使得文件系统无需关心底层硬件的具体细节,反之亦然。 性能优化:对存储设备的随机访问通常效率很低,尤其是在机械硬盘上,会导致磁头频繁寻道,浪费大量时间。block 层通过引入 I/O 调度器 (I/O Scheduler),可以对传入的 I/O 请...
bio
[toc] include/linux/bio.hBIO 迭代器与数据段访问接口 (bio_iter, bio_advance_iter)核心功能该代码片段定义了一系列宏和static inline函数,它们共同构成了一个用于遍历和操作 struct bio(块 I/O 请求的基本单元)中数据段(bio_vec)的API。其核心功能是为块设备驱动提供一个标准、高效且安全的接口,用于: 访问当前数据段: 获取当前 I/O 进度(由 bio->bi_iter 迭代器所指向位置)的物理页、页内偏移和数据长度。 迭代遍历: 提供遍历 bio 中所有数据段的机制。 更新进度: 在驱动处理完一部分数据后,精确地更新 bio 的 bi_iter 迭代器,使其指向下一个待处理的数据位置。 状态查询: 提供辅助函数来查询 bio 的状态,例如数据方向(读/写)、是否包含有效数据等。 实现原理分析 迭代器设计模式: 这套 API 的核心设计思想是迭代器模式。struct bio 内部包含一个 struct bvec_iter bi_i...
blk-ioc
[toc] block/blk-ioc.c I/O上下文管理(I/O Context Management) 进程I/O优先级的关联与继承历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了解决在多任务操作系统中,如何区分和管理不同进程发起的I/O请求的重要性,从而实现更智能、更公平的I/O调度。 在blk-ioc.c(I/O Context)所代表的机制出现之前,内核的I/O调度器(I/O Scheduler)对所有进程发起的I/O请求几乎一视同仁。这会导致严重的问题: 优先级反转:一个高优先级的CPU密集型任务(如交互式桌面应用)可能会因为一个低优先级的后台I/O密集型任务(如文件索引、备份)而变得卡顿。后台任务产生的大量磁盘I/O请求会填满I/O队列,使得前台应用的关键数据读写请求需要等待很长时间。 资源争用不公:多个进程同时进行磁盘读写时,无法区分哪些进程的I/O应该被优先满足。例如,一个正在播放视频的媒体播放器和一个正...
blk-mq
[toc] block/blk-mq.c 多队列块层核心(Multi-Queue Block Layer Core) 现代存储I/O性能的基石历史与背景这项技术是为了解决什么特定问题而诞生的?blk-mq(Block Multi-Queue)框架的诞生是为了从根本上重构Linux的块设备层,以适应现代存储硬件的飞速发展,特别是高速闪存设备(SSD、NVMe)的出现。 传统的Linux块层(single-queue block layer)是为机械硬盘(HDD)设计的,其核心是一个per-device的单一请求队列。这种设计在HDD时代是合理的,因为磁盘的机械寻道时间是主要瓶颈。然而,随着能够处理数十万甚至数百万IOPS(每秒I/O操作数)的闪存设备的普及,这个单一队列的设计成为了新的、严重的性能瓶颈: 锁争用:在多核CPU系统上,所有核心提交I/O时都必须争抢保护这个单一队列的全局锁。这种锁争用导致CPU无法有效扩展,即使硬件有能力处理更多请求,软件层面也无法将请求高效地提交给硬件。 缓存行弹跳:对单一队列的频繁访问导致其数据所在的缓存行...
anon_inodes
[toc] fs/anon_inodes.c 匿名inode文件系统(Anonymous Inode Filesystem) 提供内核事件驱动的文件描述符历史与背景这项技术是为了解决什么特定问题而诞生的?这项技术是为了给那些纯粹基于内核内部事件、而没有实体文件系统后端的对象提供一个标准的文件描述符(File Descriptor)接口而诞生的。 在Linux“一切皆文件”的设计哲学下,将各种资源抽象为文件描述符,可以使用read(), write(), poll(), epoll()等一套统一的I/O接口来进行操作。 在anon_inodes出现之前,如果内核想提供一个事件通知机制(例如inotify),它可能需要实现一个迷你的、私有的伪文件系统,只为了创建一个inode和一个file对象返回给用户空间。 这导致了代码的重复和资源的浪费。 anon_inodes.c解决的核心问题是:如何以一种轻量级、标准化、且节约内存的方式,为内核子系统创建并返回一个功能性的文件描述符,而这个文件描述符背后并不对应任何磁盘上的文件或一个完整的伪文件系统。 它的发展经历了哪些重...
binfmt_script
[TOC] include/uapi/linux/elf.hElf32_Ehdr (内核中通常用 struct elfhdr): ELF文件头结构体这个结构体是ELF文件格式的“封面”和“目录”,它必须位于任何一个ELF文件的最开头。加载器(如内核)通过读取并解析这个结构体,来了解如何处理文件的其余部分。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687/* * 这是32位ELF文件头的标准定义. * 内核代码中通常会用 Elf32_Addr, Elf32_Half 等类型来保证在不同架构下的大小是固定的. */typedef struct elf32_hdr { /* * e_ident: 一个16字节的数组, 用于识别文件. 它包含了多个子字段. ...
buffer
[TOC] fs/buffer.c 缓冲区管理(Buffer Management) 块设备I/O的核心缓冲层历史与背景这项技术是为了解决什么特定问题而诞生的?fs/buffer.c 及其实现的**缓冲区缓存(Buffer Cache)**是Linux/Unix系统中最古老、最核心的性能优化机制之一。它最初是为了解决一个根本性的问题:物理磁盘I/O操作极其缓慢。 性能瓶颈:相比于CPU和内存的速度,机械硬盘的读写速度要慢上几个数量级。如果每次读写请求都直接访问磁盘,系统性能将严重受限。 提供抽象:内核需要一种方法来为文件系统提供一个统一的、基于块(Block)的设备视图,隐藏底层硬件的复杂性。 缓冲区缓存通过在物理内存(RAM)中缓存磁盘块的内容来解决这个问题。当内核需要读取一个磁盘块时,它首先检查该块是否已经在缓存中。如果在,就直接从内存中读取,避免了昂贵的物理I/O。同样,写操作可以先写入缓存(标记为“脏”),然后由内核在稍后的“最佳”时机批量写回磁盘。 它的发展经历了哪些重要的里程碑或版本迭代?缓冲区缓存的发展史是Lin...








