Linux系统启动流程

Linux启动流程

linux启动根据下边图片来进行说明
在这里插入图片描述
说明1:黑色的为主步骤,蓝色为分支步骤,绿色为注释。下面详解一下,也给自己加深印象

BIOS

BIOS(Basic Input Output System):基本输入输出系统。BIOS都存放在ROM(Read Only Memory,只读存储器)中。ROM内部的资料是在ROM的制造工序中,在工厂里用特殊的方法被烧录进去的,其中的内容只能读不能改,一旦烧录进去,用户只能验证写入的资料是否正确,不能再作任何修改。如果发现资料有任何错误,则只有舍弃不用。

1、上电自检:(POST:Power-On-Self-Test)是BIOS功能的一个主要部分。它负责完成对CPU、主板、内存、软硬盘子系统、显示子系统(包括显示缓存)、串并行接口、键盘、CD-ROM光驱等的检测。当我们计算机上的某一个硬件出现问题时,BIOS在这个阶段就会报错,导致无法启动。

2、Boot Squence:在完成POST自检后,ROM BIOS将按照系统CMOS设置中的启动顺序搜寻软硬盘驱动器及CDROM、网络服务器等有效的启动驱动器 ,读入操作系统引导记录,然后将系统控制权交给引导记录,由引导记录完成系统的启动。
BIOS完成这两个步骤后,就要交由MBR的bootloader来进行引导

读取MBR

MBR(Main Boot Record)称为主引导记录,它位于磁盘的0编号分区。大小为512bytes,其中446bytes中放置bootloader程序。64bytes放置分区表信息,2bytes用于MBR分区的有效检查
注意:bootloader引导加载器是一个程序,无法在逻辑卷上加载,只能是标准分区
对于bootloader来说,它的主引导程序分为两种:
LILO:LInux LOader,缺点:放到1024柱面之后的加载程序无法启动。现在已经用的很少
GRUB:Grand Uniform Bootloader,多系统启动程序。这里就以grub来进行说明:
grub的执行分为三个阶段:
      stage1、存放在MBR分区,也就是bootloader。
      stage1.5、MBR之后的扇区,让第1步中的bootloader能够识别出第3步的文件系统
      stage2、存放在磁盘分区之上(/boot/grub),根据grub的配置文件(/boot/grub/grub.conf)查找内核信息,然后加载内核至内存中,并创建initrd(ramdisk)文件。而后把系统控制权交给内核。

initrd说明:

initrd:bootloader initialized RAM disk 是bootloader的初始化内存盘。该文件是在安装系统时自动产生的。并在stage2步骤同内核一起加载至内存中。在内核启动之后会先访问此文件系统,用来帮助挂载真正的根目录。centos5之前相对应的文件为initrd。centos6,7相对应的文件为initramfs
为什么要有这个文件?
由于linux面对的硬件架构不同,把所有市面上可见的硬件驱动写入内核中显然不太现实。所以内核中只保留了最基础的驱动。剩下的一部分驱动则在系统安装过程中写入了initrd中。

运行kernel

当内核接收到控制权后,会进行自身初始化:
1、探测可识别到的所有硬件设备
2、加载硬件驱动程序
3、以只读方式挂载根文件系统
4、运行用户空间的第一个程序/sbin/init
这时候系统的控制权全部交由init进程来管理

init

init进程是所有进程的父进程,在这一步,它主要根据配置文件、运行脚本来初始化系统。以便让用户以自己指定的某种方式运行系统。主要流程:
设置默认级别—>运行系统初始化脚本,完成系统初始化–>关闭对应级别下需要停止的服务,启动对应级别下需要开启的服务–>设置登录终端[–> 启动图形终端]

1、init的运行级别

运行级别解释
0关机
1单用户模式,此级别会直接进入root用户,属于维护模式
2多用户模式,此级别会启动网络功能,但不会启动NFS,属于维护模式
3多用户模式,此级别只会启动文本界面,属于全功能模式
4预留级别,此级别目前特别适用目的
5多用户模式,此级别会启动图形界面,具有完全功能
6重启
示例:
     各级别之间的相互切换:
                 ~# init #
     级别查看:
      [root@localhost ~]# who -r 
             运行级别 5 2019-04-02 17:04

