这几天对于操作系统是如何引导启动的特征的感兴趣,已经到了不能自拔的状态了,所以索性好好了解一下;

前面已经说过了,MBR对于系统启动的重要性,这是不多啰嗦;  现在介绍一个 grub ,启动管理器,它可以用于引导不同的系统;

grub 是一个怎么样的引导原理?

通过我的实验,我得到的结论就是: 整个grub启动管理器其实也算是有点大的,引导扇区里是放不开的;  所以,grub会往引导扇区(可以是MBR, 也可以是每一个分区里面的引导扇区)里面写入部分内容,对于剩余的部分,它会写入到我们的硬盘分区里面的;在启动时,首先运行引导扇区里的程序, 然后在运行硬盘分区里的程序,最后引导操作系统;

对于引导扇区里的程序是如何找到硬盘分区里的程序与配置的,这个就是细节方面的问题了,我们可以忽略;不过我也是一个好学习的人,我也查了查相关的资料,有的解释如下:

来自:作者:js li
链接:https://www.zhihu.com/question/27652991/answer/37500373
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

grub的话,肯定是要在mbr里写东西的,但446字节的机器码也干不了太多东西,只是负责把后续的内容加载到内存在执行而已。这个写到mbr的是stage1,它加载的是写在mbr之后62个扇区中的stage1.5(因为过去磁盘是按磁道还划分分区的,一个碰道63个扇区,因为mbr占据了第一个磁道的第一个扇区,所以第一个分区只能从第二个磁道开始,这样在mbr和第一个分区之间就留下了62个扇区的空间,62*512byte=31KB)。

mbr之前说了容量太小没法放下识别文件系统的代码,只能以计算扇区绝对偏移的方法加载stage1.5,但31KB的stage1.5就足够了(但基本也只够一种类型的文件系统,所以stage1.5是有好几个,分别对应ext4,xfs等等,在grub安装时根据需要写入,随便一提,正是因为GPT分区表占用了后62个扇区的相当一部分位置,导致空间不够写下stage1.5,所以需要额外分出一个非常小的分区来存放)。 (我的备注:我在写grub时,没有设置是ext4,还是xfs, 应该是它自动识别的吧)

stage1.5可以识别文件系统,然后根据安装时硬写到里面的系统路径(hexdump可以看到)找到stage2,然后这个stage2才是真正负责干活的,它会读取grub.cfg并生成启动菜单,然后根据你的选择加载内核并把执行权限转过去,完成启动。

实验部分:

先跟着实验走一遍,然后就会更容易明白grub是如何引导的,来,先折腾起来:

我使用的grub版本分别为 grub-0.97 和 grub-2.02;

grub-0.97 的使用:

第一步:我们下载 grub-0.97这个工具,并安装到 linux系统上

(注意:这里说的安装是指的 把这个 grub-0.97 工具安装到 linux 上,而不是把 grub-0.97的启动管理器安装到 硬盘分区上;我们需要使用grub-0.97 这个工具来安装 grub-0.97 启动管理器)

方法1:在 linux 上 使用 apt-get install grub 下载下来的为就是 grub-0.97版本的,所以直接 apt-get install grub 就下载下来了;

