[RH134] 12-系统启动
阅读原文时间:2023年07月10日阅读:3

1.系统启动流程

开机--->BIOS自检(需要检测的设备是否正常)--->磁盘的MBR分区--->BootLoader(引导加载器)加载内核--->识别各分区的文件系统

2.内核

什么是内核:内核其实也是一个软件(例如Linux内核用C语言开发),存放在磁盘的某个地方(例如sda1分区)。

不同的操作系统(内核不一样),文件系统也不一样。不同的操作系统一般不识别其他的文件系统,只有当内核运行起来后,才能识别分区中的文件系统。也就是说,操作系统是否能识别文件系统是由内核来决定的(例如NTFS的移动硬盘在Linux下可能无法识别)。

悖论:要加载内核,则需要去sda1中读取,要识别sda1的文件系统,则需要先加载内核。那么如何让我们在加载内核之前就能从sda1中读取内核代码呢?

3.如何加载内核

如上图,在https://www.cnblogs.com/leokale-zz/p/12543697.html 中我们知道,所有的分区是从第2048个扇区开始划分的,也就是说前面的2048个扇区是空着的。目前我们只知道第1个扇区有一个MBR,其中包含分区表和Bootloader等东西。

如何在文件系统中找到内核:

1)bootloader实际上是从grub的stage1这段代码反汇编出来的,作用就是用来加载第二个扇区(即MBR后面一个扇区的内容)。

2)第二个扇区里存放着grub的stage1.5反汇编出来的代码,作用是加载第3~n个扇区。

3)第3~n个扇区里存储的是一个极精简的fs,但是可以让我们读懂文件系统了。至于n是多大,要根据我们需要识别的文件系统(例如/boot分区)来决定。

4)内核在什么地方呢?是在/boot/grub2/grub.cfg配置文件中指定的。

4.如何修改grub配置文件(永久修改内核参数)

当我们想要修改内核参数时,我们不能直接对 /boot/grub2/grub.cfg 进行修改。

我们需要先修改 /etc/default/grub ,然后执行一个命令:

grub2-mkconfig -o /boot/grub2/grub.cfg

意思是将/etc/default/grub中我们修改的内容,转移到/boot/grub2/grub.cfg中生效。

例子,修改开机时内核选择的等待时间以及默认选择:

我们在开机时可以看到一个让我们选择内核的界面,倒数5s默认选择第一个内核。当然我们可以通过修改配置让其默认选择第二个:

# /etc/default/grub配置文件

GRUB_TIMEOUT=
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
#GRUB_DEFAULT=saved
GRUB_DEFAULT=
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap net.ifnames=0 biosdevname=0 rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

可以看到,我们将默认等待时间修改为10s,将默认选择修改为1(从0开始算,1表示第2个内核)。然后执行命令让其生效:

[root@centos7-test ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file …
Found linux image: /boot/vmlinuz-3.10.-1062.18..el7.x86_64
Found initrd image: /boot/initramfs-3.10.-1062.18..el7.x86_64.img
Found linux image: /boot/vmlinuz-3.10.-.el7.x86_64
Found initrd image: /boot/initramfs-3.10.-.el7.x86_64.img
Found linux image: /boot/vmlinuz--rescue-f30a982c74c94344b2d0248c84efd1c8
Found initrd image: /boot/initramfs--rescue-f30a982c74c94344b2d0248c84efd1c8.img
done

重启看看:

可以看到,等待时间从5s变成了10s,并且默认选择了第2个内核。

除了以上例子中我们修改的内容,我们还可以修改 GRUB_CMDLINE_LINUX 的内容,为内核指定一些参数,例如aa=100(没有意义的参数)。

5.临时修改内核参数

在第4节中,我们进入系统对配置文件进行修改,修改后重启系统就可以让参数永久生效,直到下次手工修改参数。

如果我们想要临时修改内核参数,则可以在启动界面选择内核的时候按 "e" 进入内核编辑页面:

我们在其中添加一个自定义参数:

然后使用Ctrl+x来保存。

进入系统后,使用命令查看当前内核的参数信息:

[root@centos7-test ~]# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.-1062.18..el7.x86_64 root=/dev/mapper/centos-root ro
crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap net.ifnames= biosdevname= rhgb quiet bb=

可以看到我们添加的参数bb=200。这个参数是临时的,再次重启系统后参数消失。

[root@centos7-test ~]# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.-1062.18..el7.x86_64 root=/dev/mapper/centos-root ro
crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap net.ifnames= biosdevname= rhgb quiet

可以看到,重启后bb=200消失了。

6.rescue救援模式

我们正常启动系统的时候,有一些必须启动的服务,例如有20个。如果有一些服务出问题无法启动,则会导致系统无法正常启动。

这时,我们就可以使用rescue模式,因为rescue模式需要的必须服务比较少,例如10个。当出问题的服务,不在这10个服务当中,系统就可以启动起来。

如何进入rescue模式:

这样表示要进入rescue模式,相当于windows的安全模式。

注意:rescue模式进入系统也是需要root密码的。

可以看到,我们已经进入rescue模式,输入root密码即可进入系统。

6.emergency模式

当rescue模式都无法启动的时候,可以尝试使用emergency模式,这个模式比rescue模式需要的必须服务更少。

注意:emergency模式也相当于windows的安全模式,也是需要root密码的。

7.重置root密码

当我们忘记root密码时,可以对其进行重置。

1)选择内核时按e,进入编辑模式