init配置文件都在/etc/initab中,每行定义一种action以及与之对应的process

 id:runlevels:action:process
      #以下说明每个字符表示的含义
            id:一个任务的标识符
            runlevels:在哪些 级别下启动某些任务,如 #,###(代表级别数字) 也可以表示为空
            action:在什么条件下启动任务、
            process:任务,如启动程序、执行脚本等
      
      # action的条件有如下几种:
               wait:等待切换至此任务所在的级别时执行一次
               respawn:一旦任务进行终止,就自动重新启动
               indefault:设定默认级别,此时process为空,不能为0和6
               sysinit:系统初始化,只有在系统重启或开始时,才会执行一次process     
  例如:
          id:3:indefault:    #表示设置默认级别为3
          si::sysinit:/etc/rc.d/rc.sysinit     #表示系统在重启或开机时,执行后面的rc.sysinit的脚本

2、系统初始化

系统初始化脚本放在/etc/rc.d/rc.sysinit文件中,该文件的主要功能:
1、设置主机名
2、设置欢迎信息
3、激活udev和selinux
4、挂载/etc/fstab文件中定义的所有文件系统
5、检测根文件系统,并以读写的方式重新挂载根文件系统
6、设置系统时钟
7、根据/etc/sysctl.conf文件中的配置来设置内核参数
8、激活LVM和raid设备
9、激活swap设备
10、加载额外的驱动程序
11、清理操作

系统初始化完成之后,系统开始执行关闭和开启一些服务脚本

3、关闭和开启相对应的服务

这一步系统会执行/etc/rc.d/rc #(#号代表运行级别,总共有7个级别) 下的脚本。其中K*是要关闭的服务,S*是要开启的服务。

#此处为rc0.d下的脚本
[root@ydong rc0.d]# ls
K01certmonger      K15httpd           K60crond       K75blk-availability  K84NetworkManager  K89netconsole    K99lvm2-monitor
K01libvirt-guests  K15svnserve        K60nfs         K75netfs             K84wpa_supplicant  K89portreserve   K99rngd
K01smartd          K16abrt-ccpp       K61nfs-rdma    K75ntpdate           K85mdmonitor       K89rdisc         K99sysstat
K02oddjobd         K16abrtd           K69rpcsvcgssd  K75quota_nld         K85messagebus      K90network       S00killall
K05atd             K25sshd            K72autofs      K75udev-post         K87irqbalance      K92ip6tables     S01halt
K05wdaemon         K30postfix         K73pcscd       K76ypbind            K87restorecond     K92iptables
K10cups            K30spice-vdagentd  K73winbind     K83bluetooth         K87rpcbind         K92pppoe-server
K10psacct          K36mysqld          K74acpid       K83nfslock           K88auditd          K95firstboot
K10saslauthd       K50dnsmasq         K74haldaemon   K83openct            K88rsyslog         K95rdma
K15htcacheclean    K50kdump           K74ntpd        K83rpcgssd           K88sssd            K99cpuspeed

说明:
k*:要停止的服务;k##,优先级,数字越小,越先有限关闭;依赖的服务先关闭,而后关闭被依赖的服务
S*:要启动的服务;S##, 优先级,数字越小,越是优先启动;被依赖的服务先启动,而后启动依赖的服务

4、执行/etc/rc.d/rc.local脚本

此脚本功能主要放置用户需要开机就自动运行的命令

5、执行/sbin/login

最后一步执行/sbin/login,等待用户登录

说明:以上init的所有操作均是centos5上的操作,centos6上的init仍为/sbin/init,但是使用的upstart风格,centos7的init程序则变成了systemd。6和7同时兼容sysV init(也就是5的init程序)。

grub多系统引导程序

以上的grub只是作为centos启动流程里提了一下,此处将做详细说明。
grub作为一个引导程序,它的功能提供一个菜单,允许用户选择要启动的系统和不同的内核版本,把用户选择到的内核版本加载至内存中的特定空间,对其解压、展开。而后将控制权交给内核。

它目前有两个版本:
grub 0.x:grub legacy(centos6使用)
grub 1.x:grub2(centos7使用)

grub执行的步骤

stage1:即写入MBR的bootloader程序。
stage1.5:执行mbr之后的扇区,让stage1中的bootloader程序能够识别磁盘分区/boot/grub上的文件并载入内存中。
注意:此处若是boot分区的文件系统类型不属于stage1_5的中的一个,则会借助ramdisk来加载在/lib64/moudles/下额外的文件系统驱动。
stage2:位于磁盘分区/boot/grub之上,该步骤主要给用户提供一个友好的菜单。并加载/boot下的内核文件至内存中。

