第3章 Linux 启动过程和系统引导器GRUB

                                                      第3章  Linux 启动过程和系统引导器GRUB

3.1 Linux启动过程

3.1.1 Linux启动过程详解

    1.从计算机BIOS到Linux内核

    (1)BIOS自检

    (2)提取MBR的信息

    查看MBR的内容:

    -->dd if=/dev/sda of=mbr.bin bs=512 count=1   #os -xa mbr.bin

记录了1+0 的读入
记录了1+0 的写出
512字节(512 B)已复制,0.000151686 秒,3.4 MB/秒


    这个dd命令需要以root用户的身份运行,它从/dev/sda(第一个SCSI盘)上读取前512字节的内容,并将其写入

mbr.bin文件中。od命令会以十六进制和ASCIL码格式打印这个二进制文件的内容。

    -->od mbr.bin 

0000000 061753 010220 150216 000274 134260 000000 154216 140216
0000020 137373 076000 000277 134406 001000 122363 020752 000006
0000040 137000 003676 002070 005565 143203 100420 177376 072407
0000060 165763 132026 130002 135401 076000 100262 072212 105401
0000100 001114 011715 000352 000174 165400 000376 000000 000000
0000120 000000 000000 000000 000000 000000 100000 000001 000000
0000140 000000 000000 175377 110220 141366 072200 173005 070302
0000160 001164 100262 074752 000174 030400 107300 107330 136320
0000200 020000 120373 076144 177474 001164 141210 137122 076005
0000220 040664 125273 146525 055023 071122 100475 052773 072652
0000240 101467 000741 031164 140061 042211 040004 042210 104777
0000260 001104 002307 000020 105546 056036 063174 056211 063010
0000300 017213 076140 104546 006134 042307 000006 132160 146502
0000320 071023 135405 070000 073353 004264 011715 006563 102132
0000340 007722 157203 137000 076605 101351 063000 133017 104306
0000360 177544 063100 042211 007404 150666 161301 104002 104350
0000400 040364 042211 007410 141266 164300 063002 002211 120546
0000420 076140 004546 072700 063116 056241 063174 151061 173546
0000440 104064 030721 063322 072367 035404 004104 033575 140776
0000460 142610 140060 164301 004002 104301 055320 143210 000273
0000500 107160 030703 134333 001001 011715 017162 141614 017140
0000520 000271 107001 030733 137766 100000 143216 171774 017645
0000540 177541 055046 137174 076600 001753 107676 164175 000064
0000560 112276 164175 000056 014315 177353 051107 041125 000040
0000600 062507 066557 044000 071141 020144 064504 065563 051000
0000620 060545 000144 042440 071162 071157 005015 135400 000001
0000640 007264 010315 036254 072400 141764 000000 000000 000000
0000660 000000 000000 000000 000000 071642 000012 000000 020200
0000700 000041 156603 037436 004000 000000 120000 000017 156400
0000720 037437 177203 177777 124000 000017 054000 005760 177000
0000740 177777 177202 177777 000000 006000 000000 000200 000000
0000760 000000 000000 000000 000000 000000 000000 000000 125125
0001000


    2.启动GRUB

    GRUB是引导加载程序,引导加载程序(Boot Loader)会引导操作系统。当机器引导它的操作系统时,BIOS会读取

引导介质上最前面的512字节,即主引导记录(MBR)。在单一的MBR中只能存储一个操作系统的引导记录,所以当需要

多个操作系统时就会出现问题,因此需要更灵活的的引导加载程序。

    3.加载内核

    当内核映像被加载到内存之后,内核阶段就开始了。通过它是一个zImage或bzImage,它是提前使用zlib进行压缩的。

如果有初始RAM磁盘映像,就会将它移动到内存中,并标明以后使用。


    使用initrd映像引导一个特定的内核,方法如下:

    -->grub> kernel /bzImage-2.6.14.2

    [Linux-baImage, setup=0x1400, size=0x29672e]

    -->grub> inittf /initrd-2.6.14.2.img

    [Linux-initrd @ 0x5f13000, 0xcc199 bytes]

    -->grub> boot

    AUncompressing Linux... Ok, booting the kernel.



    4.执行init进程

    init进程是系统所有进程的起点,内核在完成内核引导以后,即在本线程(进程)空间内加载init程序,它的

