grub 学习之路
现在,是grub2的天下了呀,虽然网上关于grub2的资料不少,但很多都是就一个方面讨论的,跟着这些教程配置虽然也能够成功,但总是迷迷糊糊,不知这grub2背后到底是怎么实现的。所以决定花时间深入了解一下。在学习grub2之前,我特地去看了以下grub2的前身:grub。
所以,就有了这篇文章。作为自己的笔记,也供大家参考,因为(目前)没办法弄到grub的实践环境(缺少编译环境),一大部分都是用grub2来试。所以只是凭着个人的理解,参考grub手册和网上各位大神的博客写出这篇博客。如果诸位前辈发现有错误的地方,希望自己能抛砖引玉,得到前辈们的指点。谢谢。
一般你装完系统,grub就已经自动安装好。这就很容易造成我们不了解grub,我们平时用的grub-install,在终端的grub shell界面的setup,都只是在第一个硬盘最前端512字节(或者你所安装的系统所在的分区最前端)安装grub的boot loader主程序,而不是我们理解的安装grub这个程序。(关于安装grub这个程序,我会在下面第一点就说明)所以,实质上grub就是一个程序,而grub-install等等是这个程序的功能。甚至可以说grub是一个系统。因为它不需要其他系统提供接口就可以直接运行在计算机上。事实上,你在开机时,就是先运行grub,然后通过grub加载内核(kernel)等相关文件,到启动整个系统。注意:我们平时说的grub就是说这个stage1安装的bootloader主程序。
这个流程图是大牛M. Tim Jones在Inside Linux boot process中绘制的。其中的stage1就是在"grub>"界面用setup或者在终端直接用grub-install安装的。
第一点:安装grub这个程序 =>官方说是安装Grub system(grub 系统)
如前所述,grub是默认安装在linux等系统上的。一般来说,你不需要下载安装这个程序。但为了了解grub运行机制,我们假设我们电脑上还没有安装它,我门下面来看以下它如何安装。首先,像安装其他软件一样,我们需要下载安装包。地址:ftp://alpha.gnu.org/gnu/grub/grub-0.97.tar.gz(好像不灵了,得自己去找,或者在下面我给出)
下载之后,先把它复制到/tmp目录下,然后解压:zcat grub-0.97.tar.gz | tar xvf -
解压之后,做下面的步骤就可以完成安装了:
#cd grub-0.97
#./configure
#make install
那么上面到底安装了些什么呢?如下:grub shell(就是grub>),Multiboot checker :mbchk(多重启动检查,检查内核格式用的),相关的grub image(在/usr/lib/grub/下),还有grub说明手册(通过info grub可以查看)。目前还没将grub做成bootloader,所以此时你重启是进不了系统的。当然,我们一般不会有这种情况,如前所说,我们在装系统时已经装好了grub了。还有,这里注意一下,如果你不是用grub-install安装,而是用grub shell,那么你需要将stage1和stage2复制到/boot/grub/下
第二点:安装grub(就是运行grub程序安装 grub bootloader)
第二点的预备知识: 一 块硬盘,有一个主引导记录(即MBR)。此后硬盘最多可以分成4个主分区,也可以把其中的一个主分区变成扩展分区,进而分成若干个 逻辑分区。其中每一个分区又有自己的引导扇区,虽然名字不叫MBR,但是作用是一样的,不同的是,MBR是由BIOS自 动装载到内存中并CPU跳转过去执行的,而普通分区上的引导扇区,需要MBR中的引导程序去装载并提交控制权。grub bootloader既可以装到MBR中,也可以装到任 意分区的引导扇区上。所以一台电脑上可以装多个grub。grub1(最近grub第二代已经推出,机制改变了)由三段程序组成:stage1、stage1.5、stage2。如果你装的是grub1,可以进入/boot/grub目录看一看。
安装grub时stage1和stage2是必装的,而stage1.5是可选的。
stage1:/boot/grub中的stage1文件大小为512b,它是引导扇区中引导程序(前446字节为引导程序)的备份文件,功能是用来装载 stage1.5或stage2的。
stage1.5:因为STAGE2较大,通常都是放在一个文件系统当中的,但是STAGE1并不能识别文件系统格式,所以才需要STAGE1.5来引导位于某个文件系统当中的STAGE2
stage2:grub能让用户以选项方式将OS加载、改变参数、修改选项,这些全都是stage2程序的功能。stage2可以去获取grub.conf以及menu.lst等文件的内容。
命名规则(Naming convention)。其实可以用两个例子来说明:第一个磁盘的第一个分区这样表示:(hd0,0),第二个分区则是(hd0,1);第二个磁盘第一个 分区:(hd1,0),第二个分区则是:(hd1,1)。以此类推。也就是说磁盘和分区都是从zero开始算起的。需要注意的是,linux查找磁盘是按 照查找到的先后顺叙来排序的,而不是按照在主板上的排线顺叙来分配序号的。
注意注意注意,这个步骤安装完grub bootloader后,还是只能从grub>命令行,用自己手写命令加载系统内核或将加载权转交给其他bootloader。我们平时进入系统时就能选择的那个系统的菜单是需要配置一个叫menu.lst的文件才行的。
第二点正式开始: 装完grub 这个程序后,你可以选择利用grub程序制作各种启动盘;在mbr或者分区上的引导扇区上安装bootloader。
1.先说制作启动软盘(Creating a GRUB boot floppy):
为了创建一个启动软盘,你需要在image目录下将stage1和stage2复制出来,并且将他们写在软盘的第一和第二个块上。
命令:# cd /usr/lib/grub/i386-pc
# dd if=stage1 of=/dev/fd0 bs=512 count=1//写在软盘的第一个块
1+0 records in
1+0 records out
# dd if=stage2 of=/dev/fd0 bs=512 seek=1//写在软盘的第二个块上
153+1 records in
153+1 records out
#
注意:设备(/dev/fd0)和镜像目录可能不一样,按照你自己的情况来做。
好了,一个启动软盘就做好了。可以用它来引导你的linux系统了(不能直接引导DOS/Windows哦)。选择从它开机就可以看到一个可爱的画面:
在这个界面你可以做什么?可以引导(加载)内核启动。可以给还没有bootloader的系统(linux)安装 grub bootloader。可以将引导权转交给其他bootloader。
2.接下来我们在引导扇区上安装grub(即stage1)。安装stage1也有两(多?)种方法。据官方手册介绍,用启动盘的grub shell(即grub> )安装会比较安全。而用在终端运行的grub shell 或者 grub-install安装的话可能会由于找错硬盘或分区(mapping错误:硬盘映射错误)而导致将stage1安装在错误的扇区。
2.1 启动盘安装grub bootloader(Installing GRUB natively) 注意:用这种方法安装会擦除安装在分区上的系统的bootloader。
这种方法安装你需要做一个启动盘(例如上面做的软盘),插入电脑,重启,并从启动盘启动,如上面插图一样,你会看到一个grub> 如下:
grub> root (hd0,0) =>这个是指定你的stage1文件在哪里,一般都在/boot/grub/下。为什么指定?你要安装stage1总得告诉"grub>"stage1在哪吧?
如果不确定的话,可以这样找: grub> find /boot/grub/stage1 =>会将含有stage1的磁盘分区罗列出来,一般只有一个。
grub> setup (hd0) =>将grub bootloader安装在第一个磁盘的Master Boot Record (MBR)上
嘿嘿,如果你想安装在你系统的引导扇区(boot section)上,你可以这样:
grub>setup (hd0,0) =>第一个磁盘第一个分区的引导扇区。
setup完之后,下次重启你就可以不需要启动盘都可以出现grub>图标。也就是说,grub bootloader 已经装好了。下面,就可以利用这个画面booting(加载)内核,进入系统了。
2.2 上面用的是启动盘引导安装,这里说一下用grub-install安装。(这种方法是我们平时用得最多的,但它不一定每次成功,因为可能出现mapping 错误,一般它都会提示你检查device.map这个文件),开始吧
# grub-install /dev/hda
运行这一步发生什么呢?会默认将/usr/lib/grub/下的相关配置文件image等复制到/boot/grub/目录下,然后在第一个磁盘的mbr上安装grub bootloader。这也是为什么我说如果不用grub-install安装的话,要先将/usr/lib/grub/下的stage1等东西复制到/boot/grub/目录下。
那如果你不想将/usr/lib/grub/下的配置文件装到/boot/grub/下呢?比如我想做一个启动软(或U)盘,就需要将/usr/lib/grub/下的东西复制到软(或U)盘的grub目录下。可以这样:
# mke2fs /dev/fd0 =>将软盘格式化
# mount -t ext2 /dev/fd0 /mnt =>挂载
# grub-install --root-directory=/mnt fd0 =>--root-directory=/mnt 看,这个参数代表将/usr/lib/grub/下的文件复制到/mnt下
# umount /mnt =>这个我也不知什么意思.嘿嘿
好了,这就是利用grub-install安装grub bootloader了。到这里,肯定会发现还有一个在终端输入grub,然后出现一个grub> ;我的系统是这样的:
可以发现并没有出现grub>图标。因为我系统的grub是目前最新版的。已经将终端调用grub shell(即grub>)功能删除了。为什么删除?前面就已经提到,终端的grub shell是不安全的。它不能保证每次都能成功。官方手册里说:Note that the grub shell is an emulator。就是说grub shell只是一个模拟器。其实grub-install就是一个脚本,它通过调用grub shell来完成工作的。官方这样说:Note that grub-installis actually just a shell script and the real task is done by the grub shellgrub(see Invoking the grub shell). Therefore, you may run grub directly to install GRUB, without using grub-install. Don't do that, however, unless you are very familiar with the internals of GRUB. Installing a boot loader on a running OS may be extremely dangerous.(不想翻译了-=-)
第三点:通过grub bootloader 的grub> 加载内核等相关文件来启动 (Booting)
做完上面地步骤,你开机时,就会出现一个带有grub>的画面。也就是说,现在你可以加载启动系统了。
1.grub>kernel /boot/vmlinuz(按Tab自动补齐) root=/内核所在位置/
2.grub>initrd /boot/initrd(按Tab自动补齐)
3.grub>boot
一般是上面几个步骤,这里大致描述。更详细的话百度就有。一大堆前辈的经验。实质上很多人开机遇到grub>以为是错误,其实gurb bootloader本来就这样。
其实grub是用一致的方法引导多重引导兼任内核(Multiboot-compliant kernel)。什么是多重引导兼任内核?我去搜了一下它的含义,没有搜到。只能说一下我的理解了,多重引导兼任内核就是可以由grub直接引导的系统,像linux。而window这些不能由grub直接加载内核的,明显不是多重引导兼任内核,需要用(chainload) (如果有大神发现我理解错误,希望纠正一下,在此感激不尽)。
第四点:创建一个配置文件(Configuration)
或许你已经发现,上面的步骤下来到现在,你每次进入系统都要通过几行命令。没有谁喜欢这种方式吧?于是,grub有一个无比牛逼的方案,就是在/boot/grub/下配置一个叫menu.lst(不同系统文件名不一样)的文件,开机时就先加载这个文件,通过这个文件的配置来引导你的系统。我们平时接触的就是这个文件比较多。通过这个文件你可以配置你喜欢的东西。下面我们来简单看一下。
menu.lst文件:
default=0 <==预设开机选项,使用第 1 个开机选单 (title)
timeout=5 <==若 5 秒内未动键盘,使用预设选单开机
splashimage=(hd0,0)/grub/splash.xpm.gz <==背景图示所在的档案
hiddenmenu <==读秒期间是否显示出完整的选单画面(预设隐藏)
title CentOS (2.6.18-92.el5) <==第一个选单的内容
root (hd0,0)
kernel /vmlinuz-2.6.18-92.el5 ro root=LABEL=/1 rhgb quiet
initrd /initrd-2.6.18-92.el5.img
关键是对最后三句的理解:
root:代表的是内核文件放在哪个分区。如上则是放在第一个硬盘第一个分区(如果装系统是独立分配一个/boot,那么这里说的第一个分区就是/boot)。
这里要将/boot与根目录/区分。
kernel:kernel后面接的是内核的文件名,文件名后是参数、由于启动过程需要加载根目录(因为很多本来是内核里的配置被分化出来变成模块放在根目录里,
这样相当于简化内核体积)。因此root=LABEL=/1是指根目录所在分区。根分区放着各种系统模块,内核需要驱动他们才能完成启动系统rhgb为彩色
显示,quiet是安静模式。
initrd:由于模块被放在根目录的/lib/modules中,而usb,SATA等磁盘驱动程序通常以模块方式存在。问题是想要挂载根目录必须要取得磁盘驱动程序才能识别磁盘,
但磁盘驱动却被放
在要挂载的根目录里。这样明显进退两难。于是,要通过InitialRAM Disk(虚拟文件系统)来处理:它的文件名通常是/boot/initrd,它也能够通过bootloader
加载到内存中。然后这个文件(即/initrd-2.6.18-92.el5.img)会被解压并且在内存中仿真(虚拟)成一个根目录,这个虚拟根目录会能够提供一个加载启动过程中
所需要的各种驱动(一般是USB,SATA等驱动)的一个可执行程序。 结尾:好了,关于grub我就说这么多。但是,grub的强大之处我还没有真正全部摸索透。我学习它是因为我要学习grub2. 参考:官反手册:http://www.gnu.org/software/grub/manual/legacy/grub.html#root 转载的博客:http://tianwanjun8680.blog.163.com/blog/static/49692234201291084641655/
stage1的运行详细过程:GRUB启动分析之stage1-Bean_lee-ChinaUnix博客
grub 学习之路的更多相关文章
- jQuery学习之路(1)-选择器
▓▓▓▓▓▓ 大致介绍 终于开始了我的jQuery学习之路!感觉不能再拖了,要边学习原生JavaScript边学习jQuery jQuery是什么? jQuery是一个快速.简洁的JavaScript ...
- Android开发学习之路-RecyclerView滑动删除和拖动排序
Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...
- RPC远程过程调用学习之路(一):用最原始代码还原PRC框架
RPC: Remote Procedure Call 远程过程调用,即业务的具体实现不是在自己系统中,需要从其他系统中进行调用实现,所以在系统间进行数据交互时经常使用. rpc的实现方式有很多,可以通 ...
- webService学习之路(三):springMVC集成CXF后调用已知的wsdl接口
webService学习之路一:讲解了通过传统方式怎么发布及调用webservice webService学习之路二:讲解了SpringMVC和CXF的集成及快速发布webservice 本篇文章将讲 ...
- [精品书单] C#/.NET 学习之路——从入门到放弃
C#/.NET 学习之路--从入门到放弃 此系列只包含 C#/CLR 学习,不包含应用框架(ASP.NET , WPF , WCF 等)及架构设计学习书籍和资料. C# 入门 <C# 本质论&g ...
- Redis——学习之路四(初识主从配置)
首先我们配置一台master服务器,两台slave服务器.master服务器配置就是默认配置 端口为6379,添加就一个密码CeshiPassword,然后启动master服务器. 两台slave服务 ...
- Redis——学习之路三(初识redis config配置)
我们先看看config 默认情况下系统是怎么配置的.在命令行中输入 config get *(如图) 默认情况下有61配置信息,每一个命令占两行,第一行为配置名称信息,第二行为配置的具体信息. ...
- Redis——学习之路二(初识redis服务器命令)
上一章我们已经知道了如果启动redis服务器,现在我们来学习一下,以及如何用客户端连接服务器.接下来我们来学习一下查看操作服务器的命令. 服务器命令: 1.info——当前redis服务器信息 s ...
- 踏上Salesforce的学习之路(一)
相信通过前面的学习,大家已经拥有了一个属于自己的Salesforce开发者账号,下面,我们将用这个账号正式踏上Salesforce的学习之路. 首先,点击网址:https://developer.sa ...
随机推荐
- 关于JavaScript的模块化
为什么需要模块化 最近在学习网易微专业的<前端系统架构>课程,里面讲到了关于JavaScript的模块化问题.具体指的是当随着Web系统不断强大起来,需要在客户端进行的操作就多了起来(比如 ...
- 关于html5调用手机相机(原创)
很久没写随笔了 从ios6开始,webview支持html <input type="file">标签,用来调取手机的相册和相机,但是没有权限提示,不知道是不是我写的有 ...
- 深度学习的2016: NIPS 2016速览
With best wishes for a happy New Year! NIPS(Nerual Information Processing Systems)是人工智能.机器学习领域的顶级学术会 ...
- struts2自定义日期类型转换器
在java web表单中提交的数据难免会有日期类型,struts2支持的日期类型是yyyy-MM-dd,如果是其他格式,就需要自己进行转换.比如yy-MM-dd 要完成自己定义的转换需要完成. 主要的 ...
- 什么是RESTful?
RESTful一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制. REST ...
- android通过代码获取华为手机的EMUI系统版本号
因为app中用到华为推送,但是华为推送在不同版本上是存在不同问题的,需要单独来处理. 那么最基本的问题是要获取EMUI系统的版本号. 上网翻了很多博客帖子,基本上是在获取root权限下去读取/syst ...
- zlog学习随笔
zlog1使用手册 Contents Chapter 1 zlog是什么? 1.1 兼容性说明 1.2 zlog 1.2 发布说明 Chapter 2 zlog不是什么? Chapter 3 ...
- 《HelloGitHub》第 13 期
公告 本期推荐的项目到达了 30 个,里面少不了对本项目支持的小伙伴们,再次感谢大家. 本次排版尝试:根据分类项目名排序,为了让大家方便查阅.如果有任何建议和意见欢迎留言讨论 临近 5.1 假期,所以 ...
- 使用SSH框架查出的实体集合用AJAX形式刷新到页面JOSONArray报异常
所报异常:net.sf.json.JSONException: java.lang.reflect.InvocationTargetException 问题根源:数据库中查出的日期是java.sql. ...
- HTTP长连接、短连接使用及测试
概念 HTTP短连接(非持久连接)是指,客户端和服务端进行一次HTTP请求/响应之后,就关闭连接.所以,下一次的HTTP请求/响应操作就需要重新建立连接. HTTP长连接(持久连接)是指,客户端和服务 ...