grub的功用及配置文件

grub主要具有以下几种功用:

          1、提供菜单、并提供交互式接口
                   e:编辑模式,用于编辑菜单
                   c:命令模式,交互式接口
          2、加载用户选择的内核或操作系统           
                   允许传递参数给内核                     
                   可隐藏此菜单
          3、为菜单提供保护机制 
                   为编辑菜单进行认证
                   为启动内核为操作系统进行认证

grub的配置文件:/boot/grub/grub.conf

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/sda3
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0       #设定默认启动的菜单项,编号从0开始
timeout=5       #指定菜单项等待用户选择的时长
splashimage=(hd0,0)/grub/splash.xpm.gz      #指明菜单的背景图片
hiddenmenu    #隐藏菜单,若要显式,在启动时按下ESC
title CentOS 6 (2.6.32-642.el6.x86_64)    #定义菜单标题,可出现多次,便于内核的启动,以下都需要缩进
        root (hd0,0)    #grub查找stage2或kernel文件所在的设备分区。此为grub的根。
        kernel /vmlinuz-2.6.32-642.el6.x86_64 ro root=/dev/sda2 rhgb quiet   启动的内核,指定根文件所在系统分区,后面为一些参数,下面会说明
        initrd /initramfs-2.6.32-642.el6.x86_64.img #指明ramfs文件
~                                                     

注意:在一个正常的操作系统中查看/boot/grub/grub.conf文件,可以在NOTICE段看到提示,说你是否拥有一个独立的boot分区?如果有则意味着kernel和initrd的路径是从/开始的而不是/boot开始的,如/vmlinuz-xxx,如果没有独立的boot分区,则kernel和initrd的路径中需要指明boot路径,例如Boot没有分区而是在/文件系统下的一个目录,则/boot/vmlinuz-xxx。
root (hd0,0)定义grub识别的根。一般定义的都是boot所在的分区,grub只能识别hd,所以这里只能使用hd,hd0表示在第一块磁盘上,hd0,0的第二个0表示boot在第一个分区上,grub2在分区的计算上是从1开始的,这是传统grub和grub2不同的地方。
kernel定义内核文件的路径和启动参数,等价于grub2的linux命令或linux16命令。首先说明参数,ro表示只读,root=/dev/sda[N]或者root=UUID="device_uuid_num"指定根文件系统所在的分区,这是必须的参数。rhgb表示在操作系统启动过程中使用图形界面输出一些信息,将其省略可以加快启动速度,quiet表示启动操作系统时静默输出信息。再说明路径,如果是boot是独立分区的,则kernel的路径定义方式为/vmlinuz-xxx,如果没有独立分区,则指明其绝对路径,一般都是在根文件系统下的目录,所以一般为/boot/vmlinuz-xxx。
initrd定义init ramdisk的路径,路径的定义方式同kernel。除了路径之外没有任何参数。

grub的命令行接口

直接输入grub,将会出命令行接口。下面介绍常用选项

[root@ydong ~]# grub
Probing devices to guess BIOS drives. This may take a long time.


    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)

 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename.]
grub> help      

选项说明
help获取帮助
help KEYWORD详细帮助信息
find (hd#,#) /pah/to/somefile查找文件
root(hd#,#)设定grub的根
kernel /PATH/TO/SOMEFILE指定本次要启动的内核文件
initrd /PATH/TO/INITRAMFS_FILE设定为选定的内核提供额外文件的ramdisk,ramdisk必须与内核版本恩完全匹配
boot引导启动选定的内核

手动在grub命令行接口启动系统:

                  root (hd#,#)
                  kernel /vimlinuz-VERSION-RELEASE ro root=/dev/DEVICE
                  initrd /initramfs-VERSION-RELEASE.img
                  boot 

进入单用户模式:

centos6:
      1、编辑grub菜单(选定要编辑的title,然后使用e命令)
      2、在选定的kernel后附加:
                  1,s,S或single都可以
      3、在kernel所在行,键入"b"命令
CentOS 7:
    centos7的grub2界面会有两个入口,正常系统入口和救援模式,
    e 键进入edit 模式。
    找到以 linux16 开头的行,注意:只在该行里面进行操作。
        1:
            (1)把 ro更改成 rw ;(把只读更改成可写)
            (2)把 rhgb quiet 删除;(quiet静默模式,可以不删)
            (3)增加 init=/bin/bash;(或init=/bin/sh,指定shell环境)
            (4) 按下 ctrl+x 来启动系统。
            .....修改操作......
            (5)重启
        2:
            (1)该行最后输入 rd.break
            (2)ctrl+x 启动系统
            (3)进去后输入命令 mount,发现根为/sysroot/,并且不能写,只有ro=readonly权限;
                    mount -o remount,rw /sysroot/,重新挂载,之后mount,发现有了r,w权限;
            (4)chroot /sysroot/ 改变根
             .....修改操作......
            (5)ctrl+d 或者 exit  退出
            (6)重启

grub的安装

(1)grub-install 命令
使用格式:grub-install --root-directory=/PATH/TO/rootDIR DEVICE
~]# grub-install --root-directory=/ /dev/sda3
~]# sync

(2)grub命令(shell中输入)
~]# grub
grub> root (hd0,0)
grub> setup (hd0)
grub> quit
~]# sync