进程号是1.init进程是所有进程的发起者和控制者。

    init进程有两个作用:

    (1)扮演终结父进程的角色

    (2)在进入某个特定的目标时运行相应的程序,以此对各种运行基本进行管理。


    5.systemd的init进程

    systemd加载所需的服务和用户空间工具,并且挂载文件系统/etc/fstab,然后用户可以看到Linux

系统的登录界面。systemd负责协调引导过程的其余部分并配置为用户的环境。

    systemd可以处理程序之间的依赖关系,通过包括如下步骤:

    。设置主机名

    。初始化网络

    。初始化SELinux配置
  
    。打印欢迎横幅

      * 初始化基于内核启动参数的系统硬件

      * 安装文件系统,包括虚拟文件系统,如/proc文件系统

    。清理/var目录

    。设置交换分区


    Linux三种启动方式的比较:


    init 、 upstart  、 systemd


    systemd具有如下特点:

    * 启动速度较快

    * 提供系统服务快照

    * 挂载及自动挂载管理

    * 以事务系统处理相依服务

    * 服务的自动实时更新、重新启动与暂时停止

    * 使用Linux核心cgroup功能进行管理

    
    systemd架构包括:

    * systemd Utillties 

    * systemd Targets

    * systemd Core

    * systemd Libraries

    * Linux Kernel 

3.1.2 Linux运行级别到目标

    systemd使用目标取代了运行级别的概念

                           运行级别和目标对应表

    --------------------------------------------------------------------------
       sysvinit                              systemd 
    --------------------------------------------------------------------------
         init 0                          systemctl poweroff
    --------------------------------------------------------------------------
         init 1                          systemctl isolate rescue.target
    --------------------------------------------------------------------------  
         init 3                          systemctl isolate multi-user.target
    --------------------------------------------------------------------------
         init 5                          systemctl isolate graphical.target
    --------------------------------------------------------------------------
         init 6                          systemctl reboot
    --------------------------------------------------------------------------


    Red Hat Enterprise Linux 7.0的启动流程:

 
    结束-->初始化BIOS--->执行启动加载器--->载入内核-->启动init服务--->开始
                                                      
                                                    /          <--/
           <-----------------------------------------            /
          -------------------------------------------------------------
          |                              systemd                      |
           ------------------------------------------------------------


3.2 系统引导器GRUB

3.2.1 GRUB 2简介

    Linux 7.0中使用GRUB 2作为默认的启动引导器。改进如下:

    。自动搜索可用的内核和硬盘中的可用系统

    。可支持NTFS等更多的分区格式。

    。可启动Windows、Mac OS X等多种系统

    。更人性化的设计。


    从配置的角度看,GRUB 2主要有以下几点不同:

    。/boot/grub/menu.lst被/boot/grub/grub.cfg所取代

    。主配置文件grub.cfg不能直接被用户修改,而是由系统自动生成。

    。每当安装内核、更新GRUB 2或用户主动运行grub-mkconfig -o /boot/grub/grub.cfg后,

GRUB 2会根据用户配置文件重新生成grub.cfg。

    。可编辑的GRUB 2 配置文件主要包括/etc/default/grub和/etc/grub.d/下的各文件。

    。分区命令方式有变,第一个分区现在是1而不是0,但第一个设备仍然以0开始计数,如(hd,1)表示

