1、linux启动流程1.1 UEFi或BIOS初始化运行POST开机自检BIOS Basic Input and Output System基本输入输出系统就是一个程序保存着有关计算机系统最重要的基本输入输出程序系统信息设置开机加电自检程序和系统启动自举程序等。其代码存储在主板的一颗ROM存储芯片上ROM是只能读不能写的这颗芯片上的BIOS程序在主板出厂的时候己经固化好了所以不管断不断电这个BIOS程序都会一直存储在这颗芯片上。当我们修改了BIOS里面的某些设置时这个修改的数据是存储在另外一颗RAM存储芯片上RAM掉电后数据就会消失所以主板上有一颗纽扣电池来给这个RAM供电当这颗纽扣电池没电了BIOS里面的设置项就又恢复成出厂设置了。POSTPower-On-Self-Test 加电自检是BIOS程序中的一个主要功能负责完成对CPU、主板、内存、硬盘子系统、显示子系统、串并行接口、键盘等硬件情况的检测。对于一台计算机来讲通电后第一件事件就是运行BIOS程序BIOS程序最先做的就是对硬件执行POST加电自检如果硬件自检不通过会显示相应的错误还会有相应的蜂鸣音。UEFI 是传统 BIOS 的现代化替代品它解决了 BIOS 在硬件支持、用户体验和安全性方面的诸多限制。提供图形化界面支持鼠标操作可以显示图形和品牌Logo甚至支持高分辨率显示和本地化语言用户体验更友好。1.2 选择启动设备硬盘u盘网络模式启动1.3 引导加载程序bootloader1BIOS 模式下的 BootloaderBIOS找到硬盘后只读取硬盘的第一个扇区512字节这个扇区叫做MBR。MBR里面包含了以下信息一小段引导代码446字节。硬盘分区表64字节。结束标志2字节。centos7默认采用grub2作为内核的引导管理器grub2程序安装grub后会在/boot/grub2/i386-pc/目录下生成boot.img和core.img文件另外还包含文件系统类的模块等。第一阶段 BootloaderBIOS将MBR的446B加载到内存并执行。这段代码非常小功能有限它的主要任务是找到并加载第二阶段的Bootloader也就是core.img。在第二阶段 Bootloader会依次加载以下文件/boot/grub2/i386-pc/core.img#包含文件系统模块并可以加载位于/boot/grub2/目录下的、功能完整的 GRUB 2 主程序和模块/boot/grub2/grub.cfg#加载该文件后可向用户提供操作系统的启动菜单如果有多个内核或系统当用户选择了要启动的操作系统菜单后将根据grub2的配置文件找到内核文件vmlinuz-5.14.0-362.8.1.el9_3.x86_64和initramfs-5.14.0-362.8.1.el9_3.x86_64.img临时的根文件系统镜像内核需要它来挂载真正的根文件系统文件并加载它同时传递内核启动参数包括根文件系统所在分区。[!Important]/boot/grub2/grub.cfg是根据命令grub2-mkconfig -o /boot/grub2/grub.cfg读取/etc/default/grub和/etc/grub.d/配置而生成的2UEFI 模式下的 Bootloader开机后UEFI初始化时会去扫描一个特殊的分区——EFI系统分区 (ESP)UEFI固件内部集成了一个引导管理器会找到ESP分区中对应的**.efi** 文件路径。这个EFI文件包含了Bootloader的全部功能。它读取自己的配置文件显示菜单并加载操作系统内核。1.4 内核启动和初始化阶段到目前为止内核已经被加载到内存并掌握了CPU的控制权内核将initramfs解压的内容装入到tmpfs中。initramfs为了尽早进入用户空间它将init程序集成到了initramfs镜像文件中这样就可以在initramfs装入tmpfs时直接运行init进程而不用去找根文件系统下的/sbin/init。内核在这个初始根文件系统中找到一个名为init的可执行文件实际上是指向/usr/lib/systemd/systemd的链接并执行它。此时systemd以 PID 1 的身份首次出现但这是在initramfs环境中。[rootrhel93 ~]# mkdir /initramfs[rootrhel93 ~]# cd /initramfs/[rootrhel93 initramfs]# /usr/lib/dracut/skipcpio /boot/initramfs-5.14.0-362.8.1.el9_3.x86_64.img | zcat | cpio -id[rootrhel93 initramfs]# ll总用量12lrwxrwxrwx1root root78月2823:06 bin -usr/bin drwxr-xr-x2root root748月2823:06 dev drwxr-xr-x13root root40968月2823:06 etc lrwxrwxrwx1root root238月2823:06 init -usr/lib/systemd/systemd lrwxrwxrwx1root root78月2823:06 lib -usr/lib lrwxrwxrwx1root root98月2823:06 lib64 -usr/lib64 drwxr-xr-x2root root68月2823:06 proc drwxr-xr-x2root root68月2823:06 root drwxr-xr-x2root root68月2823:06 run lrwxrwxrwx1root root88月2823:06 sbin -usr/sbin -rwxr-xr-x1root root46318月2823:06shutdowndrwxr-xr-x2root root68月2823:06 sys drwxr-xr-x2root root68月2823:06 sysroot drwxr-xr-x2root root68月2823:06 tmp drwxr-xr-x8root root818月2823:06 usr drwxr-xr-x3root root408月2823:06 var1.5 systemd执行initrd.targetsystemd会启动initrd.target及其依赖的服务包括挂载 /etc/fstab、从initramfs切换到真正的根文件系统。[rootrhel93 system]# systemctl list-dependencies initrd.targetinitrd.target ○ ├─dracut-cmdline.service ○ ├─dracut-initqueue.service ○ ├─dracut-mount.service ○ ├─dracut-pre-mount.service ○ ├─dracut-pre-pivot.service ○ ├─dracut-pre-trigger.service ○ ├─dracut-pre-udev.service ○ ├─initrd-parse-etc.service ○ ├─systemd-pcrphase-initrd.service ● ├─basic.target ● │ ├─-.mount ○ │ ├─microcode.service ● │ ├─paths.target ● │ ├─slices.target ● │ │ ├─-.slice ● │ │ └─system.slice ● │ ├─sockets.target#切换根[rootrhel93 system]# systemctl list-dependencies initrd-switch-root.targetinitrd-switch-root.target ○ ├─initrd-cleanup.service ○ ├─initrd-switch-root.service ○ ├─initrd-udevadm-cleanup-db.service ● ├─plymouth-start.service ○ ├─plymouth-switch-root.service ● ├─systemd-journald.service ○ ├─initrd-fs.target ○ └─initrd-root-fs.target ○ └─systemd-repart.service[rootrhel93 initramfs]# cat ./usr/lib/systemd/system/initrd-switch-root.service[Unit]DescriptionSwitch RootAssertPathExists/etc/initrd-releaseDefaultDependenciesnoWantsinitrd-switch-root.targetAllowIsolateyesOnFailureemergency.targetOnFailureJobModereplace-irreversibly[Service]TypeoneshotExecStartsystemctl --no-block switch-root /sysroot1.6 systemd执行默认target此时systemd已经完成了根文件系统的切换正式进入操作系统的初始化过程systemd会启动default.target及其依赖的sysinit.target初始化系统、basic.target准备操作系统、multi-user.target 下的本机与服务器服务、multi-user.target 下的/etc/rc.d/rc.local、multi-user.target下的getty.target及登录服务[rootrhel93 ~]# systemctl list-dependencies default.targetdefault.target ● ├─atd.service ● ├─auditd.service ● ├─chronyd.service ● ├─crond.service ○ ├─insights-client-boot.service ● ├─irqbalance.service ● ├─kdump.service ● ├─libstoragemgmt.service ● ├─mcelog.service ○ ├─mdmonitor.service ● ├─NetworkManager.service......[rootrhel93 system]# cat /usr/lib/systemd/system/default.target[Unit]DescriptionGraphical InterfaceDocumentationman:systemd.special(7)Requiresmulti-user.target#表示要先执行multi-user.targetWantsdisplay-manager.serviceConflictsrescue.service rescue.targetAftermulti-user.target rescue.service rescue.target display-manager.serviceAllowIsolateyes[rootrhel93 system]# cat /usr/lib/systemd/system/multi-user.target[Unit]DescriptionMulti-User SystemDocumentationman:systemd.special(7)Requiresbasic.target#表示要先执行basic.targetConflictsrescue.service rescue.targetAfterbasic.target rescue.service rescue.targetAllowIsolateyes[rootrhel93 system]# cat /usr/lib/systemd/system/basic.target[Unit]DescriptionBasic SystemDocumentationman:systemd.special(7)Requiressysinit.target#执行sysinit.targetWantssockets.target timers.target paths.target slices.targetAftersysinit.target sockets.target paths.target slices.target tmp.mount当default.target的所有单元都启动完毕系统就准备就绪显示登录界面图形或命令行等待用户使用。2、linux systemd2.1 systemd介绍rhel7之前的系统都是使用init进程作为系统启动后的第一个进程但是init有两个缺点启动时间长因为init的进程是串行的只有前一个启动完毕后一个进程才启动。启动脚本复杂以前的系统初始化需要加载很多脚本依赖关系复杂靠脚本自己处理。而systemd的启动则是并行运行的而且服务的启动配置文件统一语法所以管理起来更方便。从rhel 7 版本之后开始用 systemd 实现init进程系统启动和服务器守护进程管理器负责在系统启动或运行时激活系统资源服务器进程和其它进程。systemd可以管理所有系统资源不同的资源称为unit。可以使用man systemd.unit查看帮助#查看systemd中的unit[rootrhel93 system]# systemctl -t helpAvailable unit types:service#文件扩展名为.service,用于定义系统服务mount#文件扩展名为.mount定义文件系统挂载点swap#文件扩展名为.swap用于标识swap设备socket#文件扩展名为socket用于标识进程间通信用到的socket文件target#文件扩展名为.target用于模拟实现“运行级别”定义要系统初始化时要做的事device#文件扩展名为.device用于定义内核识别的设备automount#文件扩展名为.automount由systemd负责的自动挂载文件系统timer#定时器path#扩展名为.path用于定义systemd监控的文件或目录systemd使用notify监控文件的变化slice#进程组scope#不是由systemd启动的外部进程unit文件所在路径/usr/lib/systemd/system #每个服务最主要的脚本文件目录 /run/systemd/system/ #系统执行过程中所产生的服务脚本比上面目录优先运行 /etc/systemd/system/ #管理员建立的执行脚本比上面目录优先运行列出所有在内存中的单元# systemctl list-units命令也可以查看[rootrhel93 ~]# systemctl#查看状态为active的service要查看所有的包括inactive的可以加上-a选项查看[rootrhel93 ~]# systemctl --typeserviceUNIT LOAD ACTIVE SUB DESCRIPTION atd.service loaded active running Deferred execution scheduler auditd.service loaded active running Security Auditing Service chronyd.service loaded active running NTP client/server crond.service loaded active running Command Scheduler dbus-broker.service loaded active running D-Bus System Message Bus输出字段说明字段说明UNIT服务名称LOAD加载状态 loaded|not-found|bad-setting|error|maskedACTIVE服务状态 active|reloading|inactive|failed|activating|deactivatingSUB详细状态与 LOAD和ACTIVE列有关具体可执行 systemctl --statehelp 查看DESCRIPTIONunit描述信息读取磁盘中存在的所有的service[rootrhel93 ~]# systemctl list-unit-files --typeservice -a2.2 service管理管理服务常用命令systemctl start nginx#启动服务如果服务正在运行systemctl stop nginx#停止服务systemctl restart nginx#重启服务先stop再startsystemctl reload nginx#重新加载服务配置文件systemctl status nginx#查看服务的运行状态systemctl is-active nginx#查看服务是否正在运行systemctlenablenginx#设置服务开机自启动可以加上--nowsystemctl disable nginx#设置服务开机不自启动可以加上--nowsystemctl is-enabled nginx#查看服务是否开机自启动systemctl list-unit-files#查看所有服务的开机自启动状态systemctl daemon-reload#重新载入更改的systemd配置文件systemctl mask nginx#禁用nginx服务使之开机不自动启动且也不能手动启动systemctl unmask nginx#解除禁用效果服务运行状态说明#当我们使用systemctl status查看一个服务的运行状态时有以下几种情况loaded#配置文件已经被加载active(running)#服务正在运行active(exited)#仅执行一次就正常结束的服务目前并没有任何程序在系统中执行。inactive(dead)#服务没有在运行enabled#服务被设定为开机自启动disabled#服务被设定为开机不自启动static#服务开机不自启动但是可以被其他服务调用启动2.3 service unit文件格式一般使用软件包安装的软件的启动配置文件在这个目录/usr/lib/systemd/system/下systemd文件格式说明systemd unit文件通常是由三部分组成的[Unit]#一般定义的是通用选项比如描述信息依赖关系等[Service]#特定服务的类型具体的启动关闭重启选项都在此部分配置[Install]#定义由systemctl enable和disable命令在实现服务开机自启和禁用时用到的一些选项Unit段常用说明Description#描述信息Documentation#说明文档的在线地址After#定义启动顺序表示当前配置的服务应该晚于哪些服务之后启动Requires#依赖的其它units强依赖如果被依赖的units无法激活当前unit也无法激活Wants#依赖到的其它units弱依赖Conflicts#定义units间的冲突关系Service段常用说明Type#定义服务类型forking#需要父进程启动子进程的服务类型为forkingEnvironmentFile#环境配置文件PIDFile#定义PID文件路径ExecStart#指定启动服务命令绝对路径ExecStartPre#在启动之前运行的命令ExecStartPost#在启动之后运行的命令ExecStop#指定停止服务命令绝对路径ExecReload#指定重新加载服务的配置文件的命令绝对路径Restart#当该值为1时则当此daemon服务意外终止后会再次自动启动#####type值有7种说明如下########simple#默认值, 执行ExecStart指定的命令该命令的进程就是该服务的主进程forking#以fork方式从父进程创建子进程创建后父进程会立即退出oneshot#与simple类似, 不过这个程序在工作完毕后就结束了不会常驻在内存中dbus#当前服务通过D-Bus启动notify#在启动完成后会发送一个通知消息, 还需要配合NotifyAccess来让Systemd 接收消息idle#要执行这个daemon必须要所有的工作都顺利执行完毕, 这类daemon通常是开机到最后才执行的服务Install段常用说明WantedBy #被哪些服务依赖 Requiredby #被哪些服务依赖#例如nginx.server的Install中写了[rootrhel93 yum.repos.d]# sed -n /Install/,$ p /usr/lib/systemd/system/nginx.service[Install]WantedBymulti-user.target#在设置nginx的开自启动时会在/etc/systemd/system/multi-user.target.wants目录下创建nginx.service的软链接[rootrhel93 yum.repos.d]# systemctl enable nginxCreated symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.修改完服务启动文件后需要使用以下命令重载systemctl daemon-reload#重新载入更改的systemd配置文件2.4 systemd的运行级别centos7开始使用 target 来定义运行级别。当前默认使用的级别如下[rootrhel93 ~]# readlink /etc/systemd/system/default.target/usr/lib/systemd/system/multi-user.target查看所有的target[rootrhel93 ~]# ls -l /usr/lib/systemd/system/run*target | grep -o /usr.*/usr/lib/systemd/system/runlevel0.target -poweroff.target#关机/usr/lib/systemd/system/runlevel1.target -rescue.target#救援模式用于系统维护禁止远程登录/usr/lib/systemd/system/runlevel2.target -multi-user.target#多用户模式文本界面/usr/lib/systemd/system/runlevel3.target -multi-user.target /usr/lib/systemd/system/runlevel4.target -multi-user.target /usr/lib/systemd/system/runlevel5.target -graphical.target#多用户模式图形界面/usr/lib/systemd/system/runlevel6.target -reboot.target#重启修改默认级别[rootrhel93 ~]# systemctl set-default multi-user.target[rootrhel93 ~]# systemctl get-defaultmulti-user.target3、重置root密码3.1 使用单用户模式重置密码方法一启动时按任意键暂停启动 按e键进入编辑模式 将光标移动linux 开始的行添加内核参数 rd.break 按ctrlx启动mount–o remount,rw /sysrootchroot/sysrootpasswdroot#如果SELinux是启用的,才需要执行下面操作,如查没有启动,不需要执行touch/.autorelabelexitreboot方法二启动时任意键暂停启动 按e键进入编辑模式 将光标移动linux 开始的行添加 rwinit/sysroot/bin/sh 按ctrlx启动chroot/sysrootpasswdroot#如果SELinux是启用的,才需要执行下面操作,如查没有启动,不需要执行touch/.autorelabelexitreboot3.2 使用光盘重置密码设置系统通过光盘启动选择troubleshooting选择rescue a Red Hat Enterprise Linux system按照以下操作进行密码重置调整系统从硬盘启动4、系统引导文件的修复4.1 误删grub.cfg文件但还未重启系统1模拟将文件删除[rootrhel93 ~]# ls /boot/grub2/device.map fonts grub.cfg grubenv i386-pc locale[rootrhel93 ~]# rm -f /boot/grub2/grub.cfg2恢复该文件[rootrhel93 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg4.2 误删grub.cfg文件已经重启系统请先查看/所在分区[rootrhel93 ~]# df -h /文件系统 容量 已用 可用 已用% 挂载点 /dev/mapper/rhel-root 97G2.5G 95G3% /如果误删grub.cfg文件重启系统时会进入如下界面先使用如下方式让此次系统正常启动grubsetroot(hd0,msdos1)#指定boot分区位置#hdn 便是boot分区在那个硬盘上#msdosn在那个分区# 指定内核文件 只读挂载/设备grublinux16 /vmlinuz-5.14.0-362.0.1.el9_3.x86_64 roroot/dev/mapper/rhel-root grubinitrd16 /initramfs-5.14.0-362.8.1.el9_3.x86_64.img grubboot注意 以上步骤只能完成本次引导 系统重启后仍然需要手动引导#进入系统后执行以下命令恢复grub.cfg文件[rootrhel93 ~]# grub2-mkconfig /boot/grub2/grub.cfg4.3 误删/boot/grub2/目录已经重启系统删除/boot/grub2/目录重启系统后出现如下界面此时调整系统启动方式通过光盘进入救援模式选择troubleshooting选择rescue a Red Hat Enterprise Linux system按照如下步骤操作调整系统从硬盘启动启动成功后即可正常登陆4.4 误删/boot/目录下的文件已经重启系统该种情况下和4.3的操作一样都需要通过光盘启动不同点在于增加了需要重新安装内核和initramfs文件的包的步骤#模拟文件被删除[rootrhel93 ~]# rm -rf /boot/*设置使用光盘启动后输入如下命令最后使用硬盘启动即可。