linux操作系统启动流程 & grub简述

linux操作系统启动流程 & grub简述

CentOS 5 启动流程

1.POST:通电自检
2.BIOS:BOIS自检,加载硬盘
3.读取MBR,进行MBR引导
4.bootloader:grub引导菜单
5.加载内核 Kernel(ramdisk) 
6.启动init进程,依据inittab文件设定运行级别
7.init进程,执行rc.sysinit文件
8.启动内核模块,执行不同级别的脚本程序
9.执行/etc/rc.d/rc.local
10.启动mingetty,进入系统登陆界面。

1.BIOS

  打开计算机电源,计算机会首先加载BIOS信息。BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等。开机时将ROM中的指令映射到RAM的低地址空间,CPU读取到这些指令,硬件的健康状况进行检查,按照BIOS中设置的启动设备来启动。

2.MBR

  硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,它的大小是512字节,可里面却存放了预启动信息、分区表信息。
  系统找到BIOS所指定的硬盘的MBR后,就会将其复制到0×7c00地址所在的物理内存中。被复制到物理内存的内容就是Boot Loader,那就是lilo或者grub了。

3.bootloader

  Boot Loader 就是在操作系统内核运行之前运行的一段小程序。bootloader供一个菜单,允许用户选择要启动的系统或不同的内核版本; 把用户选定的内核装载到RAM中的特定空间中,解压、展开,而后把系统控制权移交给内核。

  Boot Loader有若干种,其中Grub、Lilo和spfdisk是常见的。

grub简介

grub启动三阶段:

  • stage1: 引导安装在MBR中的引导程序(bootloader)
  • stage1_5: mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统;
  • stage2:读取存放在磁盘上的grub(存放位置:/boot/grub),grub的配置文件:/boot/grub/grub.conf,在etc目录下有此文件的连接文件:/etc/grub.conf

 注意:stage2及内核通常放置于同一个磁盘分区。

grub stage2功用:

  • 提供菜单、并提供交互式接口
     e: 编辑模式,用于编辑菜单;
     c: 命令模式,交互式接口;

  • 加载用户选择的内核或操作系统
     允许传递参数给内核
     可隐藏此菜单

  • 为菜单提供了保护机制
     为编辑菜单进行认证
     为启用内核或操作系统进行认证

grub的命令行接口

