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 | 上电 (按下电源键) |