Linux内核调优与系统启动流程完全指南

前言

作为一名Linux运维工程师,你是否曾经遇到过这些问题:系统无法正常启动、内核模块加载失败、服务器响应缓慢、或者root密码忘记无法重置?这些问题的背后,都涉及到Linux内核管理和系统启动流程的知识。

本文将系统性地讲解Linux内核的组成、内核模块管理、系统调优、以及完整的启动流程和故障修复方法,帮助你建立起从底层到应用层的完整知识体系。


一、内核:操作系统的灵魂

1.1 内核的作用

一个完整的操作系统 = 内核 + 应用程序。内核是操作系统的核心,它的主要职责包括:

  1. 识别硬件并初始化系统
  2. 资源分配(CPU、内存、I/O等)
  3. 识别文件系统和网络协议
  4. 提供安全功能(权限管理、防火墙、SELinux等)

1.2 内核的组成

Linux系统可以同时存在多个内核版本,内核文件通常位于:

复制代码
[root@lab ~]# ll /boot/vmlinuz-5.14.0-362.8.1.el9_3.x86_64

除了内核本身,还有一个重要组成部分------内核模块


二、内核模块:给内核插上功能的翅膀

2.1 什么是内核模块?

内核模块是可以动态插入内核的代码片段,为内核提供特定功能。它的设计理念很巧妙:

  • 优势:可以动态加载和卸载,按需启用功能,减少内核体积
  • 缺点:如果多个模块修改了同一位置的代码,可能导致内核崩溃

内核模块以.ko.ko.xz为后缀,存放在:

复制代码
/usr/lib/modules/$(uname -r)/kernel/

2.2 内核模块管理命令

查看已加载的模块:

复制代码
[root@lab opt]# lsmod | grep cdrom
cdrom               90112  2 isofs,sr_mod

查看模块详细信息:

复制代码
[root@lab opt]# modinfo vmxnet3

加载模块:

复制代码
[root@lab opt]# modprobe sr_mod

卸载模块(注意:被使用的模块无法卸载):

复制代码
[root@lab opt]# modprobe -r sr_mod

2.3 实战:安装硬件驱动

当系统无法识别新硬件(比如Intel网卡)时,需要手动安装驱动:

  1. 前往硬件官网下载Linux驱动程序源码包

  2. 解压并编译,生成.ko内核模块文件

  3. 使用modprobe加载模块

    [root@lab ~]# cd ice-2.6.6/
    [root@lab ice-2.6.6]# ls
    COPYING ddp ice.7 ice.spec src README ...

    查看README获取编译安装帮助


三、内核参数调优:让系统飞起来

3.1 /proc虚拟文件系统

/proc目录是一个虚拟文件系统,反映系统运行时的状态:

复制代码
/proc/cpuinfo      # CPU信息
/proc/meminfo      # 内存信息
/proc/partitions   # 磁盘分区信息
/proc/filesystems  # 文件系统信息
/proc/sys/         # 内核参数(重点!)

3.2 sysctl命令:内核参数的调节器

查看所有内核参数:

复制代码
[root@lab ~]# sysctl -a

查看特定参数(以swap倾向度为例):

复制代码
[root@lab ~]# sysctl -a | grep swap
vm.swappiness = 60

vm.swappiness的值越小,系统越优先使用物理内存;值越大,越优先使用swap空间。

临时修改(两种方式):

方式一:使用sysctl命令

复制代码
sysctl -w vm.swappiness=0

方式二:直接操作/proc/sys下的文件

复制代码
echo 0 > /proc/sys/vm/swappiness

永久生效: 写入/etc/sysctl.conf文件

复制代码
[root@lab vm]# cat /etc/sysctl.conf
vm.swappiness=0

💡 实用场景 :想让Linux充当路由器转发数据包?开启net.ipv4.ip_forward=1即可。


四、tuned:一键式系统调优

4.1 什么是tuned?

tuned是红帽默认预装的调优工具,通过加载不同的配置集批量调整系统参数。它就像一个"调优管家",让你无需手动修改繁杂的配置文件。

4.2 常用操作

复制代码
# 列出所有调优配置集
[root@lab ~]# tuned-adm list

# 手动指定配置集
[root@lab ~]# tuned-adm profile virtual-host

# 查看系统推荐的配置集
[root@lab ~]# tuned-adm recommend

配置集文件存放在/usr/lib/tuned/目录下,每个子目录对应一个配置集。


五、Swap分区:内存的"后备军"

5.1 什么是Swap?

Swap分区本质上是磁盘空间,充当内存的扩展,让系统能运行更多程序。

要不要划分Swap? 这取决于:

|--------------|--------------------|
| 场景 | 建议 |
| 内存很大(如64GB+) | 可以不划 |
| 内存较小(如4GB) | 建议划分 |
| K8S集群部署 | 必须关闭(否则集群无法运行) |

