启动流程概括:

POST (加电自检,检测硬件设备可用性)-->cpu被传递给第一条指令告诉rom空间的信息--->cpu加载rom中的指令(实现自检)---->Boot Sequence(BIOS查找启动引导顺序,选择应该从硬盘,USB,网络,光驱中的哪个设备启动系统) --> Boot Loader (找到系统所在分区,通过grub1,1.5,2阶段找到内核) --> Kernel(当无法识别根分区驱动时会用到ramdisk,通过ramfs创造一个虚拟跟文件系统,里边提供了根文件系统所在磁盘的驱动,达到能识别根所在磁盘) --> rootfs (加载根文件系统)--> switchroot(切换到根分区) --> /sbin/init(启动init程序,只有启动了init程序才能控制所有其他程序) -->(/etc/inittab, /etc/init/*.conf) --> 设定默认运行级别(根据/etc/inittab文件) --> 系统初始化脚本rc.sysinit--> 关闭或启动对应级别下的服务 --> 启动终端

MBR是硬盘上的一个扇区,包含三部分内容(引导程序、分区表及分隔标识,MBR总计512字节;其中引导程序最多占446个字节);为什么需要这个MBR,主要是因为BIOS太小,功能有限。当系统加电,bios自检后,就会将MBR Load进内存。也就意味着引导程序被激活,分区表信息已经加载到内存,同时也意味着对系统的控制权从bios过渡到GRUB.

GRUB是GRand Unified Bootloader的缩写,它是一个多重操作系统启动管理器。用来引导不同系统。GRUB是一个系统引导程序,分为两个阶段,第一阶段它保存在MBR中,用汇编语言编写,也就是MBR中的引导程序部分。①基本的硬件设备初始化(屏蔽所有的中断、关闭处理器内部指令/数据cache 等)。②为加载 Bootloader 的Stage2 准备空间。③如果是从某个固态存储媒质中,则拷贝 Bootloader 的stage2 到RAM 空间中。④设置好堆栈。⑤跳转到 stage2 的C 程序入口点。GRUB引导程序的第二阶段,通常用C语音编写,这个阶段的任务有: ①初始化本阶段要使用到的硬件设备。②检测系统内存映射。③将kernel 映像和根文件系统映像从flash 上读到RAM 空间中。④为内核设置启动参数⑤调用内核。它通常保存在/boot/grub/中。 当我们启动系统进入GRUB界面时,会看到有选择信息,如果我们自己编译了系统内核的话,你可以选择从某个内核启动。同时要注意的是GRUB的配置文件和内核在/boot分区。从前面分析我们可以看出,/BOOT和MBR不存在包含关系。GRUB第一阶段需要去MBR中去读引导程序,GRUB第二阶段需要到/boot分区读系统内核和配置文件。

第1.5阶段装在bootloader1阶段之后的空间上

rom其实是内存条上的一段空间,内存是ram

上神图:

接下来,我们分析一下bootloader里的grub

GRUB(Boot Loader):

grub: GRand Unified Bootloader

grub 0.x: grub legacy

grub 1.x: grub2

grub legacy:

stage1: mbr

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

stage2:磁盘分区(/boot/grub/)

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

grub作用:

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

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

1.Grub的命令行接口:

刚开机时敲e键,进入grub,敲c键进入命令行接口:

Root指令用于设置grub所在根设备

如何识别设备:

        (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

如果boot单独分区则直接指向root hd(0,0)

如果boot没有单独分区需要加上boot路径,即root hd(0,0)/boot/

如果已经指明了root(hd0,0),直接find / 就可以

接着:设定内核所在位置,根文件系统所在位置

指定initramfs所在位置:当内核无法识别根所在磁盘的驱动时,initramfs里边装载的硬盘驱动可以帮助内核去识别

2.grub菜单和grub.conf其实是一一对应的

grub菜单:

/boot/grub/grub.conf文件

配置项:

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

**以上用于加密grub或者加密内核启动的加密的password 可以用grub-md5-crypt命令生成

3.进入单用户模式方法:

(1) 编辑grub菜单(选定要编辑的title,而后使用e命令);

(2) 在选定的kernel后附加
      1, s, S或single都可以;
(3) 在kernel所在行,键入“b”命令;
4.安装grub----两种方法:(当grub损坏时)
 (1) grub-install
      grub-install --root-directory=ROOT /dev/DISK

具体流程:

插一块新硬盘,创建boot分区,格式化为ext2,3,4  创建根分区,格式化为ext2,3,4 

创建swap,makeswap

①将需要装grub的磁盘上的原先的boot分区挂载到/mnt/boot目录下

②执行grub-install命令:

后续:复制内核,ramfs文件到/mnt/boot下,写一个/mnt/boot/grub/grub.conf配置文件

default=0

timeout=5

title Centos (Express)

    root (hd0,0)

   kernel /vmlinuz ro root=/dev/sda3 selinux=0 init=/bin/bash (默认运行/sbin/init,因为实验,复制init太过负载,让系统开机运行bash)

   initrd /initramfs.img

挂载/dev/sda3到/mnt/sysroot 在/mnt/sysroot创建etc sbin bin lib lib64 proc dev sys tmp var usr home root mnt media目录

复制/bin/bash到/mnt/sysroot/bin下

ldd /bin/bash将库文件复制到/mnt/sysroot/lib64下

chroot /mnt/sysroot 执行bash测试bash是否正常

硬盘取下来放到新机器上当主硬盘试试

 

grub修复

dd if = /dev/sda of = /root/mbr.bak count=1 bs=512

dd if = /dev/zero of=/dev/sda bs=200(小于446) count=1

方法(1):grub-install --root-directory=/ /dev/sda

方法(2): grub命令进入grub提示符--->root (hd0,0)--->setup (hd0)即可(这个修复方法是通过到/boot/grub下取得各种stage1和stage1.5信息同步到bootloader实现的)

grub命令行提示符下---再没重启情况下在shell中直接输入grub命令(前提是boot/grub目录下有stage1和stage1.5文件)

      grub> root (hd#,#)

      grub> setup (hd#)

紧急救援模式下修复grub,这个需要光盘启动:选择Rescue installed system或者启动时敲ESC键,在boot提示符下敲linux rescue都行,有点像winPE

切换到chroot /mnt/sysp_w_picpath-----这个目录是当前系统挂载点,在以下命令行中使用grubinstall --root-directory=/ /dev/sda修复