方法2:当然也可以下载源码,自己编译(下载地址:ftp://alpha.gnu.org/gnu/grub/):别忘了给 root 权限:

// 假设应该下载完毕,,位置目录 grub 下:

tar xzvf grub-0.97.tar,gz
./configure --prefix=/usr // prefix 指定了安装的位置,当然也可以放在其它地方,不过需要添加一下环境变量,
// 如果不过添加环境变量,就到安装的目录下去运行也可以;
make
make install

第二步:安装grub 引导管理器到硬盘分区:

方法1:是通过命令一步步的安装,输入 grub 会出来 grub的交互窗口如下图,这时可以输入命令进行安装; 至于命令吧,我没有研究啊,用第二个方法方便;

方法2: 用自带的 grub-install 脚本安装: 这个脚本其实也是调用 grub 的命令进行安装的:

首先 使用help 来看看grub的用法,输入 grub-install –help:

所以,我们知道了 grub-install 的用法啦.我们仅仅使用下面的命令格式就可以了,其它的就不用管了:

sudo grub-install --root-directory=DIR install_device 

// DIR指的是grub的安装到硬盘的那一部分的目录位置;其实这个不重要,写到哪里都可以,反正 grub 的第一部分都可以找到的;只要你记住就可以了,因为可以在里面加入配置文件的;
                                                                  // 不过有一点要求:那就是把交叉硬盘,即不能把grub的第一部分与第二部分写在不同的硬盘上,我试过,会报错的;
// install_device 表示了安装到引导扇区的那一部分的到底的安装到哪一个引导扇区;
          // 例如:一块硬盘为sda, 如果 install_device 为 /dev/sda,则表示安装到了这个硬盘的MBR上;
// 如果 install_device 为 /dev/sda1,则表示安装到了这个硬盘的第一个主分区的引导扇区上;
// 当然如果安装到第MBR上, grub启动管理器可以正常运行,如果安装到分区的引导扇区上,则需要使用到 chainloader(下面会说到)

安装完成以后,我们在 sdb1的分区下面应有了一个 /boot/grub/ 目录了;里面有相关的内容;

举个两个例子:

我给虚拟机加了一块硬盘sdb,并且已经分区、格式化完成了,如下:

例子1:把 grub的 引导程序的第一部分写到硬盘的MBR上, 至于grub的剩余部分安装到哪,都行,我就安装到第一个分区里吧,过程如下:(我要先创建一个空目录 sdb1,然后把硬盘的第一个分区挂载到上面)

这时,开机把启动项选择从硬盘 sdb启动, 就会出现  grub> 窗口了,如下:(由于sdb硬盘上 grub,并没有配置信息: menu.lst,所以它自己找不到sda硬盘上的系统上,所以需要进行手动引导,见下面)

例子2:把 grub的 引导程序的第一部分写到硬盘第一分区的引导扇区上, 至于grub的剩余部分同样的安装到哪,都行,我就安装到第一个分区里吧,过程如下:(我要先创建一个空目录 sdb1,然后把硬盘的第一个分区挂载到上面)

方法与上面相同:只需要把sdb 改为 sdb1就可以了;

补充:(这一小段来自:http://blog.csdn.net/zzqhost/article/details/5935317

grub-install 是一个脚本,它完成以下任务:                     
    * 调用 grub-mkdevicemap 创建设备映像文件 /boot/grub/device.map
    * 复制 *.mod *.lst *.img 文件到 /boot/grub/
    * 调用 grub-probe 自动侦测文件系统类型
    * 调用 grub-mkimage 生成grub2内核文件 /boot/grub/core.img
    * 调用 grub-setup 安装引导记录到mbr或分区-

第三步:grub> 命令窗口下如何手动启动 linux 系统:

由于sdb硬盘上 grub,并没有配置信息: menu.lst,所以它自己找不到sda硬盘上的系统上,所以进行手动引导:

说明: 1.在 grub-0.97中,会把硬盘识别为 hd0,hd1,hd2, ……; 分区也是从0标志开始的,如第一分区(hd0,0), 第二分区(hd0,1),……;

2. grub 会把启动盘作为 hd0盘,其它盘为hd1, hd2等;

3. 记得用 tab 补全;

命令如下:

解释: 1. 第一行 root (hd1,0),  表示设置一个 linux 系统的 /boot 目录的分区,在这个 /boot 目录下有 内核文件与启动的镜像文件;又由于 这个分区是 grub 看到的,所以用grub的格式表示,那为什么为(dh1,0)呢??因为现在的启动盘为 sdb,而linux的系统在sda的第一个分区上,所以为(dh1,0);  如果省略这个 root (hd1,0) 也可以,后面找内核与镜像文件时再指明也行,只是会麻烦一些;

2.  第二行的命令是加核 linux 的内核文件,  对于后面的 root=/dev/sda1是什么?? 它指明了 linux 系统的  /  目录所在的分区,因为需要把很多东西mount到  / 目录下的目录名字下; 这个分区的路径是 linux 系统看到的,所以为 /dev/sda1;

3. 加载映像文件;(什么是initrd.img,百度或google)

4. 启动;

第四步: 配置 grub-0.97的配置文件,让它自动引导:

在 grub-0.97的 配置文件名字为:menu.lst 文件;至于配置文件的内容的书写方式,不多说,网上有很多,再说 现在都用grub2了,它的配置文件变了,所以研究也没有用了;我怎么做的呢?我先用 linux 上的grub-0.97 来自动自成一下 配置文件(命令:udpdate-grub),然后把它复制到 sdb1下的 /boot/grub/ 目录下(这个是我们上面生成的), 然后修改一下:  添加了一行命令: root  (hd1,0)  :

修改前:

修改后:

此时,我们重新从 硬盘 sdb里启动电脑,就可以启动了:

完成;

grub-2.02 的使用:

整个过程与grub-0.97 是相同的,说说不一样的地方 :

1. grub-2.02 可以在这里下载:ftp://ftp.gnu.org/gnu/grub/ftp://alpha.gnu.org/gnu/grub/

或者: ap-get install grub2-common;

2. grub-2.02支持更多的命令;

3. grub-2.02的 grub-install 的参数不一样了,同样可以通过 grub-install –help查看,部分如下:

在使用时,这么用:

sudo grub-install --boot-directory=DIR install_device 

// 例如: sudo grub-install --boot-directory=/sdb1/ /dev/sdb
// 它指的是 boot的目录 , 而不是root的目录了;

4.  在 grub-2.02中,会把硬盘识别为 hd0,hd1,hd2, ……; 而分区也是从msdos1标志开始的,如第一分区(hd0,msdos1), 第二分区(hd0,msdos2),……;

5. 在grub-2.02中的配置文件变成了 grub.cfg;

6. 当我把 grub-2.02安装到 sdb的MBR时, 把 linux系统下的 grub.cfg 文件复制到 sdb1分区上的 /grub/ 目录下时, 修改如下:

把 grub.cfg 里面的 hd0 全部替换为 hd1;  最后,在sdb硬盘启动时, sda上的 linux 系统启动成功;

7. 我发现使用在grub-2.02里,使用grub-install 写入到分区的引导记录时,会出问题,而使用grub-0.97则不会再现问题;

8.grub-2.02的命令有所不同:

set root=(hd1,msdos1)
linux /boot/ vm**** boot=/dev/sda1
initrd /boot/initrd.img***
boot

当把grub 没有安装到硬盘的 MBR里面,而是安装到了 第一分区,或第二分区时,怎么办?

使用 chainloader 命令( 它属于 grub的命令),它可以调用另一个启动器,如:在grub中,输入命令例如:

root (hd0, 0)             // 为安装grub 的分区,这是为第一分区;

chainloader +1          // 将指定的文件作为一个链式装载程序载入。为了获取在一个指定分区第一 扇区内的文件,使用+1作为文件名。

boot

这时,就会从硬盘的第一分区进行启动了;

完;

另外:可以看看相关的:GRUB(简体中文)

GRUB——系统的引导程序简单介绍的更多相关文章

  1. Asp.net博客系统收集和简单介绍

    国内Asp.net博客系统收集和简单介绍       [转载文章,仅供个人参考,引自http://www.soyaoo.com/Blog/post/92.html] 1.ZJ-Blog程序简介:基于A ...

  2. Linux系统Vi/Vim编辑器的简单介绍、安装/卸载、常用命令

    Linux系统Vi/Vim编辑器的简单介绍.安装/卸载.常用命令 1.介绍 vi(Visual Interface)编辑器是Linux和Unix上最基本的文本编辑器,工作在字符模式下.由于不需要图形界 ...

  3. Python--day67--Jsonresponse响应介绍和路由系统的分组命名匹配方式(简单介绍)

    1,Jsonresponse响应介绍: ,2,路由系统的分组命名匹配方式:(简单介绍)

  4. Linux 内核开发—内核简单介绍

    内核简单介绍 Linux 构成 Linux 为什么被划分为系统空间和内核空间 隔离核心程序和应用程序,实现对核心程序和数据的保护. 什么内核空间,用户空间 内核空间和用户空间是程序执行的两种不同的状态 ...

  5. Linux的简单介绍和常用命令的介绍

    Linux的简单介绍和常用命令的介绍 本说明以Ubuntu系统为例 Ubuntu系统的安装自行百度,或者参考http://www.cnblogs.com/CoderJYF/p/6091068.html ...

  6. iOS-iOS开发简单介绍

    概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的IOS程序.但是这里我想强调一下,前面的 ...

  7. Unix及类Unix系统文本编辑器的介绍

    概述 Vim是一个类似于Vi的著名的功能强大.高度可定制的文本编辑器,在Vi的基础上改进和增加了很多特性.VIM是纯粹的自由软件. Vim普遍被推崇为类Vi编辑器中最好的一个,事实上真正的劲敌来自Em ...

  8. iOS开发多线程篇—多线程简单介绍

    iOS开发多线程篇—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcod ...

  9. Android开发自学笔记(Android Studio)—4.界面编程与View组件简单介绍

    一.引言 Android应用开发最重要的一份内容就是界面的开发,无论你程序包含的内容多么优秀,如若没有一个良好的用户交互界面,最终也只是会被用户所遗弃.Android SDK提供了大量功能丰富的UI组 ...

随机推荐

  1. tengine 增加ngx_http_cache_purge_module 模块

    wget http://labs.frickle.com/files/ngx_cache_purge-2.1.tar.gz tar zxvf ngx_cache_purge-2.1.tar.gz -- ...

  2. 关于 Nginx upstream keepalive 的说明

    模块是 HttpUpstreamModule,配置的一个例子: [shell]upstream http_backend {    server 127.0.0.1:8080; keepalive 1 ...

  3. 【Linux】了解服务器的情况

    Java程序大多数都部署在Unix环境,而环境的稳定性对于部署的应用至关重要,所以Java开发人员需知道了解Unix环境的命令. 系统版本 查看系统版本 [root@localhost third_p ...

  4. 基于tcpdump的Android智能移动终端数据包捕获完整解决方案

    如何在Android智能手机上捕获数据包? 本文由CSDN-蚍蜉撼青松[主页:http://blog.csdn.net/howeverpf]原创,转载请注明出处! 当前Android系统越来越流行,无 ...

  5. Spark 保存文件 自定义分隔符

    Spark 保存文件 调整分隔符 废话 找了半天没找到,在某个地方看到了类似的(文中说的是读取的时候指定),试了一下保存,发现也好用,详细如下. 用法 df.write.option("de ...

  6. js 去掉html标签

    方法一: /// <summary> /// 去除HTML标记 /// </summary> /// <param name="NoHTML"> ...

  7. 【FindReport】图表快速部署开发

    在线帮助文档:http://help.finereport.com/ 开发部署环境:Java Tomcat 数据可视化工具 大屏动态显示

  8. MBCS与Unicode的转换

    一.绪 其实刚开始编程的时候我不太喜欢用Unicode编码,所以比较喜欢 VC6.0,即使使用VS2010,也会设置为未设置模式. 后来,没办法的接触了些Unicode的编程的东西,必须得研究字符集的 ...

  9. Android 程序drawable资源保存到data目录

    今天做了个小功能,就是把我们程序Drawable里面的图片保存到data目录下面,然后另外一个程序需要读取data目录里面保存的图片.涉及了data目录读写.这功能看上去挺简单,不过实际做的时候还是遇 ...

  10. WCF终结点——终结点地址(EndpointAddress)

    终结点的地址的Uri属性作为终结点地址的唯一标示. 包括客户端终结点和服务端终结点. 一.服务端终结点: 服务端的终结点通过宿主的添加方法暴露出来,从而成为可以调用的资源. 下面是将服务绑定到宿主的代 ...