help: 获取帮助列表
help KEYWORD: 详细帮助信息
find (hd#,#)/PATH/TO/SOMEFILE:
root (hd#,#)
kernel /PATH/TO/KERNEL_FILE: 设定本次启动时用到的内核文件;额外还可以添加许多内核支持使用的cmdline参数;
    例如:init=/path/to/init, selinux=0
initrd /PATH/TO/INITRAMFS_FILE: 设定为选定的内核提供额外文件的ramdisk;
boot: 引导启动选定的内核;

手动在grub命令行接口启动系统:
    grub> root (hd#,#)
    grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE 
    grub> initrd /initramfs-VERSION-RELEASE.img
    grub> boot

如何识别设备

(hd#,#)  
     hd#: 磁盘编号,用数字表示;从0开始编号    
     #: 分区编号,用数字表示; 从0开始编号  

grub配置文件

[root@localhost ~]# cat /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/sda2
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS 6 (2.6.32-696.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=d420f98e-b665-44d9-a4fd-e0e1503ea87c rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        initrd /initramfs-2.6.32-696.el6.x86_64.img

参数:
    default=#: 设定默认启动的菜单项;落单项(title)编号从0开始;
    timeout=#:指定菜单项等待选项选择的时长;
    splashimage=(hd#,#)/PATH/TO/XPM_PIC_FILE:指明菜单背景图片文件路径;
    hiddenmenu:隐藏菜单;
    password [--md5] STRING: 菜单编辑认证;
    title TITLE:定义菜单项“标题”, 可出现多次;
        root (hd#,#):grub查找stage2及kernel文件所在设备分区;为grub的“根”; 
        kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:启动的内核
        initrd /PATH/TO/INITRAMFS_FILE: 内核匹配的ramfs文件;
        password [--md5] STRING: 启动选定的内核或操作系统时进行认证;

实例:手动恢复grub

1>.屏幕上出现grub的启动项选择菜单时按c键也是可以进入grub>状态的

2>.输入“ root (hd ” ,然后按两次 TAB 键; /* 这会列出你电脑上可能的磁盘设备,硬盘为 hd0/hd1 或 sd0/sd1 等 */

然后,选择你的安装 Linux 系统的硬盘,比如 hd0 ,输入 “ root (hd0, ” 再按两次 TAB 键; /* 这会列出你的第一块硬盘上的分区情况,你会知道哪个是 swap 交换分区, 0x82 ,哪个是 Linux 分区 0x83 */

3>.cat指令是用来查看文件内容的,有时我们不知道Linux的/boot分区,以及/根分区所在的位置,要查看/etc/fstab的内容来得知
这时,我们就要用到cat (hd[0-n],y)/etc/fstab 来获得这些内容;注意要学会用tab键命令补齐的功能;

4>.root (hd[0-n,y) 指令来指定/boot所在的分区

选择你认为可能的 /boot 目录所在的分区:第一块硬盘第一个分区

5>.kernel 指令,用来指定Linux的内核,及/所在的分区

如果/boot有自己独立的分区,kernel格式如下;

kernel /vmlinuz在这里按tab键来补齐,就看到内核全称了 ro root=/dev/hd[a-z]X

6>.initrd 命令行来指定initrd文件

如果/boot是独立的一个分区,格式如下:

grub> initrd /init在这里tab 来补齐;

7>.boot 引导系统

前面的几个步骤都弄好 。就进入引导

4.加载内核

  Kernel,内核,Kernel是Linux系统最主要的程序,实际上,Kernel的文件很小,只保留了最基本的模块,并以压缩的文件形式存储在硬盘中,当GRUB将Kernel读进内存,内存开始解压缩内核文件。

  initrd(Initial RAM Disk),它在stage2这个步骤就被拷贝到了内存中,这个文件是在安装系统时产生的,是一个临时的根文件系统(rootfs)。因为Kernel为了精简,只保留了最基本的模块,因此,Kernel上并没有各种硬件的驱动程序,也就无法识rootfs所在的设备,故产生了initrd这个文件,该文件装载了必要的驱动模块,当Kernel启动时,可以从initrd文件中装载驱动模块,直到挂载真正的rootfs,然后将initrd从内存中移除。

  Kernel会以只读方式挂载根文件系统,当根文件系统被挂载后,开始装载第一个进程(用户空间的进程),执行/sbin/init,之后就将控制权交接给了init程序。

总结

  1. 探测可识别到的所有硬件设备;
  2. 加载硬件驱动程序;(有可能会借助于ramdisk加载驱动)
  3. 以只读方式挂载根文件系统:rootfs;
  4. 运行用户空间的第一个应用程序:/sbin/init

5. init:依据inittab文件设定运行级别

  内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/inittab文件,并依据此文件来进行初始化工作。其实/etc/inittab文件最主要的作用就是设定Linux的运行等级,其设定形式是“:id:5:initdefault:”,这就表明Linux需要运行在等级5上。Linux的运行等级设定如下:

[root@localhost ~]# cat /etc/inittab 
# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
# 
id:5:initdefault:

7个级别:
    0:关机, shutdown
    1:单用户模式(single user),root用户,无须认证;维护模式;
    2、多用户模式(multi user),会启动网络功能,但不会启动NFS;维护模式;
    3、多用户模式(mutli user),完全功能模式;文本界面;
    4、预留级别:目前无特别使用目的,但习惯以同3级别功能使用;
    5、多用户模式(multi user), 完全功能模式,图形界面;
    6、重启,reboot

默认级别:3, 5                   
级别切换:init #                 
级别查看:
    who -r
    runlevel 

配置文件/etc/inittab

每行定义一种action以及与之对应的process
    id:runlevels:action:process 

        id:一个任务的标识符,用于唯一标识每个登记项,不能重复
        runlevels:系统的运行级别,表示process的action要在哪个级别下运行,该段中可以定义多个运行级别,各级别之间直接写不用分隔符;如果为空,表示在所有的运行级别运行
        action:表示对应登记项的process在一定条件下所要执行的动作。
        process:任务;

    action:
        wait:等待切换至此任务所在的级别时执行一次;
        respawn:一旦此任务终止,就自动重新启动之;
        initdefault:设定默认运行级别;此时,process省略;
        sysinit:设定系统初始化方式,只有系统开机或重新启动的时候,这个process才会被执行一次,此处一般为指定/etc/rc.d/rc.sysinit脚本;

例子:
id:3:initdefault:
    表示我们默认的运行级别是3,也就是说我们默认开机启动会进入命令行模式。

si::sysinit:/etc/rc.d/rc.sysinit
    所所有的运行级别下,init依赖/etc/rc.d/rc.sysinit这个脚本对系统进行初始化


l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
.....
l6:6:wait:/etc/rc.d/rc 6

    l0:标识
    0:动作在0级别下运行
    wait:是指在切换至0级别时执行后面的process(/etc/rc.d/rc 0),并且init进程会等待直到这些进程终止。/etc/rc.d/rc 0 这是一个脚本,后面的0是传递进去的参数 ,传递进去0就代表着要去启动或关闭/etc/rc.d/rc0.d/目录下的服务脚本所控制服务;
        K*:要停止的服务;K##*,优先级,数字越小,越是优先关闭;依赖的服务先关闭,而后关闭被依赖的;
        S*:要启动的服务;S##*,优先级,数字越小,越是优先启动;被依赖的服务先启动,而依赖的服务后启动  

        [root@localhost rc1.d]# cd /etc/rc.d/rc0.d
        [root@localhost rc0.d]# ls
        K01smartd        K16abrt-ccpp               K60crond             K75ntpdate         K87irqbalance   K92ip6tables     K99sysstat
        K05atd           K16abrtd                   K61nfs-rdma          K75quota_nld       K87restorecond  K92iptables      K99vmware-tools
        K05wdaemon       K25sshd                    K73winbind           K75udev-post       K88auditd       K92pppoe-server  S00killall
        K10cups          K30postfix                 K74acpid             K83bluetooth       K88rsyslog      K95firstboot     S01halt
        K10psacct        K30spice-vdagentd          K74haldaemon         K84NetworkManager  K89netconsole   K95rdma
        K10saslauthd     K43vmware-tools-thinprint  K74ntpd              K84wpa_supplicant  K89portreserve  K99cpuspeed
        K15htcacheclean  K50dnsmasq                 K75blk-availability  K85mdmonitor       K89rdisc        K99lvm2-monitor
        K15httpd         K50kdump                   K75netfs             K85messagebus      K90network      K99rngd

6.系统初始化脚本rc.sysinit

系统初始化脚本:/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. 清理操作;

7.启动内核模块,执行不同级别的脚本程序

执行/etc/inittab中脚本:

l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
.....
l6:6:wait:/etc/rc.d/rc 6

8.执行/etc/rc.d/rc.local

/etc/rc.d/rc.local是给用户自定义启动时需要执行的文件。

9.启动mingetty,进入系统登陆界面

tty1:2345:respawn:/usr/sbin/mingetty tty1
... ...
tty6:2345:respawn:/usr/sbin/mingetty tty6

(1)mingetty会调用login程序;
(2)打开虚拟终端的程序除了mingetty之外,还有诸如getty等;

CentOS6启动流程

1.POST:通电自检  
2.BIOS:BOIS自检,加载硬盘  
3.读取MBR,进行MBR引导  
4.bootloader:grub引导菜单  
5.加载内核 Kernel(ramdisk)    
6.启动init进程,依据inittab文件设定运行级别 (inittab用于定义默认运行级别) 
7.init进程,执行rc.sysinit文件  
8.分别执行/etc/init/rcS.conf、/etc/init/rc.conf、/etc/init/start-ttys.confl来调用命令执行/etc/rc#.d/文件
        里面定义的是各种服务的启动脚本,可以ls查看,S开头代表开机启动的服务,K开头的是关机要执行的任务。#代表数字,一个数字代表一个运行级别,共7个运行级别,这里就不多说了
9.执行/etc/rc.d/rc.local  
10.执行/bin/login程序,等待用户登录

CentOS7启动流程

1.POST:通电自检  
2.BIOS:BOIS自检,加载硬盘  
3.读取MBR,进行MBR引导  
4.bootloader:grub引导菜单  
5.加载内核和inintamfs模块   
6.内核开始初始化,使用systemd来代替centos6以前的init程序
7.执行initrd.target
        包括挂载/etc/fstab文件中的系统,此时挂载后,就可以切换到根目录了
8.从initramfs根文件系统切换到磁盘根目录
        entos7表面是有“运行级别”这个概念,实际上是为了兼容以前的系统,每个所谓的“运行级别”都有对应的软连接指向,默认的启动级别时/etc/systemd/system/default.target,根据它的指向可以找到系统要进入哪个模式 
        模式:

        0 ==> runlevel0.target, poweroff.target
        1 ==> runlevel1.target, rescue.target
        2 ==> runlevel2.target, multi-user.target
        3 ==> runlevel3.target, multi-user.target
        4 ==> runlevel4.target, multi-user.target
        5 ==> runlevel5.target, graphical.target
        6 ==> runlevel6.target, reboot.target
9.systemd执行sysinit.target
10.systemd启动multi-user.target下的本机与服务器服务
11.systemd执行multi-user.target下的/etc/rc.d/rc.local
12.Systemd执行multi-user.target下的getty.target及登录服务
        getty.target是启动终端的systemd对象。如果到此步骤,系统没有被指定启动图形桌面,到此就可以结束了,如果要启动图形界面,需要在此基础上启动桌面程序
13.systemd执行graphical需要的服务

区别

你可能感兴趣的:(linux)