Linux入门——系统启动流程

理解操作系统开机引导和启动过程对于配置操作系统和解决相关启动问题是至关重要的。本文章笔者总结了 一下linux 引导装载程序开机引导装载内核的过程和 systemd 初始化系统执行开机启动操作系统的过程。

linux启动流程(5与6)

总的来说分为5大步骤

1post自检

上电自检过程中其实 Linux 没有什么也没做,上电自检主要由硬件的部分来完成,这对于所有操作系统都一样。当电脑接通电源,电脑开始执行 BIOS(基本输入输出系统Basic I/O System)的 POST(上电自检Power On Self Test)过程

2BIOS自检同时决定启动方式

BIOS 上电自检确认硬件的基本功能正常,然后产生一个 BIOS 中断 INT 13H,该中断指向某个接入的可引导设备的引导扇区。它所找到的包含有效的引导记录的第一个引导扇区将被装载到内存中,并且控制权也将从引导扇区转移到此段代码。

引导扇区是引导加载器真正的第一阶段。大多数 Linux 发行版本使用的引导加载器有三种:GRUB(5与6为grub)、GRUB2(grub2在7里面) 

3加载mbr

硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,它的大小是512字节(前446字节为bootLoader,中间64字节为分区表,最后两字节结束字节),别看地方不大,可里面却存放了预启动信息、分区表信息。
系统找到BIOS所指定的硬盘的MBR后,就会将其复制到0×7c00地址所在的物理内存中。其实被复制到物理内存的内容就是Boot Loader,而具体到你的电脑,那就是grub了。

