Linux:文件系统结构与启动过程深度解析
Linux 核心知识体系:文件系统结构与启动过程深度解析
1. Linux 文件系统结构(FHS)
文件系统层次结构标准(Filesystem Hierarchy Standard,FHS) 是 Linux 操作系统中文件和目录布局的规范。它确保了不同 Linux 发行版之间的一致性,便于软件管理、系统维护和可移植性。
FHS 的核心理念是将系统文件和用户数据、静态数据和可变数据进行逻辑分离,以实现系统稳定性、可管理性和多用户兼容性。
1.1 FHS 主要目录及其用途
/(根目录)- 文件系统层次结构的起点,所有其他目录和文件都在其下。
- 只包含系统启动和运行所需的最少文件和目录。
/bin(用户二进制文件)- 所有用户都可用的基本命令,如
ls,cp,mv。这些命令是单用户模式下系统启动和维护所必需的。
- 所有用户都可用的基本命令,如
/sbin(系统二进制文件)- 系统管理员使用的基本系统管理命令,如
fdisk,mkfs,reboot。通常用于系统启动、恢复和维护。
- 系统管理员使用的基本系统管理命令,如
/etc(配置文件)- 所有系统范围的配置文件,如
/etc/passwd,/etc/group, 服务配置文件。通常是文本文件。
- 所有系统范围的配置文件,如
/dev(设备文件)- 设备文件,是操作系统与硬件设备交互的接口,如
/dev/sda(硬盘),/dev/tty0(终端)。
- 设备文件,是操作系统与硬件设备交互的接口,如
/proc(进程信息虚拟文件系统)- 虚拟文件系统,提供内核和进程的实时信息,如
/proc/cpuinfo,/proc/meminfo。内容在内存中动态生成。
- 虚拟文件系统,提供内核和进程的实时信息,如
/sys(系统文件系统)- 虚拟文件系统,提供结构化的内核数据和硬件设备信息,用于设备模型和驱动程序状态,如
/sys/class/net。
- 虚拟文件系统,提供结构化的内核数据和硬件设备信息,用于设备模型和驱动程序状态,如
/var(可变数据文件)- 在系统正常运行期间会频繁变化的数据,如
/var/log(日志文件),/var/tmp(比/tmp更持久的临时文件)。
- 在系统正常运行期间会频繁变化的数据,如
/tmp(临时文件)- 所有用户都可以写入的临时文件,通常在系统重启后会被清空。
/usr(Unix System Resources)- 包含大部分用户使用的程序和文件,通常是只读的共享数据,如
/usr/bin(大部分用户命令),/usr/lib(库文件)。 /usr/local: 本地安装的软件和数据,避免与系统自带的软件包冲突。/usr/share: 与架构无关的共享数据,如文档、man 手册。
- 包含大部分用户使用的程序和文件,通常是只读的共享数据,如
/opt(可选的应用程序软件包)- 用于安装附加的、独立的第三方应用程序软件包。
/home(用户主目录)- 所有普通用户的个人主目录,包含用户数据和配置文件。
/root(超级用户主目录)root用户(超级用户)的专用主目录。
/boot(引导加载程序文件)- 引导加载程序(如 GRUB)所需的文件以及 Linux 内核文件,如
/boot/vmlinuz。
- 引导加载程序(如 GRUB)所需的文件以及 Linux 内核文件,如
/mnt(临时挂载点)- 用于临时挂载文件系统,如 CD/DVD-ROM, USB 驱动器。
/media(可移动媒体设备挂载点)- 用于自动挂载可移动媒体设备,如 USB 闪存驱动器。
/srv(服务数据)- 包含特定服务的数据,如
/srv/www(Web 服务器数据)。
- 包含特定服务的数据,如
2. Linux 内核交互接口:VFS、/proc、/sys 与相关核心机制
为了实现用户空间和内核空间的安全高效交互,Linux 内核设计了一系列接口和机制,其中 虚拟文件系统 (VFS) 扮演核心角色,而 /proc 和 /sys 则是其重要实现。
2.1 虚拟文件系统机制(VFS)
VFS (Virtual Filesystem Switch) 是 Linux 内核的一个抽象层,它提供一个 统一的文件系统接口,让用户程序以相同方式访问不同类型的文件系统,屏蔽了底层文件系统的实现细节。
- 统一接口: 应用程序通过标准系统调用(
open(),read(),write(),close())与 VFS 交互。 - 兼容性: 新的文件系统类型可轻松集成,无需修改现有应用程序。
2.2 虚拟文件系统类型详解
2.2.1 procfs (/proc)
procfs 是 /proc 目录背后的虚拟文件系统,它是一个基于内存的、动态的、大部分只读的文件系统,用于提供关于 系统进程和内核状态的实时信息。
- 进程信息: 每个运行中的进程都有一个以其 PID 命名的子目录(如
/proc/1234),包含cmdline,exe,status等。 - 内核参数与状态: 通过
/proc/sys子目录暴露大量可读可写的内核参数,允许运行时调整内核行为。 - 虚拟化: 内容在内存中动态生成,不占用实际磁盘空间。
2.2.2 sysfs (/sys)
sysfs 是 /sys 目录背后的虚拟文件系统,在 Linux 2.6+ 内核中引入,旨在提供一个 更结构化、面向对象、易于编程的接口,用于暴露 内核的设备模型信息。
- 统一设备模型: 它是 Linux 设备模型的具体体现,将设备、驱动、总线等组织成层次化结构。
- 层次化结构:
/sys/bus/(总线类型),/sys/class/(设备类别),/sys/devices/(物理连接拓扑)。 - 设备属性: 每个设备目录下文件代表设备属性,可读写(如 MAC 地址、电源状态)。
- 事件通知: 与 udev 紧密协作,通过
netlink向用户空间发送设备状态变化通知。
2.2.3 tmpfs
tmpfs 是一种基于 RAM(内存)或 Swap(交换空间) 的虚拟文件系统,提供一个 高速、易失性的存储区域。
- 内存存储: 文件和目录存储在 RAM 中,读写速度快。
- 使用 Swap 空间: RAM 不足时,数据可交换到 Swap 分区。
- 易失性: 数据在系统重启后全部丢失。
- 动态调整大小: 根据需要动态增长和收缩。
- 常见挂载点:
/dev/shm(进程间通信),/run(运行时数据),/tmp(临时文件)。
2.2.4 devtmpfs
devtmpfs 是 tmpfs 的特殊变种,在 Linux 2.6.32+ 内核中引入,旨在 简化 /dev 目录的生成和管理。
- 动态设备节点: 内核在系统启动早期直接在内存中创建
/dev下的所有设备文件。 - 内核直接控制: 确保设备文件在引导早期就可用。
- 与
udev协作:devtmpfs创建基本设备文件,udev在此基础上提供更高级的命名、权限和自动化管理(如创建符号链接)。 - 内存存储,易失性: 数据在系统重启后清空。
2.3 相关核心机制
2.3.1 udev 机制
udev 是 Linux 中的 设备管理子系统。
- 动态设备节点创建: 当硬件插入或移除时,动态在
/dev下创建/删除设备文件。 - 基于规则的设备配置: 根据
/etc/udev/rules.d/中的规则,为设备文件分配固定名称、设置权限,并触发脚本。 - 用户空间守护进程: 监听内核发出的
netlink事件。 udevadm命令: 用于查询 udev 状态、测试规则、触发事件(如udevadm info,udevadm monitor)。
2.3.2 sysctl 机制
sysctl 是命令行工具,用于在运行时 检查和修改 /proc/sys 目录下暴露的内核参数。
- 查询参数:
sysctl -a。 - 设置参数:
sysctl -w net.ipv4.ip_forward=1。 - 永久设置: 将配置写入
/etc/sysctl.conf或/etc/sysctl.d/,然后用sysctl -p加载。
2.3.3 kmod 机制
kmod 是用于 管理 Linux 内核模块的工具集。内核模块可在运行时动态加载/卸载,扩展内核功能。
modprobe: 最常用,加载/卸载模块及其依赖项。insmod: 直接加载单个模块文件。rmmod: 卸载单个模块。lsmod: 列出已加载模块。depmod: 分析模块依赖关系。
3. Linux 启动过程深度解析:UEFI → GRUB2 → initramfs → systemd
Linux 系统的启动是一个多阶段协同工作的复杂过程。
3.1 UEFI/BIOS 阶段 (固件初始化)
系统启动的第一个环节,由主板固件负责。现代系统主要使用 UEFI。
- 初始化硬件: 执行 **POST (Power-On Self-Test)**。
- 启动设备选择: 根据启动顺序查找可引导设备。
- UEFI 独有特性:
- 支持 GPT 分区。
- **安全启动 (Secure Boot)**:验证启动链中组件的数字签名。
- **EFI 系统分区 (ESP)**:存放 EFI 应用程序(如引导加载器
grubx64.efi)。
- 流程: UEFI/BIOS 执行 POST → 找到并加载 ESP 中的 EFI 应用程序。
3.2 GRUB2 阶段 (引导加载器)
GRUB2 (GRand Unified Bootloader version 2) 是最常用的引导加载器。
- 多系统引导: 可识别和引导多个操作系统。
- 模块化设计: 灵活且强大。
- 支持多种文件系统: 可直接读取文件系统上的内核和
initramfs。 - 交互式菜单: 提供选择操作系统或修改启动参数的菜单。
- 流程 (UEFI): UEFI 执行
grubx64.efi→ GRUB2 读取grub.cfg→ 加载 Linux 内核映像 (vmlinuz) 和 初始内存文件系统 (initramfs) 到内存 → 将控制权交给内核。
3.3 initramfs (Initial RAM Filesystem) 阶段
在内核挂载根文件系统前,提供临时工具和驱动。
- 临时根文件系统: 压缩的 CPIO 归档文件,加载到内存中作为临时根文件系统。
- 提供早期驱动: 包含访问根文件系统所需驱动(如 LVM, 加密文件系统)和早期启动工具。
- 解压并挂载真根:
initramfs中的/init脚本负责加载驱动,找到并挂载真正的根文件系统,然后通过pivot_root或chroot切换控制权。
3.4 systemd 阶段 (系统初始化)
控制权最终移交给 /sbin/init,在现代 Linux 中通常是 systemd。
- PID 1 进程: systemd 是系统启动的第一个用户空间进程,PID 永远是 1。
- 服务管理器: 负责启动、停止、重启、监控所有系统服务。
- 并行启动: 采用并行化策略,大大加快启动速度。
- 基于 Unit 的配置: 使用
service,target,mount等 Unit 文件定义资源和启动行为。 - 日志管理 (journald): 统一的日志管理机制。
- 设备管理 (udev): 集成
udev进行动态设备管理。 - 流程: 内核启动 systemd → systemd 加载 Unit 文件 → 确定启动目标 → 解析依赖并并行启动服务 → 启动登录管理器 → 用户登录。
3.5 总结流程图:
1 | 上电 (按下电源键) |