2)进入命令行后,我们查看磁盘挂在的模式

在readonly模式下,我们是不能修改root密码的,所以我们要重新挂载一下。

3)重新挂载分区

4)重置selinux标签

5)执行命令,重启

8.给grub加密

为了使系统更加安全,我们可以给grub加个密码。也就是我们在选择内核的时候想进入编辑页面,必须要输入一个账户和密码。

使用明文密码:

修改/etc/grub.d/00_header文件:

cat <<EOF
set superusers="leo"
password leo
EOF

在最后加上以上内容,设置用户名为leo,密码为88888888。

然后执行命令生效:

grub2-mkconfig -o /boot/grub2/grub.cfg

重启,尝试进入内核编辑页面:

可以看到,要求我们输入账号和密码,我们输入leo 88888888即可。

使用密文密码:

前面我们在00_header中的密码使用的是明文,我们也可以对其进行加密(hash):

我们先生成密码88888888的hash值:

[root@centos7-test ~]# grub2-mkpasswd-pbkdf2
Enter password:
Reenter password:
PBKDF2 hash of your password is grub.pbkdf2.sha512..D9D6A857A18676310A354A83DFA825E95E9A643D0FC2B41DE60DB3C9D8B8FC958F70F22BF118767320FCD03A6859B7AEA2F2FF3975C1D2BE4569F828B14DE86A.F815B659D965CC890E4891CAF52A6471E4F0B825FFD5E84AAC684D7E799D9D3D430984E443396D191A3E3242E9B5A2ABE3241A1EB3F0C7C2622CF7850ADD591D

然后写入00_header文件:

cat <<EOF
set superusers="leo"
password_pbkdf2 leo grub.pbkdf2.sha512..D9D6A857A18676310A354A83DFA825E95E9A643D0FC2B41DE60DB3C9D8B8FC958F70F22BF118767320FCD03A6859B7AEA2F2FF3975C1D2BE4569F828B14DE86A.F815B659D965CC890E4891CAF52A6471E4F0B825FFD5E84AAC684D7E799D9D3D430984E443396D191A3E3242E9B5A2ABE3241A1EB3F0C7C2622CF7850ADD591D
EOF

然后执行命令让其生效:

grub2-mkconfig -o /boot/grub2/grub.cfg

8.系统超级救援模式

当同时出现以下情况时:

  • grub被加密,不知道账号密码
  • root密码也忘了

这时我们就可以使用以下要描述的救援方式。(以Vmware下的CentOS7为例)

1)使用系统对应版本的光盘

例如在虚拟机的CDROM一定要挂载光盘。

2)在重启显示VMware LOGO的时候,按ESC,选择从光盘启动

3)选择Troubleshooting

4)选择Rescue a CentOS system

注意:这里的rescue和前面第6节中的rescue是不一样的。

5)进入光盘中的系统

这种方式类似于windows下的winPE模式

我们按回车就可以得到一个shell命令行:

6)进入我们要修复的系统

注意:当我们获得sh-4.2#命令行的时候,我们还是在光盘操作系统中的。(这是相当于我们还是神)

待修复的系统目前是挂载到一个子目录下的:

使用命令,切换到被修复的系统根(投胎为人):

7)重置root密码、重置grub密码

当我们使用光盘系统进入待修复系统后,我们无需使用任何密码就可以获得最高权限。

重置root密码:

echo | passwd --stdin root

重置grub密码:

vi /etc/grub.d/00_header

修改grub密码即可

9.重新安装grub

当grub被损坏(磁盘的前446字节,即bootloader被损坏),导致无法引导系统,我们可以重新安装grub引导程序。

参考第8节 超级救援模式,进入系统(这种模式是使用光盘系统帮助引导进入的)。

然后执行以下命令重建grub:

此时,重启即可:

9.boot目录损坏

当我们的/boot目录损坏,例如内核被删除等。我们使用删除/boot下所有文件来模拟故障:

重新启动:

可以看到,提示我们缺少一些文件。

可以通过以下步骤来恢复:

1)通过光盘引导进入系统(参考第8节)

可以看到,/boot下什么都没有。

2)重新安装内核

3)重新生成grub配置文件

因为位于/boot下的grub配置文件被删除了,所以我们要重新生成一份。

4)重新安装grub

不管grub是否损坏,都需要重新安装一下grub,因为/boot/grub2/下存放着grub需要的一些文件。

5)重新启动

发现已经可以启动了:

可以看到,这里显示的内核版本是我们重新安装的内核版本。

===