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=10 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" #GRUB_DEFAULT=saved GRUB_DEFAULT=1 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.0-1062.18.1.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-1062.18.1.el7.x86_64.img Found linux image: /boot/vmlinuz-3.10.0-327.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-327.el7.x86_64.img Found linux image: /boot/vmlinuz-0-rescue-f30a982c74c94344b2d0248c84efd1c8 Found initrd image: /boot/initramfs-0-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.0-1062.18.1.el7.x86_64 root=/dev/mapper/centos-root ro
crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap net.ifnames=0 biosdevname=0 rhgb quiet bb=200
可以看到我们添加的参数bb=200。这个参数是临时的,再次重启系统后参数消失。
[root@centos7-test ~]# cat /proc/cmdline BOOT_IMAGE=/vmlinuz-3.10.0-1062.18.1.el7.x86_64 root=/dev/mapper/centos-root ro
crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap net.ifnames=0 biosdevname=0 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 88888888 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.10000.D9D6A857A18676310A354A83DFA825E95E9A643D0FC2B41DE60DB3C9D8B8FC958F70F22BF118767320FCD03A6859B7AEA2F2FF3975C1D2BE4569F828B14DE86A.F815B659D965CC890E4891CAF52A6471E4F0B825FFD5E84AAC684D7E799D9D3D430984E443396D191A3E3242E9B5A2ABE3241A1EB3F0C7C2622CF7850ADD591D
然后写入00_header文件:
cat <<EOF set superusers="leo" password_pbkdf2 leo grub.pbkdf2.sha512.10000.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 123456 | 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)重新启动
发现已经可以启动了:
可以看到,这里显示的内核版本是我们重新安装的内核版本。
===