Linux 系统启动流程与grub的应用

Linux 系统启动流程

  

POST –> BIOS(Boot Sequence) –> MBR(bootloader) –> kernel + initramfs(initrd) –> rootfs (ro) –> /sbin/init –> (/etc/inittab, /etc/init/*.conf) –>设定默认运行级别–>使用/etc/rc.d/rc.sysinit初始化系统 –> 分别启动并关闭指定服务 –> 启动终端

    1. post当我们按下开机的电源后,主板上的芯片组会首先向CPU发出一个reset指令,之后待芯片组检测到电源供电稳定后便撤去reset指令,CPU就会跳转到BIOS中的启动代码位置; BIOS首先要检测关键设备是否正常,这个过程就称为POST(加电后自检)。

    

    2MBRCPU读取可引导设备的第一个扇区即MBRMaster boot record),也称“主引导记录”,大小为512字节,其中存放着:

        引导加载程序(boot loader)446bytes,常用的boot loaderLILOGRUB,现以GRUB为主;

        分区表:64bytes

        有效性标记:2bytes

        CPU执行boot loaderboot loader选择要启动的内核(在当前磁盘的某或某些分区上)并加载到内存中

    

    3.kernel + initramfs内核被加载后,它要做的工作主要有:探测硬件、装载驱动程序、以只读方式装载根文件系统(rootfs)、启动第一个进程/sbin/init

备注:内核要装载根文件系统就需要先能驱动磁盘,即需要先装载驱动程序,而驱动程序又在磁盘上。为解决此问题,boot loader在加载内核的同时也把initramfs(或initrd)加载到内存中,它是一个临时的根文件系统,里面包含了启动所必须的驱动模块。内核挂载这个临时根,装载驱动程序,然后释放临时根,挂载实际的根文件系统,并启动第一个进程/sbin/init


    4.init:内核初始化的最后一步就是启动pid为1的/sbin/init进程。这个进程是系统的第一个进程,它负责产生其他所有进程。init进程上来首先做的事是去读取/etc/inittab和/etc/init/*.conf

 

init程序类型:

         SysV: init, CentOS 5

                  配置文件:/etc/inittab

         Upstart: init, CentOS 6

                  配置文件:/etc/inittab, /etc/init/*.conf

     Systemdsystemd, CentOS 7

                  配置文件:/usr/lib/systemd/system, /etc/systemd/system

 

在/etc/inittab和/etc/init/*.conf中,大致规定了以下动作: 

    取得runlevel即运行级别

    使用/etc/rc.d/rc.sysinit进行系统初始化

    根据runlevel启动相应的服务并关闭需要停止的服务

    确定Ctrl+Alt+Delete组合键功能

    启动字符终端

    启动图形终端

系统运行级别:

    0:关机

    1single user mode,单用户模式;直接以root身份登录,无需身份认证,且不会开启网络服务

    2multi user mode,不支持NFS功能

    3:完全多用户模式,文本接口

    4:未使用,预留级别

    5:完全多用户模式,图形接口

    6:重启

    可在命令行切换级别:init #

 

   blob.png                                         

配置文件:/etc/inittab

                id:runlevels:action:process

各字段的含义:

             id:登记项的标识符,必须是唯一的

             runlevels:系统的运行级别,表示processaction要在哪个级别下运行,可定义多个级别,各级别间不用

                        分隔符;如果为空,表示在所有的运行级别下运行

             具体的action有:

                 respawn:当process终止后马上启动一个新的

                 wait:当进入指定的runlevelsprocess才会启动一次,并且到离开runlevels为止

                 initfault:设定默认的运行级别

                 sysinit:系统初始化,只有系统开机或重启时process才会被执行一次

    5.sysinit: 在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本

                                               (1) 设置主机名;

                                               (2) 设置欢迎信息;

                                               (3) 激活udevselinux;

                                               (4) 挂载/etc/fstab文件中定义的文件系统;

                                               (5) 检测根文件系统,并以读写方式重新挂载根文件系统;

                                               (6) 设置系统时钟;

                                               (7) 激活swap设备;

                                               (8) 根据/etc/sysctl.conf文件设置内核参数;

                                               (9) 激活lvmsoftware raid设备;

                                               (10) 加载额外设备的驱动程序;

                                               (11) 清理操作;

    6.启动指定的默认级别的默认为启动的服务,停止指定的级别下默认为关闭的服务

       /etc/rc.d/rc#.d (#表示运行级别),该目录下都是符号链接文件,其指向的实际服务脚本位于/etc/rc.d/init.d目录中(该目录有个软链接/etc/init.d)。这些链接文件均以SK开头:

                S##:启动的服务

                K##:停止的服务

            ##01-99,数字越小,越优先启动或关闭

blob.png

注意:正常级别下,最后启动一个服务S99local没有链接至/etc/rc.d/init.d一个服务脚本,而是指向了/etc/rc.d/rc.local脚本;因此,不便或不需写为服务脚本放置于/etc/rc.d/init.d/目录,且又想开机时自动运行的命令,可直接放置于/etc/rc.d/rc.local文件中;

 

chkconfig:查看或修改服务随系统启动的启动选项,它并不是直接激活或停止一个服务,而只是修改了其符号链接。用法如下:

a) 让指定的服务接受chkconfig命令管理:

   第一步:在位于/etc/rc.d/init.d目录下的服务脚本中添加如下一行或多行注释:

     # chkconfig: LEVEL SPRI KPRI ,例如# chkconfig: – 85 15

        chkconfig后面有三个字段,它们的含义分别为:

        LEVEL:当此服务由chkconfig控制时,默认在哪些运行级是启动的。若默认不在任何运行级启动,以“”号表示

        SPRI:启动优先级

        KPRI:关闭优先级

    第二步:chkconfig –add SERVICE,该命令会自动在/etc/rc.d/rc#.d目录中创建链接文件

b) chkconfig del SERVICE:让指定服务不再接受chkconfig管理,会删除链接文件

c) chkconfig –list [SERVICE]:显示所有服务或指定服务的开机启动设置

d) chkconfig [–level ###] SERVICE on/off/reset:若不指定–level选项,onoff操作默认只对运行级2345有效,而reset默认对所有运行级有效,reset意为重置,即恢复成服务脚本中的初始设置

blob.png

grub应用


GRUB:grand uniform bootloader:统一引导加载器,找到操作系统所在的磁盘,并把内核加载到内存,将控制器转交给内核的程序。

GRUBGrand Unified Bootloader)是由GNU下的FSF组织所推行的;

CentOS 5CentOS 6上使用的版本为Grub 0.97

CentOS 7上使用的版本为Grub2  1.96

 

功能:MBR中的前 446 个字节,是BooTLoader的一种,提供一个菜单,允许用户选择要启动系统或不同的内核版本;把用户选定的内核装载到内存中的特定空间中,解压展开,把系统控制权移交给内核,主要是由device.mapmenulststage1,stage2,以及一系列的stage1_5组成。

blob.png

grub legacy:

            stage1: mbr (0柱面 0磁道 1扇区)

            stage1_5: mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统;

            stage2:磁盘分区(/boot/grub/),读取grub.conf配置文件,并实现引导功能的扩展

 

配置文件:/boot/grub/grub.conf <– /etc/grub.conf

配置项:

              1.default=#: 设定默认启动的菜单项;落单项(title)编号从0开始;

              2.timeout=#:指定菜单项等待选项选择的时长;

              3.splashimage=(hd#,#)/PATH/TO/XPM_PIC_FILE:指明菜单背景图片文件路径;

              4.hiddenmenu:隐藏菜单;

              5.password [–md5] STRING: 设置密码,菜单编辑认证;

              6.title TITLE:定义菜单项“标题”, 可出现多次;

a) root (hd#,#)grub查找stage2kernel文件所在设备分区;为grub的“根”;

b) kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:启动的内核,指定 kernel 文件的位置,还要             指出root(系统启动后)的位置,挂载方式 ro,这项很关键

c) initrd /PATH/TO/INITRAMFS_FILE: 内核匹配的ramfs文件;

d) password [–md5] STRING: 启动选定的内核或操作系统时进行认证;

blob.png

 

initramfs文件说明:initramfs-2.6.32-573.el6.x86_64.img

          nitramfs 是以 gzip 压缩的 cpio 格式的文件。内核启动时将他作为一个临时的根文件系统。

          grub stage2 initrd加载到内存里,然后将其中的内容释放到内存中,

          内核便去执行init脚本,这时内核将控制权交给了init文件处理。

          init 它也主要是加载各种存储介质相关的设备驱动程序。当所需的驱动程序加载完后,

          会创建一个根设备,然后将根文件系统rootfs以只读的方式挂载。

          这一步结束后,释放未使用的内存,转换到真正的根文件系统上面去,同时运行/sbin/init程序,

          执行系统的1号进程。此后系统的控制权就全权交给/sbin/init进程了。

blob.png

 

grub的功能:

          (1) 提供菜单、并提供交互式接口

                    e: 编辑模式,用于编辑菜单;

                    c: 命令模式,交互式接口;

blob.png

          (2) 加载用户选择的内核或操作系统

                                          允许传递参数给内核

                                          可隐藏此菜单

          (3) 为菜单提供了保护机制

                                          为编辑菜单进行认证

                                          为启用内核或操作系统进行认证

如何识别设备:

                       (hd#,#)

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

                                 #: 分区编号,用数字表示; 0开始编号

 

                                 (hd0,0)

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

 

示例1  grub保护机制,为grub设置密码,开机进入也需要输入密码

a) grub-md5-crypt生成密码

blob.png

b) 保护编辑功能,则需要title之外的添加

vi /boot/grub/grub.conf

password –md5 $1$.Co8f$ytb48fDRNEzwZBzE36GUv.

blob.png

 

        现在添加好密码到文件后 重启系统在开选择grub 就需要密码才能进入

       blob.png

示例2 如果忘记根密码就进入单用户模式修改密码

a) 启动计算机,在显示GRUB菜单时e, 进入编辑kernele

blob.png

 

b) 输入空格+single 回车b,重启系统进入单用户模式,输入以下命令更改口令:    

blob.png

blob.png

 

安装grub:

           (1) grub-install

                    grub-install –root-directory=ROOT /dev/DISK

                           

           (2) grub

                    grub> root (hd#,#)

                    grub> setup (hd#)

 

示例重新安装grub, grub-install安装

         dd if=/dev/zero of=/dev/sda bs=200 count=1 模拟破坏掉原来的grub

grub-install –root-directory=/ /dev/sda 重新安装grub

blob.png

示例4 grub命令提示符下修复grub

         dd if=/dev/zero of=/dev/sda bs=200 count=1 模拟破坏掉原来的grub

         grub

         root (hd0,0)

         setup (hd0)

 

示例在紧急救援模式下修复

d if=/dev/zero of=/dev/sda bs=200 count=1

放入光碟重启,进入救援模式,或者按住ESC 进入命令行提示符输入linux rescus

blob.png

   blob.png 

   blob.png

打开一好shell 命令提示符输入

chroot /mnt/sysimage

grub-install –root-directory=/ /dev/sda

reboot

blob.png

 

示例6 Vmware 虚拟机下制作grub

 

第一步:准备好块新磁盘,分3个区

blob.png

 

第二步:模拟启动时的boot目录,和根目录,并挂载。

mkdir /mnt/boot

mount /dev/sdb1 /mnt/boot/

blob.png

第三步:制作 grub,并生成 grub 的配置文件

grub-install –root-directory=/mnt /dev/sdb

blob.png

拷贝内核文件和initramfs 文件到 /mnt/boot 目录下,并生成 grub.conf 文件

cp /boot/vmlinuz-2.6.32-573.el6.x86_64 /mnt/boot/vmlinuz

cp /boot/initramfs-2.6.32-573.el6.x86_64.img /mnt/boot/initramfs.img

vi /mnt/boot/grub/grub.conf

blob.png

第四步: 生成根文件系统

mkdir /mnt/sysroot

mount /dev/sdb3 /mnt/sysroot/

cd /mnt/sysroot/

mkdir -pv etc bin sbin lib lib64 dev proc sys tmp var usr home root mnt media

 blob.png


第五步:拷贝使用命令和库到对应根目录下

cp /bin/bash /mnt/sysroot/bin/

ldd /bin/bash

cp /lib64/libtinfo.so.5 /mnt/sysroot/lib64/

cp /lib64/libdl.so.2  /mnt/sysroot/lib64/

cp /lib64/libc.so.6 /mnt/sysroot/lib64/

cp /lib64/ld-linux-x86-64.so.2 /mnt/sysroot/lib64/

sync

vi /mnt/boot/grub/grub.conf

blob.png

 

将刚才的磁盘镜像作为另一个虚拟机的启动盘。

blob.png

原创文章,作者:liangkai,如若转载,请注明出处:http://www.178linux.com/11641