(3)如果mbr中的bootloader程序损坏
插入一个系统引导光盘,进入救援模式重新安装grub

grub练习

        新加硬盘,提供直接单独运行bash系统;         

1、首先,我们先新添加一块硬盘sdb。

[root@bogon ~]# fdisk -l

Disk /dev/sda: 128.8 GB, 128849018880 bytes
255 heads, 63 sectors/track, 15665 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000150b0

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          64      512000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              64       15666   125316096   8e  Linux LVM

Disk /dev/sdb: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

2、我们分别来创建3个分区,分别为作grub启动的sdb1、和作为grub根的sdb2,外加一个swap分区


[root@bogon ~]# fdisk /dev/sdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x63ffbd19.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p  
Partition number (1-4): 1
First cylinder (1-2610, default 1): 
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610): +500M

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (66-2610, default 66): 
Using default value 66
Last cylinder, +cylinders or +size{K,M,G} (66-2610, default 2610): +5G

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (720-2610, default 720): 
Using default value 720
Last cylinder, +cylinders or +size{K,M,G} (720-2610, default 2610): +2G

Command (m for help): t
Partition number (1-4): 3
Hex code (type L to list codes): 82
Changed system type of partition 3 to 82 (Linux swap / Solaris)

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
[root@bogon ~]# partx -a /dev/sdb
BLKPG: Device or resource busy
error adding partition 1
BLKPG: Device or resource busy
error adding partition 2
BLKPG: Device or resource busy
error adding partition 3
[root@bogon ~]# cat /proc/partitions 
major minor  #blocks  name

   8        0  125829120 sda
   8        1     512000 sda1
   8        2  125316096 sda2
   8       16   20971520 sdb
   8       17     522081 sdb1
   8       18    5253255 sdb2
   8       19    2104515 sdb3
 253        0   52428800 dm-0
 253        1    2031616 dm-1
 253        2   70852608 dm-2

4、分别将sdb1、sdb2、sdb3的文件系统格式化为ext4、ext4和swap。

[root@bogon ~]# mke2fs -t ext4 /dev/sdb1

[root@bogon ~]# mke2fs -t ext4 /dev/sdb2

[root@bogon ~]# mkswap /dev/sdb3

5、安装grub时,grub会自动的去寻找boot目录来进行安装,所以我们创建一个/mnt/boot的目录,并将sdb1挂载至此处。

[root@bogon ~]# mkdir /mnt/boot
[root@bogon ~]# mount /dev/sdb1 /mnt/boot
[root@bogon boot]# ls
lost+found

##以下这步为grub安装。
[root@bogon boot]# grub-install --root-directory=/mnt /dev/sdb
Probing devices to guess BIOS drives. This may take a long time.
Installation finished. No error reported.
This is the contents of the device map /mnt/boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.

(fd0)	/dev/fd0
(hd0)	/dev/sda
(hd1)	/dev/sdb

6、创建一个grub的根,并将sdb2挂载至此处。

[root@bogon ~]# mkdir /mnt/sysroot

[root@bogon ~]# mount /dev/sdb2  /mnt/sysroot/

#此根需要与当前系统根上的目录一样,如果需要运行程序或者运行某些命令的话,只需将同等路径下的命令程序复制到相对应Grub根上的目录即可。
[root@bogon sysroot]# mkdir -pv root dev proc sys tmp mnt home var bin sbin lib lib64 etc 
[root@bogon sysroot]# cp /bin/bash ./bin