5.2 创建Swap的两种方式

方式一:基于文件创建Swap

复制代码
# 创建1GB的空文件
[root@lab ~]# dd if=/dev/zero of=/tmp/1G.swp bs=1M count=1024

# 格式化为swap
[root@lab ~]# mkswap /tmp/1G.swp

# 临时启用
[root@lab ~]# swapon /tmp/1G.swp

# 查看swap状态
[root@lab ~]# swapon -s
Filename          Type    Size    Used    Priority
/tmp/1G.swp       file    1048572 0       -2

方式二:基于分区创建Swap

使用fdisk创建分区,类型选择Linux swap(代码82),然后用mkswap格式化。

5.3 Swap优先级

优先级数字越大,越优先使用该swap空间。相同优先级则轮询使用。

复制代码
# 指定优先级挂载
swapon -p 10 /tmp/1G.swp

5.4 永久挂载Swap

写入/etc/fstab

复制代码
/tmp/1G.swp  swap  swap  defaults  0 0

六、systemctl:服务管理神器

6.1 systemd vs initd

从RHEL 7开始,PID为1的进程从initd变成了systemd。两者区别巨大:

|------|----------|----------|
| 特性 | initd | systemd |
| 启动方式 | 串行启动 | 并行启动 |
| 启动脚本 | Shell脚本 | 服务单元配置文件 |
| 依赖处理 | 无法自动解决 | 自动解决依赖 |
| 启动速度 | 慢 | 快 |

串行启动意味着必须等一个服务启动完才能启动下一个,一旦某个服务卡住,后面的都得等着。

6.2 systemctl常用命令

查看服务状态:

复制代码
[root@lab ~]# systemctl status sshd.service

输出中重点关注:

  • Loaded: enabled(开机自启动) / disabled(不自启动)
  • Active: active (running) / inactive (dead)

启动/停止/重启:

复制代码
systemctl start sshd
systemctl stop sshd
systemctl restart sshd   # 修改配置文件后需重启生效

重载 vs 重启:

  • systemctl reload sshd:不改变PID,平滑读取新配置(发送signal 1信号)
  • systemctl restart sshd:完全重启,PID会变化

不确定服务是否支持reload?用这个:

复制代码
systemctl reload-or-restart sshd

设置开机自启动:

复制代码
systemctl enable sshd    # 创建软链接到/etc/systemd/system/
systemctl disable sshd   # 删除软链接

# 组合命令(同时启停)
systemctl enable --now sshd
systemctl disable --now sshd

锁定服务(防止被意外启动):

复制代码
systemctl mask chronyd    # 锁定
systemctl unmask chronyd  # 解锁

⚠️ 实战提醒 :在OpenStack等云平台环境中,network.serviceNetworkManager.service不能同时开启,否则会导致网卡IP丢失。这时就需要用mask锁定其中一个。


七、Target启动目标:系统的"运行模式"

7.1 runlevel → target的演变

RHEL 7之前用运行级别(runlevel) ,之后用启动目标(target)

|----------|-------------------|---------|
| runlevel | target | 说明 |
| 0 | poweroff.target | 关机 |
| 1 | rescue.target | 救援模式 |
| 2, 4 | multi-user.target | 多用户文本模式 |
| 3 | multi-user.target | 多用户文本模式 |
| 5 | graphical.target | 图形化模式 |
| 6 | reboot.target | 重启 |

7.2 target管理命令

vb 复制代码
`# 查看当前运行级别
[root@lab ~]# runlevel
N 5

# 查看当前target
[root@lab ~]# systemctl get-default
graphical.target

# 设置默认target
[root@lab ~]# systemctl set-default multi-user.target

# 临时切换target
[root@lab ~]# systemctl isolate graphical.target`

八、Linux系统启动流程:从按下电源到登录

理解启动流程是排查启动故障的基础。完整流程如下:

第1步:开机上电

按下电源按钮,硬件开始通电。

第2步:BIOS/UEFI自检

BIOS(基本输入输出系统)检查CPU、内存、硬盘等硬件是否正常。

传统服务器用Legacy BIOS ,现代服务器用UEFI BIOS。UEFI支持更大硬盘、启动更快。

第3步:加载启动设备

BIOS根据设定的顺序(硬盘 → 光盘 → 网卡)加载启动设备。

第4步:加载引导程序 GRUB2

  • 传统BIOS :引导程序位于硬盘前446字节(MBR)
  • UEFI BIOS :引导程序是/boot目录下的EFI文件

第5步:加载引导配置文件

GRUB2加载/boot/grub2/grub.cfg,显示内核选择菜单。

第6步:加载内核和initramfs

  • 内核文件/boot/vmlinuz-*
  • initramfs:提供内核所需的驱动程序(特别是根文件系统驱动)

