系统的启动其实是一项非常复杂的过程,因为内核得要检测硬件并加载适当的驱动程序,接下来则必须要调用程序来准备好系统运行的环境,以让用户能够顺利的操作整台主机系统,如果你能够理解系统启动的原理,那么将有助于你在系统出问题时能够很快速的修复系统,而且还能够顺利的配置多重操作系统的多重启动问题,为了多重启动的问题,你就不能不学 grub 这个 Linux 下优秀的启动管理程序(boot loader),而在系统运行期间,你也得要学会管理内核模块,下面进入正题开始学习吧.
关于Linux系统的启动流程一览
操作系统的启动过程是一个很复杂的过程,在启动过程中,那个引导装载程序(BootLoader)使用的软件可能不一样,例如目前主流发行版为GRUB,但是呢早期Linux系统使用的是,LILO,现在很多人喜欢使用SPFDISK,不管如何,我们总要了解整个(BootLoader)的工作情况,才能了解怎样进行多重引导的设置.
这里以个人计算机搭建的Linux主机为例子,当你按下电源时计算机硬件会主动读取BIOS来加载硬件的一些信息,和自我检测,之后系统会读取第一个可启动的设备(由BIOS设置的),此时就可以读入引导装载程序啦.
引导装载程序可以指定使用那个内核来启动,并负责实际加载内核到内存当中解压与执行,此时内核就能够开始在内存中活动啦,并检测所有硬件信息,与加载相应的驱动程序,等到内核加载驱动完毕,此时我们的操作系统就完成整个启动过程啦,简单的归纳来说,系统的启动流程是这样的:
● 按下开机按钮,这个是必须的,奥对了,必须要有电才可以. ● 系统会加载BIOS,来进行硬件信息的读取,和自我检测,并依据设置取得第一个可启动设备. ● 读取并执行第一个可启动设备内 MBR 记录里的 BootLoader(grub或者是spfdisk). ● 依据BootLoader里的设置加载内核,内核会开始检测硬件,并加载相应的驱动程序. ● 在完成驱动的加载后,内核此时会主动调用systemd进程,而systemd进程会取得run-level信息. ● systemd进程执行
/etc/rc.d/init.d
内的脚本,部署操作环境(如网络,时区等). ● systemd进程执行,run-level的各个服务程序脚本,来启动指定运行级别的各种服务. ● systemd进程执行/etc/rc.d/rc.local
加载内部的一些数据. ● systemd进程执行终端机模拟程序mingetty来启动login程序,最后等待用户的登陆.
以上的流程,就是Linux系统的启动流程,你会发现systemd进程非常重要,当然这可是系统的根,这些内容你最好背过,要不然面试问到的话就尴尬啦.
关于BIOS开机自检与MBR主引导记录
想要启动一个系统首先就得让系统去加载BIOS,并通过BIOS程序去加载CMOS里的相关信息,并通过CMOS里的设置值去读取主机的各项硬件配置,例如:CPU频率,内存大小,系统时间等常规的参数.
接着在取得这些信息后,BIOS还会进行开机自检(Power-On Self Test,POST),然后开始执行硬件检测初始化,并配置PNP设备等,之后再定义出可启动的设备顺序,接下来就会开始进行启动设备的数据读取了(MBR的相关任务开始).
BIOS会指定启动的设备,好让我们可以读取磁盘中的操作系统内核文件,但由于不同的操作系统的文件格式并不相同,因此我们必须要以一个引导装载程序来处理内核文件的加载问题,这个引导装载程序就被称为BootLoader,这个BootLoader程序就安装在启动设备的第一个扇区内,也就是我们所说的MBR(主引导记录)了.
其实只要BIOS能够检测得到你的磁盘,那么它就有办法来读取你的第一个扇区,如此一来,BootLoader也够被执行.
Boot Loader的功能
每个文件系统 (filesystem,或者 partition) 都会保留一块引导扇区 (boot sector) 提供操作系统安装 boot loader,而通常操作系统默认都会安装一份 loader 到他根目录所在的文件系统的 boot sector 上.
每个操作系统默认是会安装一套 boot loader 到他自己的文件系统中,而在 Linux 系统安装时,你可以选择将 boot loader 安装到 MBR 去,也可以选择不安装。.如果选择安装到 MBR 的话,那理论上你在 MBR 与 boot sector 都会保有一份 boot loader 程序的,至于 Windows 安装时,他默认会主动的将 MBR 与 boot sector 都装上一份 boot loader 所以你会发现安装多重操作系统时,你的 MBR 常常会被不同的操作系统的 boot loader 所覆盖.
BootLoader的常用功能有以下几个 1.提供一个菜单:用户可以选择不同的启动项. 2.加载内核文件:直接执行可启动系统的区段. 3.转交给其他loader:将引导装载入成功,转交给其他loader负责.
由于具有菜单功能,因此我们可以选择不同的内核来启动,这里需要强调的是,如果要装双系统应该先装windows再装linux.
加载内核自检与systemd的功能
接下来就是加载内核的时候啦,由于我们的Linux驱动都是以模块的形式存在的,比如键盘鼠标驱动,网络驱动等,包括我们的硬盘驱动,常用的一些驱动文件就是放在/lib/modules目录内的,那么这里就出现了一个问题,想一下,我们的硬盘驱动是在Linux模块里的,而我们要使用硬盘才是能启动系统,系统没启动也就无法加载磁盘驱动,无法加载磁盘驱动也就无法打开磁盘啊,这里就出现了一个东西,那就是虚拟文件系统(InitiaIRAM Disk).
虚拟文件系统,一般使用的文件名为/boot/initrd,这个文件的作用是临时加载一些系统启动而需要用到的驱动的,你可以把它想象成是一个微型的Linux系统,它的作用只是加载系统的必要驱动而已,通过该程序来加载启动过程中所最需要的内核模块,通常这些模块就是 U盘,RAID,LVM,SCSI等文件系统与磁盘驱动程序,等加载完成后会自动调用 /sbin/init 将控制权交给完整的Linux系统管理.
当上面的工作完成后,我们的系统已经可以开始工作啦,下面就要将控制权交给/sbin/init来进一步初始化我们的系统环境.
第一个进程init,与/etc/inittab
当内核加载完成后,我们的init进程就开始干活了,/sbin/init主要的任务就是加载后续的系统环境,比如终端的变量,或者调用其它配置文件,继续干活,其最主要的是系统的执行等级,我们的系统有以下7个执行等级,分别是:
基本上runlevel分为0-6 ,7个等级: 0:关机-shutdown 1:单用户模式(sigle user),root用户,无须认证;维护模式 2:多用户模式(multi user),会启动网络功能,但不会启动NFS;维护模式 3:多用户模式(multi user),完全功能模式;文本界面 4:预留级别:目前无特别使用目的,但习惯同3级别使用 5:多用户模式(multi user),完全功能模式,图形界面 6:重启模式
由于 run level 0, 4, 6 不是关机、重新启动就是系统保留的,所以:『 您当然不能将默认的 run level 配置为这三个值 』,否则系统就会不断的自动关机或自动重新启动.
完成级别的选择之后,下一步就是进一步调用配置文件,继续加载参数.
系统初始化的过程主要是执行一些脚本配置文件来完成的: 1.执行系统初始化脚本(
/etc/rc.d/rc.sysinit
)对系统进行基本的配置以读写方式挂载,根文件系统及其它文件系统,到此系统算是基本运行起来了,后面需要进行运行级别的确定及相应服务的启动. 2.执行/etc/rc.d/rc
脚本,该文件定义了服务启动的顺序是先K后S,而具体的每个运行级别的服务状态是放在/etc/rc.d/
目录下,所有的文件均是指向/etc/init.d
下相应文件的符号链接,rc.sysinit
通过分析/etc/inittab
文件来确定系统的启动级别,然后才去执行/etc/rc.d/rc.d
下的文件. 3.执行用户自定义引导程序/etc/rc.d/rc.local
完成了系统所有的启动任务后,linux会启动终端或X-Window来等待用户登录. 4.最后一步输入用户名及密码就可以登入系统了.
至此我们的操作系统就启动起来啦,接下来看一下常用的启动管理命令吧.
1.第一步修改GRUB配置文件,改掉几个配置参数,然后生成写入/boot目录即可.
[root@localhost ~]# vim /etc/default/grub
GRUB_TIMEOUT=5 #引导时间
GRUB_DEFAULT=1 #从哪个内核引导,默认是0
[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
1.第一种方式是明文设置,不推荐,但下面还是要看一下配置流程的.
[root@localhost ~]# vim /etc/grub.d/00_header
文件末尾追加
cat << EOF
set superusers=admin
password admin 123123
EOF
[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
2.第二种方法,先加密我们的密码,此处通过命令生成.
[root@localhost ~]# grub2-mkpasswd-pbkdf2
Enter password:
Reenter password:
PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.4E2254C5684C9F12C06354A090B8447B0D1532D1BCA9FA5CBE870E7
0E1ED46A25BD3D2443E2E3676613AAF909FD4F34C213B2904C7580B1096B1E16736E48883.D5C3FDF2DF61424C6655FE343CE909C0D13B65
95312DD50CE764B6EC3954347BA63E04CA62D6B3DA1AE00D5DAA8CF8DCF752F8046BFB18F5B19604DCE512C09E
接着复制这一行将密码列用密钥代替即可.
[root@localhost ~]# vim /etc/grub.d/00_header
文件末尾追加
cat << EOF
set superusers=admin
password_bkdf2 admin grub.pbkdf2.sha512.10000.4E2254C5684C9F12C06354A090B8447B0D1532D1BCA9FA5CBE870E7
0E1ED46A25BD3D2443E2E3676613AAF909FD4F34C213B2904C7580B1096B1E16736E48883.D5C3FDF2DF61424C6655FE343CE909C0D13B65
95312DD50CE764B6EC3954347BA63E04CA62D6B3DA1AE00D5DAA8CF8DCF752F8046BFB18F5B19604DCE512C09E
EOF
[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
1.如果我们的开机密码忘记了,我们可以使用如下方法解决.重启系统按e键,找到linux16
加入以下内容.
linux16 /vmlinuz-3.10.0 root=/dev/centos-root rhgb quiet
删除: rhgb quiet 添加上:init=/bin/sh
按住: CTRL+X
2.接着会看到进入到一个shell环境,我们依次执行以下代码即可.
sh-4.2# mount -o remount,rw /
sh-4.2# echo "redhat" | passwd --stdin root
sh-4.2# touch /.autorelabel
sh-4.2# exec /sbin/init
1.重启系统按e键,找到
ro`加入以下内容.
linux16 /vmlinuz-el7.x86_64 root=/dev/mapper/centos-root ro
将ro替换成 rw init=/sysroot/bin/bash
同时按住Ctrl+x这两个键,系统正式进入emergency模式
:/# chroot /sysroot/
1.重启系统按e键,找到rhgb quite
在后面加入single
内容.
linux16 /vmlinuz-3.10.0 root=/dev/centos-root rhgb quiet single
[root@localhost /]# passwd root
[root@localhost /]# chage -M 99999 root
[root@localhost /]# chage -l root
grub密码也忘记了,如何修改密码.(光盘救援模式)了解下.
执行以下步骤:Troubleshooting -> Rescue a CentOS system -> Continue ->/bin/sh 会进入光盘系统.
sh-4.2# chroot /mnt/sysimage/
sh-4.2# vi /etc/grub.d/00_header
删除以下字段
cat << EOF
set superusers=admin
password admin 123123
EOF
[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
1.使用命令来模拟数据损坏,这里我们强制覆盖硬盘的前446
字节的数据,来模拟MBR损坏.
[root@localhost ~]# dd if=/dev/zero of=/dev/sda bs=1 count=446
[root@localhost ~]# reboot
2.执行完成上面的步骤再次开机,会发现自动的从光盘引导启动啦,原因就是我们的MBR被删除了,而系统会默认寻找第二个启动设备,此时正好光盘能够被启动.
执行以下步骤:Troubleshooting -> Rescue a CentOS system -> Continue ->/bin/sh 会进入光盘系统.
sh-4.2# chroot /mnt/sysimage #切换到硬盘分区
bash-4.2# grub2-install /dev/sda #把grub装在sda里面
bash-4.2# exit
sh-4.2# reboot
如上我们就完成了MBR的修复工作,再次开机系统会进入正常的环境啦.
1.这里我们通过删除/boot/
目录下的所有文件,来模拟BOOT文件丢失的修复流程.
[root@localhost ~]# rm -fr /boot/*
[root@localhost ~]# reboot
2.此时重启后我们的系统就无法正常使用啦,会看到以下grub rescue>
提示符,说明我们的GRUB没问题,接下来我们来修复,老样子挂载光盘使用光盘系统进入bash
并修复一下.
执行以下步骤:F12->CD-ROM->Troubleshooting -> Rescue a CentOS system -> Continue ->/bin/sh 会进入光盘系统.
sh-4.2# chroot /mnt/sysimage/
bash-4.2# mount /dev/sr0 /mnt
bash-4.2# rpm -ivh --force /mnt/Packages/kernel-3.10.0-862.el7.rpm
bash-4.2# mkdir /boot/grub2 #创建BRUB目录,并修复
bash-4.2# grub2-mkconfig -o /boot/grub2/grub.cfg
bash-4.2# grub2-install /dev/sda
bash-4.2# exit
sh-4.2# reboot
到此为止我们的/boot目录就修复成功啦,是不是很简单啊.