#复制完命令还不行,我们需要将它依赖的动态库也复制到相对应的路径目录里。
[root@bogon sysroot]# ldd /bin/bash
	linux-vdso.so.1 =>  (0x00007ffcd30af000)
	libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f47d96ca000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f47d94c6000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f47d9131000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f47d98f6000)
[root@bogon sysroot]# cd 
[root@bogon ~]# cp /lib64/libtinfo.so.5 /mnt/sysroot/lib64
[root@bogon ~]# cp /lib64/libdl.so.2 /mnt/sysroot/lib64
[root@bogon ~]# cp /lib64/libc.so.6 /mnt/sysroot/lib64
[root@bogon ~]# cp /lib64/ld-linux-x86-64.so.2 /mnt/sysroot/lib64

##切换根来尝试是否成功

[root@bogon ~]# chroot /mnt/sysroot/
bash-4.1# hklj

7、将当前系统下的内核和initrd文件复制到/mnt/boot目录下。并编写grub配置文件(grub安装好之后需要自己现写配置文件)。

[root@bogon ~]# cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/boot/vmlinuz
[root@bogon ~]# cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot/initramfs

#以下为配置文件内容
default=0
timeout=10
title mycentos
        root (hd0,0)
        kernel /vmlinuz ro root=/dev/sda2 selinux=0 init=/bin/bash
        initrd /initramfs
~                           

8、将做好的此块硬盘添加至新虚拟机里即可。

在这里插入图片描述

练习:分别用while、for循环检测10.0.0.1/24网段存活的IP地址

10.0.0.1/24网段的IP地址范围为:10.0.0.1-10.0.0.254,以下演示为前两个ip地址。
while循环:



#!/bin/bash

declare -i ip=1;
while [ $ip -ne 3 ]; do
         {
                ping -c 1 10.0.0.$ip >/dev/null
                 if [ $? -eq 0 ];then
                         echo  "ipaddress is : 10.0.0.$ip running"
                elif [ $? -ne 0 ];then
                        echo "ipaddress is : 10.0.0.$ip down"
                 fi
        }
        let ip++
done

[root@localhost ~]# bash ipaddr.sh 
ipaddress is : 10.0.0.1 down
ipaddress is : 10.0.0.2 down


for循环:

#!/bin/bash

for ip in {1..3};do
        ping -c 1 10.0.0.$ip >/dev/null
        if [ $? -eq 0 ];then
                echo "address  10.0.0.$ip is running"
        else
                echo "address 10.0.0.$ip is down"
        fi
        let ip++
done
~              
[root@localhost ~]# bash ipaddr-for.sh 
address 10.0.0.1 is down
address 10.0.0.2 is down
address 10.0.0.3 is down

练习:while循环打印出乘法口诀

  1 #!/bin/bash
  2 declare -i i=1
  3 while [ $i -lt 10 ];do
  4         {
  5         declare -i j=1
  6           while [ $j -le $i ];do
  7                 echo -n  "$j * $i "
  8                 let j++
  9          done
 10         }
 11         echo " "
 12         let i++
 13 done
~            
[root@localhost ~]# bash chengfa.sh 
1 * 1  
1 * 2 2 * 2  
1 * 3 2 * 3 3 * 3  
1 * 4 2 * 4 3 * 4 4 * 4  
1 * 5 2 * 5 3 * 5 4 * 5 5 * 5  
1 * 6 2 * 6 3 * 6 4 * 6 5 * 6 6 * 6  
1 * 7 2 * 7 3 * 7 4 * 7 5 * 7 6 * 7 7 * 7  
1 * 8 2 * 8 3 * 8 4 * 8 5 * 8 6 * 8 7 * 8 8 * 8  
1 * 9 2 * 9 3 * 9 4 * 9 5 * 9 6 * 9 7 * 9 8 * 9 9 * 9        

内核

内核,是一个操作系统的核心。它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。它的设计分为两大流派:单内核和双内核。
在这里插入图片描述
内核的主要功能:
在这里插入图片描述
内核的组成部分:

 kernel:内核核心,一般为bzimage,通常位于/boot目录下,其名称为vmlinuz-VERSION-release
 kernel object:内核对象,即内核模块,一般放置于/lib/modules/VERSION-release/
            注意: 内核模块和内核核心版本一定要严格匹配

systemd、upstart和sysv的区别
https://www.cnblogs.com/baiyw/p/3504419.html
网络内核参数以及相关问题解释
https://help.aliyun.com/knowledge_detail/52868.html

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值