initramfs只在开机时生效,它包含了挂载根文件系统所需的驱动(如xfs驱动)。

第7步:挂载根文件系统并启动systemd

initramfs将真正的根挂载到自己的/sysroot,然后chroot切换过去,执行/usr/lib/systemd/systemd

第8步:systemd初始化系统

  • 读取/etc/fstab挂载所有文件系统
  • 根据默认target启动对应服务

九、启动故障修复:救命的几招

9.1 grub.cfg配置文件丢失

现象 :看不到内核菜单,直接进入grub >提示符。

修复方法(手动引导):

复制代码
# 1. 查看磁盘分区
grub > ls
(hd0) (hd0,msdos1) (hd0,msdos2) (hd0,msdos3)

# 2. 指定boot分区(通常是第一个分区)
grub > set root=(hd0,msdos1)

# 3. 指定内核和initramfs
grub > linux /vmlinuz-xxx root=/dev/mapper/rhel-root
grub > initrd /initramfs-xxx.img

# 4. 启动
grub > boot

进入系统后重新生成配置:

复制代码
[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg

💡 更简单的方法 :用安装光盘进入救援模式,chroot到真正的根后执行上述命令。

9.2 GRUB2引导程序丢失

传统BIOS场景:MBR的前446字节被破坏,开机可能直接进入安装界面或网络启动。

修复方法(救援模式):

复制代码
# 进入救援模式后,切换到真正的根
# 然后重新安装GRUB
grub2-install /dev/sda   # /dev/sda是系统盘

⚠️ 注意 :一定要先chroot切换到真正的根,否则会报modinfo.sh找不到的错误。

UEFI场景 :引导程序是/boot/efi/下的文件。修复方法:

  1. 重新安装efi-filesystemshim-x64两个rpm包
  2. 或从其他正常机器拷贝一份

9.3 重置Root密码

这是最经典的故障场景。从RHEL 9开始,方法有变化:

步骤1: 开机时选择第二个救援内核 (rescue),按e编辑

步骤2: 找到linux开头的那一行,在末尾添加参数:

  • RHEL 9及之前:rd.breakinit=/bin/bash
  • RHEL 10及之后:必须用 init=/bin/bash

步骤3:Ctrl+X继续引导

步骤4: 进入emergency模式后:

复制代码
# 重新以读写方式挂载根
mount -o remount,rw /sysroot

# 切换到真正的根
chroot /sysroot

# 修改密码
passwd root

# 创建autorelabel文件(如果SELinux开启)
touch /.autorelabel

# 退出重启
exit
exit

🔑 关键点 :如果SELinux开启且不创建/.autorelabel,重启后所有修改都不会生效。这个文件告诉SELinux重新给所有文件打标签,相当于"放行"这次操作。


结语

从内核模块的动态加载,到sysctl的精准调优,再到启动流程的每一个环节------Linux系统的魅力就在于它的透明性和可控性。当你理解了这些底层机制,遇到问题时就不再是"重启试试",而是能够精准定位、快速修复。

希望这篇文章能帮助你建立起对Linux内核和启动流程的系统性认知。如果你在实践中遇到了本文未覆盖的问题,欢迎留言交流!


📌 本文基于RHEL9系列整理,不同发行版可能略有差异,请以实际环境为准。

相关推荐
学无-止境19 小时前
STM32H743 + CMSIS-RTOS2 + Mongoose 网络协议栈移植教程
arm开发·物联网
振南的单片机世界2 天前
单片机:一颗芯片包办CPU、内存、外设的“单芯片计算机”
arm开发·stm32·单片机·嵌入式硬件
振南的单片机世界3 天前
地址总线定门牌号,数据总线搬货量:CPU的“寻址”与“搬运”
arm开发·stm32·单片机·嵌入式硬件
2401_854151554 天前
ARM Cortex-M 体系结构深度解析——寄存器模型、处理器模式、AAPCS 与异常模型
arm开发·stm32·单片机·嵌入式硬件
zlinear数据采集卡4 天前
从0到1硬核拆解:工业级数据采集卡的隔离设计与Modbus通信实战
arm开发·单片机·嵌入式硬件·fpga开发·开源
keep7546 天前
ARM NEON 向量优化在图像处理中的应用:降低 CPU 开销,提升模式切换稳定性
arm开发·图像处理·人工智能
zlinear数据采集卡8 天前
从协议解析到波形实时显示:硬核拆解ZLinear采集卡上位机软件的开发架构
arm开发·单片机·嵌入式硬件·fpga开发·架构·开源
奔跑的架构师8 天前
[A-48]ARMv9/v8-电源状态管理机制(PSCI协调机制)
android·linux·arm开发·arm
想你依然心痛8 天前
RT-Thread组件生态:SAL网络框架与AT组件实战——网络抽象、AT指令
网络·arm开发·at·sal