查看mbr
[root@centos6 grub]# dd if=/dev/sda of=mbr.bin bs=512 count=1
[root@centos6 grub]# hexdump -C mbr.bin 
00000000 eb 48 90 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0 |.H..............| 00000010 fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00 |...|.........!..| 00000020 00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75 |....8.u........u| 00000030 f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 03 02 |.........|...t..| 00000040 ff 00 00 20 01 00 00 00 00 02 fa 90 90 f6 c2 80 |... ............| 00000050 75 02 b2 80 ea 59 7c 00 00 31 c0 8e d8 8e d0 bc |u....Y|..1......| 00000060 00 20 fb a0 40 7c 3c ff 74 02 88 c2 52 f6 c2 80 |. ..@|<.t...R...| 00000070 74 54 b4 41 bb aa 55 cd 13 5a 52 72 49 81 fb 55 |tT.A..U..ZRrI..U| 00000080 aa 75 43 a0 41 7c 84 c0 75 05 83 e1 01 74 37 66 |.uC.A|..u....t7f| 00000090 8b 4c 10 be 05 7c c6 44 ff 01 66 8b 1e 44 7c c7 |.L...|.D..f..D|.| 000000a0 04 10 00 c7 44 02 01 00 66 89 5c 08 c7 44 06 00 |....D...f.\..D..| 000000b0 70 66 31 c0 89 44 04 66 89 44 0c b4 42 cd 13 72 |pf1..D.f.D..B..r| 000000c0 05 bb 00 70 eb 7d b4 08 cd 13 73 0a f6 c2 80 0f |...p.}....s.....| 000000d0 84 f0 00 e9 8d 00 be 05 7c c6 44 ff 00 66 31 c0 |........|.D..f1.| 000000e0 88 f0 40 66 89 44 04 31 d2 88 ca c1 e2 02 88 e8 |[email protected]........| 000000f0 88 f4 40 89 44 08 31 c0 88 d0 c0 e8 02 66 89 04 |[email protected]..| 00000100 66 a1 44 7c 66 31 d2 66 f7 34 88 54 0a 66 31 d2 |f.D|f1.f.4.T.f1.| 00000110 66 f7 74 04 88 54 0b 89 44 0c 3b 44 08 7d 3c 8a |f.t..T..D.;D.}<.| 00000120 54 0d c0 e2 06 8a 4c 0a fe c1 08 d1 8a 6c 0c 5a |T.....L......l.Z| 00000130 8a 74 0b bb 00 70 8e c3 31 db b8 01 02 cd 13 72 |.t...p..1......r| 00000140 2a 8c c3 8e 06 48 7c 60 1e b9 00 01 8e db 31 f6 |*....H|`......1.| 00000150 31 ff fc f3 a5 1f 61 ff 26 42 7c be 7f 7d e8 40 |1.....a.&B|..}.@| 00000160 00 eb 0e be 84 7d e8 38 00 eb 06 be 8e 7d e8 30 |.....}.8.....}.0| 00000170 00 be 93 7d e8 2a 00 eb fe 47 52 55 42 20 00 47 |...}.*...GRUB .G| 00000180 65 6f 6d 00 48 61 72 64 20 44 69 73 6b 00 52 65 |eom.Hard Disk.Re| 00000190 61 64 00 20 45 72 72 6f 72 00 bb 01 00 b4 0e cd |ad. Error.......| 000001a0 10 ac 3c 00 75 f4 c3 00 00 00 00 00 00 00 00 00 |..<.u...........| 000001b0 00 00 00 00 00 00 00 00 1d c6 04 00 00 00 80 20 |............... | 000001c0 21 00 83 9f 06 19 00 08 00 00 00 40 06 00 00 9f |!..........@....| 000001d0 07 19 83 fe ff ff 00 48 06 00 00 00 80 02 00 fe |.......H........| 000001e0 ff ff 82 fe ff ff 00 48 86 02 00 00 40 00 00 fe |.......H....@...| 000001f0 ff ff 05 fe ff ff 00 48 c6 02 00 b8 b9 04 55 aa |.......H......U.| 00000200

4启动bootloader

bootLoader最重要的就是grub(7中为grub2)GRUB 的最主要作用都是将内核加载到内存并运行。6,7两个版本的 GRUB 的基本工作方式一致,其主要阶段也保持相同,都可分为 3 个阶段。虽然 GRUB2并未在其三个引导阶段中正式使用这些阶段stage名词,但是为了讨论方便,我们在本文中使用它们。

[root@centos6 grub]# cd /boot/grub/
[root@centos6 grub]# ls
device.map     grub.conf         minix_stage1_5     ufs2_stage1_5
e2fs_stage1_5  iso9660_stage1_5  reiserfs_stage1_5  vstafs_stage1_5
fat_stage1_5   jfs_stage1_5      stage1             xfs_stage1_5
ffs_stage1_5   mbr.bin           stage2

[root@centos6 grub]# cat grub.conf
default=0
timeout=5                     #没有选择启动的操作系统超时时间
hiddenmenu                    #隐藏菜单(非必须)
title CentOS 6 (2.6.32-696.el6.x86_64)     #开机时提供的菜单标签(可更改)
root (hd0,0)                    #第一个硬盘的第一个分区。即引导分区
kernel /vmlinuz ro  #加载内核 root=UUID=5822af4a-9e28-4f5c-9b33-879b507fcf70  #根的转换(这里也可用卷标) rhgb quiet #静默模式(可不写,但会在启动时看到很多乱七八糟的东西)
initrd /initramfs-2.6.32-696.el6.x86_64.img       #初始化包含启动的镜像

stage1

如上文 POST自检阶段提到的,在 POST 阶段结束时,BIOS 将查找在接入的磁盘中查找引导记录,其通常位于 MBR,它加载它找到的第一个引导记录中到内存中,并开始执行此代码。引导代码(及阶段 1 代码)必须非常小,因为它必须连同分区表放到硬盘的第一个 512 字节的扇区中。 在传统的常规 MBR 中,引导代码实际所占用的空间大小为 446 字节。这个阶段 1 的 446 字节的文件通常被叫做引导镜像(boot.img),其中不包含设备的分区信息,分区是一般单独添加到引导记录中。

由于引导记录必须非常的小,它不可能非常智能,且不能理解文件系统结构。因此阶段 1 的唯一功能就是定位并加载阶段 1.5 的代码。为了完成此任务,阶段 1.5 的代码必须位于引导记录与设备第一个分区之间的位置。在加载阶段 1.5 代码进入内存后,控制权将由阶段 1 转移到阶段 1.5。

stage1.5

如上所述,阶段 1.5 的代码必须位于引导记录与设备第一个分区之间的位置。该空间由于历史上的技术原因而空闲。第一个分区的开始位置在扇区 63 和 MBR(扇区 0)之间遗留下 62 个 512 字节的扇区(共 31744 字节),该区域用于存储阶段 1.5 的代码镜像 core.img 文件。该文件大小为 25389 字节,故此区域有足够大小的空间用来存储 core.img。

因为有更大的存储空间用于阶段 1.5,且该空间足够容纳一些通用的文件系统驱动程序,如标准的 EXT 和其它的 Linux 文件系统,如 FAT 和 NTFS 等。GRUB2 的 core.img 远比更老的 GRUB1 阶段 1.5 更复杂且更强大。这意味着 GRUB2 的阶段 2 能够放在标准的 EXT 文件系统内,但是不能放在逻辑卷内。故阶段 2 的文件可以存放于 /boot 文件系统中,一般在 /boot/grub2目录下。

注意:windows与linux双系统实现:mbr中的Boot Loader一定要为grub

stage2

GRUB 阶段 2 所有的文件都已存放于 /boot/grub2目录及其几个子目录之下。该阶段没有一个类似于阶段 1 与阶段 1.5 的镜像文件。相应地,该阶段主要需要从 /boot/grub/i386-pc 目录下加载一些内核运行时模块。

GRUB 阶段 2 的主要功能是定位和加载 Linux 内核到内存中,并转移控制权到内核。内核的相关文件位于 /boot 目录下,这些内核文件可以通过其文件名进行识别,其文件名均带有前缀 vmlinuz。你可以列出 /boot 目录中的内容来查看操作系统中当前已经安装的内核。

也就是,编写内核命令行,装载初始化虚拟磁盘,将控制权交给Linux内核。

注意:stage2是grub的核心,不是linux的核心,grub加载以后,目的就是加载linux内核

GRUB,支持从 Linux 内核选择之一引导启动。Red Hat 包管理器(DNF)支持保留多个内核版本,以防最新版本内核发生问题而无法启动时,可以恢复老版本的内核。默认情况下,GRUB 提供了一个已安装内核的预引导菜单,其中包括问题诊断菜单(recuse)以及恢复菜单(如果配置已经设置恢复镜像)。

5启动init(只是在5与6里面,7里面有重大改变)

内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/inittab文件,并依据此文件来进行初始化工作。其实/etc/inittab文件(在5里面很重要不能缺少,但是在6里面不重要)最主要的作用就是设定Linux的运行等级,其设定形式是“:id:5:initdefault:”(默认5级别运行),在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序,它做的工作非常多,包括设定PATH、设定网络配置(/etc/sysconfig/network)、启动swap分区、设定/proc等等。

Linux的运行等级设定如下:

0 关机,系统默认运行级别不能设为0,否则不能正常启动
1 单用户(root权限)
2 多用户状态(没有NFS)
3 完全的多用户状态(有NFS),登陆后进入控制台命令行模式
4 系统未使用,保留(一般用于个人自自定义)
5 图形化的多用户模式
6 系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动


init进程是系统所有进程的起点,内核在完成核内引导后,即在本进程空间内加载init程序,它的进程号是1。init是所有进程的发起者和控制者。因为在任何基于Linux的系统中,它都是第一个运行的进程,所以init进程的编号(PID)永远是 1
init进程有以下两个作用:
1) init进程的第一个作用是扮演终结父进程的角色。因为init进程永远不会被终止,所有系统总是可以确信它的存在,并在必要的时候以它为参照。如果某个进程在它衍生出来的全部子进程结束之前被终止,就会出现必须以init为参照的情况,此时那些失去父进程的子进程就都会以init作为它们的父进程
2) init的第二个作用是在进入某个特定的运行级别时运行相应的程序,以此对各种运行级别

常见启动排错

进入救援模式

6:开机按下esc选择第三项CD-ROM Driver

 

选择第三项Rescue installed system

(见了鬼这张截图死活放不见来)

选择ok

选择ok

 

是否需要开启网络服务,这个随意

 

选择continue

 

选择ok

这段话的意思是救援系统默认把你原来的根挂载在/mnt/sysimage下

 

 选择ok

选择第一项创建一个shell

5与6稍有不同

第一步一样第二步需要手动输入linux rescue 进入救援模式,后面步骤完全一致

实验一:删除/boot/grub/下除了grub.conf外的其他文件

     系统无影响照样启动,因为在内核中加载的有stage1,1.5,2的信息,grub中的为备份。

实验二:删除/boot/grub/下除了grub.conf外的其他文件同时dd if=/dev/zero of=/dev/sda bs=1 count=446 破坏BootLoader即破坏stage1

    系统无法启动。解决方法

进入救援模式
chroot /mnt/sysimage           #更改root
grub-install /dev/sda            #恢复grub文件,这个命令可以恢复,/boot/grub内除grub.conf的所有文件
exit
exit
这是我们再次重复实验一,我们发现系统无法启动
这是因为我们已经把内核内的stage1,1.5,2已经破坏,此后在此启动只通过/boot/grub内的备份启动

实验三:删除/boot/grub下的所有文件,并恢复,使启动时,没有任何人工干预能正常启动.

进入救援模式
chroot /mnt/sysimage           #更改root
grub-install /dev/sda 
cd /boot/grub
vim grub.conf
  default=0
  timeout=5
  title Centos 6.9
    root (hd0,0)
    kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=234f756b-b613-425b-af46-269c7cafd100(根的uuid) rhgb quiet
    initrd /initramfs-2.6.32-696.el6.x86_64.img
#保存退出
exit
exit

实验四:删除/boot下的所有文件,并恢复 

进入救援模式
chroot /mnt/sysimage           #更改root
grub-install /dev/sda 
cd /boot/grub
vim grub.conf
  default=0
  timeout=5
  title Centos 6.9
    root (hd0,0)
    kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=234f756b-b613-425b-af46-269c7cafd100(根的uuid) rhgb quiet
    initrd /initramfs-2.6.32-696.el6.x86_64.img
#保存退出
#此时我们恢复了grub,还缺少内核文件与伪根,(在/boot下系统启动中只需要这三个文件),我们进入rescue模式本身就是一个linux系统只是通过光盘启动,
#所以我们的光盘内存在一个内核文件
cp /media/isolinux/vmlinux /boot
mv vmlinux vmlinuz-2.6.32-696.el6.x86_64         #这个名字一定要与grub.conf内写的名字一样
mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)  #生成伪根
exit
exit

实验五:删除/etc/fstab 及/boot下的所有文件

这个试验中删除了分区表,所以进入rescue模式时我们的根无法自动挂载,需要我们手动挂载,并恢复/etc/fstab
进入rescue模式
df                   #产看自己的根是哪个分区,方便挂载
mount /dev/sda2 /mnt/sysimage #挂载根目录
blkid >> /mnt/sysimage/etc/fstab #将uuid导入fstab
vim /etc/fstab             #我们只需要把/,/boot,swap三个分区挂起就可保证系统启动的正确

  UUID=5822af4a-9e28-4f5c-9b33-879b507fcf70 / ext4 defaults 1 1
  UUID=c236dd51-f15d-40f4-89c4-338b1a838aab /boot ext4 defaults 1 2
  UUID=32ce5ce2-0e0d-4393-a610-56dfea47ba85 swap swap defaults 0 0

#保存退出

exit

exit

#我们推荐大家再次重启进入rescue模式验证/etc/fstab是否正确恢复

chroot /mnt/sysimage              #更改root
grub-install /dev/sda 
cd /boot/grub
vim grub.conf
  default=0
  timeout=5
  title Centos 6.9
    root (hd0,0)
    kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=234f756b-b613-425b-af46-269c7cafd100(根的uuid) rhgb quiet
    initrd /initramfs-2.6.32-696.el6.x86_64.img
#保存退出
# 我们除了从光盘中拷贝内核外,还可以再次安装内核恢复/boot
mount /dev/cdrom /media
rpm -ivh /media/Packages/kernel-2.6.32-696.el6.x86_64.rpm --force
exit
exit

实验六:删除/etc/fstab /etc/inittab(centos6 /etc/init/rcS.conf) /etc/rc.d/rc.sysinit /bootok

#恢复/etc/fstab 与恢复 /boot 与前几个实验相同,这里我们介绍恢复 /etc/inittab或/etc/init/rcS.comf  与/etc/rc.d/rc.sysinit/bootok
#这些文件都是通过rpm包安装附带创建的,我们可以重新安装对应的rpm包恢复,但是可能会会造成数据的丢失,我们介绍一种进可能减少数据丢失的方法
进入rescue模式
rpm -qf /etc/init/rcS.conf
  initscripts-9.03.58-1.el6.centos.x86_64
rpm -qf /etc/rc.d/rc.sysinit
  
initscripts-9.03.58-1.el6.centos.x86_64        #我们可以看出这两个文件来自同一个rpm包
mount /dev/cdrom /media
cp /media/Packages/initscripts-9.03.58-1.el6.centos.x86_64.rpm /app/ #拷贝该rpm包到/app下
rpm2cpio initscripts-9.03.58-1.el6.centos.x86_64.rpm |cpio -id #解开该安装包
cp etc/init/rcS.conf /etc/init                          #拷贝需要的文件到该文件目录下
cp etc/rc.d/rc.sysinit /etc/rc.d

猜你喜欢

转载自www.cnblogs.com/angge/p/9546020.html