第一块硬盘上的第一个分区。

                                      GRUB和GRUB 2对比
    ------------------------------------------------------------------------------------
                            GRUB (RHEL 6)                 GRUB 2(RHEL 7)
    ------------------------------------------------------------------------------------
          配置文件     /boot/grub/grub.conf              /boot/grub2/grub.cfg

                       /boot/efi/EFI/redhat/grub.conf    /boot/efi/EFI/redhat/grub.cfg  
                             
                                                         /etc/default/grub

                                                         /etc/grub.d/*
    ------------------------------------------------------------------------------------
          GRUB模块文件  /boot/grub/*_stage1_5            /boot/grub2/i386-pc/*.mod

                                                         /boot/grub2/x86_64-efi/*.mod
    ------------------------------------------------------------------------------------
          GRUB安装命令  grub-intall                      grub2-install
    ------------------------------------------------------------------------------------
          安装引导加载程序    无                         grub2-mkconfig
    ------------------------------------------------------------------------------------
          加密方法      grub-crypt                       grub2-mkpasswd-pbkdf2
    ------------------------------------------------------------------------------------
          设置默认启动        无                         grub2-set-default
    ------------------------------------------------------------------------------------


3.2.2 GRUB的启动菜单界面

    启动时按Esc可显示启动菜单。

    Red Hat Enterprise Linux Server, with Linux 3.10.0-123.el7.x86_64

    Red Hat Enterprise Linux Server, with Linux 0-rescue-190403ad328541daab2->

 
                                     GRUB的启动菜单按键
    ----------------------------------------------------------------------------
         按 键                            功能说明
    -----------------------------------------------------------------------------
         ↓↑                         使用上下方向键,在启动菜单项间进行移动 
    -----------------------------------------------------------------------------
         Enter                        按下回车键启动当前的菜单项
    -----------------------------------------------------------------------------
         E                            按下E键编辑当前的启动菜单项
    -----------------------------------------------------------------------------
         C                            按下C键进入GRUB的命令行方式
    -----------------------------------------------------------------------------

3.2.3 GRUB的启动菜单编辑界面


                                     GRUB的启动菜单项编辑按键
    ----------------------------------------------------------------------------
         按 键                            功能说明
    -----------------------------------------------------------------------------
         ↓↑                         使用上下方向键,在启动菜单项间进行移动 
    -----------------------------------------------------------------------------
         E                            按下E键编辑当前选中的行
    -----------------------------------------------------------------------------
         Ctrl+C                       进入命令行状态
    -----------------------------------------------------------------------------
         Ctrl+X                       以编辑的内容启动
    -----------------------------------------------------------------------------
         Esc                          按下Esc键返回,回到菜单项
    -----------------------------------------------------------------------------


3.2.4 GRUB 2 命令行界面
 
    GRUB两种方法进入命令行界面

    。从GRUB的启动菜单进入命令行界面: 命令行界面支持的命令比较完整

    。在Shell状态下使用grub进入命令行界面:受操作系统的限制很多命令不能使用。


    1.GRUB命令行界面的特点

    。提供在线帮助命令“help”,并且可以获得每条命令的详细帮助说明。

    。可使用左右方向键编辑行命令。

    。可使用上下方向键滚动历史命令。

    。可使用Tab键补全命令和路径。


    2.从GRUB的启动菜单进入命令行界面

    在GRUB的启动菜单项编辑界面中按下C键可进入GRUB命令行界面。使用Esc键返回菜单界面。

使用help获得GRUB当前可使用的命令。

    -->grub> help


3.2.5 GRUB 2的一些常用命令

    (1)help

    查看命令用法,如:

    -->help search


    (2)set

    设置变量值,如:

    -->set default=0

    -->set timeout=5

    -->set root=(hd0,3)

    需要调用变量XX的值时,使用${XX},如set root=(hd1,1),则${root}=(hd1,1)


    (3)default

    定义默认引导的操作系统。0表示第一个操作系统,1表示第二个操作系统。

    (4)timeout

    定义在某时间内用户没有按下键盘上的某个按键时,自动引导default指定的操作系统。

    (5)root

    指定用于启动系统的分区

    (6)insmod和rmmod

    加载或移除某模块:

    -->insmod jpeg

    -->insmod png

    -->insmod ntfs

    -->rmmod png

    (7)drivemap

    drivemap兼容grub的map,主要用于只能从第一块硬盘(hd0)引导启动的系统如Windows 2000/XP/2003,

比如要添加第二块硬盘第一个分区上的Windows XP系统。


    (8)ls

    列出当前的所有设备,如(hd0)、(hd0,1)、(hd0,5)、(hd1)、(hd1,1)、(hd1,2)等

    -->ls -l


    详细列出当前的所有设备。对于分区,会显示其label及uuid

    -->ls /

    列出当前设为root的分区下的文件

    -->ls (hd1,1)/

    列出当前设为root的分区下的文件


    (9)search

    -->search -f /ntldr

    列出根目录下包含ntldr文件的分区,返回分区号。

    -->search -l LINUX

    搜索label是LINUX的分区

    -->search --set -f /ntldr

    搜索根目录下哎包含ntldr文件的分区并设为root。注意:如果分区外含有ntldr文件,那么

set将失去作用。


    (10)loopback
    
    loopback命令可用于建立回放设备,如:

    -->loopback 1o0 (hd1,1)/abc.iso

    可以使用lo0设备来访问abc.iso里的内容,比如,可以从abc.iso文件的映像中启动:

    -->loopback lo0 (hd1,1)/abc.iso

    -->linux (lo0)/memdisk

    -->linux (lo0)/abc.img

    要删除某一回放设备,可以使用-d参数:

    -->loopback -d lo0


   (11)pager

    分页显示

    -->set pager=1

    显示满一页时暂停,按空格键继续。

    -->set pager=0

    取消分页显示


   (12)linux 

    使用linux命令取代grub的kernel命令

    
    (13)chainloader

    调用另一个启动器,如:

    -->chainloader (hd0,1)+1

    调用第一块硬盘第一个分区引导扇区内的启动器,可以是Windows或Linux启动器。


3.2.6 理解GRUB 2的配置文件

    -->cat /etc/grub2.cfg 
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub2-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
set pager=1

if [ -s $prefix/grubenv ]; then
  load_env
#加载变量,如果在grubenv中保存变量,则启动时加载
fi
if [ "${next_entry}" ] ; then
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="${saved_entry}"

#设置默认引导项,默认值为0
fi

if [ x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi

export menuentry_id_option

if [ "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

#可以使用save_env pre_saved_entry 把变量值存入grubenv,也可以使用save_envdefault把default
值存入grubenv,供load_env调用。

function savedefault {
  if [ -z "${boot_once}" ]; then
    saved_entry="${chosen}"
    save_env saved_entry
  fi
}

function load_video {
  if [ x$feature_all_video_module = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
#插入vbe模块,GRUB 2引入模块化机制,要使用它,需要在这里加入

    insmod vga

#载入合适的显示卡驱动
    insmod video_bochs
    insmod video_cirrus
  fi
}

terminal_output console
if [ x$feature_timeout_style = xy ] ; then
  set timeout_style=menu
  set timeout=5

# 设置GRUB菜单的启动延时为5秒
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
  set timeout=5
fi
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/10_linux ###
# 下面每个菜单项要包括menuentry双引号" "和花括号{}才完整,否则不显示菜单。
menuentry 'Red Hat Enterprise Linux Server, with Linux 3.10.0-123.el7.x86_64' --class red --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-123.el7.x86_64-advanced-59dc0a8e-d85d-4669-b846-2b4cfa872e0a' {
	load_video
	set gfxpayload=keep
	insmod gzio
	insmod part_msdos 
	insmod ext2
#插入文件系统支持的模块,除了用作启动的分区外,其它分区可在menuentry底下再添加
	set root='hd0,msdos1'
#指定系统root分区,也就是/分区
	if [ x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  761b479c-8c9a-4f72-843c-bd28ef16e185
	else
	  search --no-floppy --fs-uuid --set=root 761b479c-8c9a-4f72-843c-bd28ef16e185
#指定uuid=761b479c-8c9a-4f72-843c-bd28ef16e185的分区为root分区
	fi
	linux16 /vmlinuz-3.10.0-123.el7.x86_64 root=UUID=59dc0a8e-d85d-4669-b846-2b4cfa872e0a ro vconsole.keymap=us crashkernel=auto  vconsole.font=latarcyrheb-sun16 net.ifnames=0 biosdevname=0 rhgb quiet 
	initrd16 /initramfs-3.10.0-123.el7.x86_64.img
}
menuentry 'Red Hat Enterprise Linux Server, with Linux 0-rescue-e08a018ab0ba42cf9943bf604dd571d6' --class red --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-e08a018ab0ba42cf9943bf604dd571d6-advanced-59dc0a8e-d85d-4669-b846-2b4cfa872e0a' {
	load_video
	insmod gzio
	insmod part_msdos 
	insmod ext2
	set root='hd0,msdos1'
	if [ x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  761b479c-8c9a-4f72-843c-bd28ef16e185
	else
	  search --no-floppy --fs-uuid --set=root 761b479c-8c9a-4f72-843c-bd28ef16e185
	fi
	linux16 /vmlinuz-0-rescue-e08a018ab0ba42cf9943bf604dd571d6 root=UUID=59dc0a8e-d85d-4669-b846-2b4cfa872e0a ro vconsole.keymap=us crashkernel=auto  vconsole.font=latarcyrheb-sun16 net.ifnames=0 biosdevname=0 rhgb quiet 
	initrd16 /initramfs-0-rescue-e08a018ab0ba42cf9943bf604dd571d6.img
}

### END /etc/grub.d/10_linux ###

### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###

### BEGIN /etc/grub.d/20_ppc_terminfo ###
### END /etc/grub.d/20_ppc_terminfo ###

### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###

### BEGIN /etc/grub.d/41_custom ###
if [ -f  ${config_directory}/custom.cfg ]; then
  source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###


    
3.2.7 /etc/;grub.d 目录下的脚本文件

    -->ls /etc/grub.d/

00_header  20_linux_xen     30_os-prober  41_custom
10_linux   20_ppc_terminfo  40_custom     README

    在/etc/grub.d/目录下的脚本,当update-grub执行时被读取,并合并到/boot/grub2/grub.cfg文件中。

grub.cfg文件中菜单条目的放置,是由/etc/grub.d/目录下的脚本运行顺序决定的。文件名以数字开头的

脚本被先执行,并且数字小的先执行。

                                    /etc/grub.d 目录下的脚本文件
    ---------------------------------------------------------------------------------------------------
        文件名称                                   说明
    ---------------------------------------------------------------------------------------------------
     00_header         设置环境变量,比如系统文件位置、显示卡设置和之前保存的入口。这个文件也导入
                       了一些相关的东西。用户通常不需要改变这个文件
    ---------------------------------------------------------------------------------------------------
     05_debian_theme   这个文件的主要作用是设置GRUB 2的背景图片、文本颜色,选择高亮和主题
    ---------------------------------------------------------------------------------------------------
     10_linux          识别在root device(根设备)中操作系统正在使用的内核,并且为这些内核创建菜单入口。
                       这个文件包含了相应的"recovery mode (恢复模式)"选项
    ----------------------------------------------------------------------------------------------------
     20_memtest86+     寻找/boot/memtest86+.bin (内存测试启动项),并且把它作为一个选项加入到GRUB 2启动
                       菜单中
    ----------------------------------------------------------------------------------------------------
     40_custom         自定义启动项,按菜单标准格式在后面添加即可
    ----------------------------------------------------------------------------------------------------


3.2.8 应用实例

    1.重新生成GRUB 2的配置文件

    -->grub-mkconfig -o /boot/grub/grub.cfg
     
    2.将GRUB 2安装到硬盘引导扇区

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

    3.使用密码保护GRUB 2

    -->cp /boot/grub2/grub.cfg /boot/grub2/grub.cfg.orig

    -->cp /etc/grub.d/10_linux /etc/grub.d/20_linux.org

    -->grub2-mkpasswd-pbkdf2  | tee /root/.g

    -->awk -F 'is ' ' {print $2}' /root/.g >> /etc/grbu.d/00_header

    -->vim /etc/grub.d/00_header

    在文件尾部加入以下内容

cat << EOF
set superusers="tejasbarot" password tejasbarot alub@123
EOF


    这里的用户名是 tejasbarot,密码是 alub@123

    建立新的配置文件:

    -->grub2-mkconfig --output=/tmp/grub2.cfg

    -->mv /boot/grub2/grub.cfg /boot/grbu2/grub.cfg.move

    -->mv /tmp/grub2.cfg /boot/grub2/grub.cfg


    4.修改启动顺序的方法

    -->grub2-editenv list

saved_entry=Red Hat Enterprise Linux Linux, with Linux 3.10.0-123.el7.x86_64


    对于使用Windows +Linux的用户,可以使用如下方法修改启动顺序

    (1)首先找到Windows的menuentry:

    -->cat /boot/grub2/grbu.cfg | grep Windows

    结果:

    menuentry "Windows 7 (loader) (on /dev/sda1)" --class windows --class os {


    (2)设置Windows作为默认的启动项(这里只能使用上面命令输出双引号""或者单引号''中的内容)

    -->grub2-set-default "Windows 7 (loader) (on /dev/sda1)"

    (3)验证默认的启动项:

    -->grbu2-editenv list

    saved_entry=Windows  7 (loader) (on /dev/sda1)
博主

让学习成为习惯,坚持-共享-开源-自由! 成功者决不放弃,放弃者绝不成功!

相关推荐

嗨、骚年、快来消灭0回复。