2012年12月9日星期日

有关多系统应用的引导构建与修复(涉及GRUB,NTLDR,BOOTMGR以及SBM)

本文的目的是以我的电脑为案例,简要的说明一下系统启动过程,并介绍几个启动工具。
本文的预期阅读对象是:多系统用户(涉及多重引导)、老旧电脑用户(BIOS不支持优盘或者光驱启动)


开机原理:
1、开机电脑从BIOS开始,进行硬件扫描,如果没有问题,将默认使用BIOS中定义的第一引导设备(一般为第一块硬盘)引导系统。
2、对于每一个引导媒介,其引导信息位于其存储空间的第一个Block,即前512字节。
3、在安装操作系统时,为了兼容可能发生的多系统并存,操作系统通常会将引导信息同时写在引导设备的前512字节和系统分区的前512字节。
4、因此MBR通常指向最后一个安装的操作系统所在的分区,并引导电脑加载该分区的Bootloader。
5、Bootloader可以引导电脑加载操作系统核心并启动操作系统,或者将引导任务转交给其他的Bootloader。
*6、另外MBR的最后64字节与引导无关,是磁盘的分区表。

我的电脑本来是三个系统,Windows XP, Windows 7以及Ubuntu。
最先安装的WinXP到/dev/sda1,然后MBR就指向/dev/sda1,而/dev/sda1的前512字节内容则指导电脑加载NTLDR也就是Windows XP的Bootloader。
然后安装的Win7到/dev/sda2MBR仍然指向/dev/sda1,而/dev/sda1的前512字节的功能变成了指导电脑加载BOOTMGR也就是Windows 7的Bootloader。
最后安装的Ubuntu到/dev/sda5MBR指向/dev/sda5,而/dev/sda5的前512字节的内容指导电脑加载GRUB 2也就是Ubuntu的Bootloader。

另外/dev/sda3被作为数据盘用来交换数据,没有安装任何操作系统。
另外/dev/sda4是扩展分区,内建两个逻辑分区/dev/sda5和/dev/sda6,作为Linux系统的根分区和swap分区。

三个系统和平的共存着,直到今天。
今天我突然意识到,我的WinXP,当初作为万一有Win7不兼容的程序的后备系统,在最近一年之中根本没有用到。
而在可预期的未来也不会再用Windows XP这样老的操作系统了,因此我准备把Windows XP完全卸载掉,腾出一个分区用。


然而我意识到,/dev/sda1作为硬盘的第一个分区,格式化第一个分区可能导致MBR改变从而开机无法进入GRUB,进而无法进入任何一个系统。
即使格式化第一个分区没有影响到MBR中的引导信息,除了Windows XP之外,Windows 7的引导文件也在/dev/sda1上(先安装WinXP再安装Win7一般就会这样),所以假设GRUB可以正常启动,可以正常引导Linux系统,却无法进入Win7,因为承载BOOTMGR的分区被我格式化了。

因此我必须保证以下几点:
1、将Win 7的核心引导文件BOOTMGR以及BOOT目录迁移到/dev/sda2
2、保证GRUB在/dev/sda1格式化后可以正常加载
3、修改系统的Bootloader从而让Ubuntu和Win7能够和平共存并且具有鲁棒性,方便以后安装系统。


所以以下是操作步骤:
1、启动到Win7,把/dev/sda1根目录中的bootmgr以及Boot文件夹复制到/dev/sda2也就是Win7系统的根目录。
2、启动到Ubuntu,将/dev/sda1格式化,将/dev/sda1去掉boot标志,将/dev/sda2加上boot标志位。
3、不要关机,趁现在还在Linux下,重新安装Grub到/dev/sda,方法是
复制代码
  1. sudo grub-install --no-floppy /dev/sda
  2. sudo update-grub

以上两行命令的作用分别是:
安装Grub引导管理器,并向MBR写入引导信息
更新Grub操作系统选单。

4、准备一张Windows7系统盘,放进光驱,重启计算机,选择从光盘启动。进入Windows7安装向导,选择修复计算机。
5、取消安装向导可能提示你进行的自动修复,进入命令提示符进行手动修复,执行以下命令:
复制代码
  1. bootrec /scanos
  2. bootrec /fixboot
  3. bootrec /rebuildbcd

以上三行命令的作用分别是:
扫描磁盘寻找已安装的Windows系统,
将引导信息写入系统分区的前512字节(而非MBR),
重新构建系统选单,防止BOOTMGR找不到Windows系统。
注意到我并没有使用bootrec /fixmbr命令,因为如果那样的话Grub写入MBR的引导信息会被覆盖。
6、关闭命令提示符,重启计算机并取出光盘,从硬盘启动电脑。
现在你的电脑开机,读取MBR会引导计算机从/dev/sda5启动,并加载位于/dev/sda5的GRUB也就是Ubuntu使用的Bootloader,
然后你可以选择启动Linux系统或者将引导任务转交给/dev/sda2,并加载位于/dev/sda2的BOOTMGR也就是Windows7使用的Bootloader。


那么,目前存在一个小小的缺憾是:
GRUB Bootloader可以将引导任务转交给BOOTMGR,然而BOOTMGR却不能将引导任务交还给GRUB。
所以进阶教程主要研究如何尽量在不更改主硬盘MBR的前提下让Bootloader可以互相转交引导任务,以及介绍更多引导工具。
我选择的是GRUB4DOS,因为他太简单了!完全无需更改MBR。

操作步骤:
1:下载Grub4dos,从中解压缩出来三个文件,grldrgrldr.mbr,以及menu.lst,并将它们放进Windows系统根目录。
严格来说,menu.lst是需要修改一下以适应不同的电脑,不过其初始menu.lst已经写的很不错了,可以寻找并加载磁盘上的Windows系统或者使用Grub Legacy的任何Linux系统,但默认不支持引导使用Grub 2的Linux系统。所以如果你是新手你可以不管menu.lst,老手的话可以自行修改。

2(对Win7用户):
Win7系统其实已经不再使用boot.ini文件了,不过仍然兼容它,所以在Win7系统根目录建立一个boot.ini文件,并写入如下内容
复制代码
  1. [boot loader] 
  2. timeout=10
  3. [operating systems]
  4. C:\grldr.mbr="START GRUB4DOS"

保存退出。

2(对WinXP用户或Win7/XP并存用户):
你的WinXP系统根目录下应该已经存在boot.ini文件,如果没找到,请开启系统文件、隐藏文件的显示。
更改boot.ini的属性,取消勾选只读属性,打开该文件,先将timeout的值修改为0以上的数字,例如5。然后再文件最后追加一行:
复制代码
  1. C:\grldr.mbr="START GRUB4DOS"
保存后不要忘记更改boot.ini的属性,重新勾选其只读属性。


3:重新启动计算机,你可以看到在Windows系统的引导界面,多出了一个叫做START GRUB4DOS的操作系统,选择他就可以进入GRUB4DOS引导了。
GRUB4DOS默认可以寻找并启动电脑上的Windows系统,寻找并启动电脑上使用Grub Legacy的Linux系统,或者选择从软盘启动。
我对Grub4dos的配置文件进行了小小的修改,让他可以从第一块硬盘启动,这样我又可以回到GRUB 2引导管理器了。
只需在menu.lst中新增下面几行:
复制代码
  1. title Boot from First HDD
  2. chainloader (hd0)+1
  3. rootnoverify (hd0)


到这里其实已经很完善了,你的电脑的多个Bootloader将可以互相转交引导任务,对大多数人其实已经完美了。然而……
接下来所要讲的是老旧电脑的支持。

有些同学家里可能有2000年左右的电脑,他们往往已经支持USB设备了,但其BIOS不支持USB启动,除硬盘外,仅支持软盘或光盘启动。
或者还有更老的电脑,除硬盘外,他们仅仅支持软盘引导启动,连光盘都不支持。

可是你又希望能够给这样的电脑安装一个像样的操作系统,不是吗?
于是这时候就需要祭出引导大杀器了,这是国人写的不到30K的软件哦:Smart Boot Manager,简称SBM。
你可以去其官网下载,或者最新版的Ubuntu 12.04系统盘中的install文件夹中就有sbm.bin。

SBM最牛X的特点在于:
1、大小不足30KB,可以轻松的放进一张软盘
2、可以选择从你能想到的各种设备引导计算机开机
3、可以将引导任务转交给多种设备。例如转交给优盘启动,即使你的电脑BIOS本来不支持从优盘启动


不过这里声明SBM本身并不是Bootloader,他更像一个加强版的BIOS,可以让你选择更多的引导启动设备而不受BIOS的限制

在这里介绍SBM的两种用法:
1、用dd直接烧到软盘里用
2、用Grub的映射功能,将硬盘上的sbm.bin软盘镜像映射成软盘,然后启动SBM

两种办法都很简单,不过第一个要求你必须有真的软盘。
第二个的话Grub4dos默认的系统选单就有,只要你把sbm.bin与grldr放在同一个目录下就可以

这下你可以强制BIOS中不支持光盘启动或者优盘启动的计算机,从光盘或者优盘引导启动了。
(但前提是你的系统还是支持光盘或者软盘设备的,就是说你在操作系统中无需安装额外的驱动就可以使用)
最终,我的电脑里的几个Bootloader加上SBM的关系是这样的(为了简单起见,因为MBR直接指向/dev/sda5所以没有画出来): 

全文完。

哈哈说了这么多,我终于可以在那个老旧、光驱已经坏了的Thinkpad R30上安装一个像样的操作系统了!
注:Thinkpad R30支持内建光驱、内建硬盘启动,以及USB-FDD启动,不支持USB-HDD启动,因此无法用常规的方法优盘安装系统。
注:其实以我家的网速,我是准备直接从互联网给Thinkpad R30安装Debian的,使用SBM其实是PLAN B。

2012年12月8日星期六

从互联网安装Debian(或Ubuntu等Debian系Linux),无需光盘优盘

Install Debian/Ubuntu without any external boot media via Internet 
For my English readers please click here, it will re-direct you to Ubuntu Community Documents:

这篇HOWTO讲述的是一种仅需加载越20MB核心文件,然后整个安装过程在互联网进行的,Ubuntu/Debian安装方法。
这种方法甚至不需要你刻录CD启动盘或者USB启动盘,也不需要你有另外一台电脑作为局域网启动伺服,因为除了本地约20MB的核心文件,其他的一切都直接下载自互联网。这个方法也适合其他Debian系Linux操作系统甚至更多Linux操作系统。本教程假设你的电脑已经安装有Linux系统或者Microsoft Windows XP,这样你可以无需任何Grub启动盘。如果你的电脑是全新的,或者现有系统已经崩溃,则可能需要一张Grub引导盘。

其他可用方法:
如果你的电脑暂时不具备互联网介入条件,或者你的电脑没有现有的系统,则不建议采用此种办法安装。你可以考虑硬盘安装或者光盘安装抑或是优盘安装。

安装步骤:
1. 在Ubuntu/Debian的软件源下载合适的linux核心文件和initrd初始化RAMDISK。
(以下参考地址假设你安装Ubuntu/Debian当前稳定版本,你使用i386计算机)
Debian请在浏览器打开:
http://mirrors.163.com/debian/dists/stable/main/installer-i386/current/images/netboot/debian-installer/i386/
Ubuntu请在浏览器打开:
http://mirrors.163.com/ubuntu/dists/quantal/main/installer-i386/current/images/netboot/ubuntu-installer/i386/
发现了没有,Ubuntu和Debian其实是非常相像的。如果你希望安装64位版本,或者一些老版本,你可以从网易开源软件镜像开始一级一级的往下找,就照葫芦画瓢就行。
你当然可以使用其他镜像源,例如中国科大的开源软件镜像站点,支援IPv6访问。
下载其中的linux文件(有些发行版可能是vmlinuz)以及initrd.gz文件,并保存到你电脑磁盘第一个分区的根目录。

2. 确定你的电脑有可用的Grub引导管理器
如果你现有的系统是Linux,并且已经安装有Grub,那么你可以跳过这一步。如果你安装的是Microsoft Windoes XP,请下载Grub4dos,将他解压缩到你的C盘根目录,确定你的C盘根目录下存在grldr文件以及boot文件夹。请在我的电脑中,点击工具菜单,选择文件夹选项,你需要设置显示系统文件以及显示隐藏文件。你现在可以在你的C盘发现一个boot.ini文件,请右键单击他点击属性,取消勾选他的只读选项,并打开他。将TIMEOUT值修改为大于0的数字,例如5,并且在其最后追加一行:
复制代码
  1. C:\grldr="START GRUB4DOS"
保存并退出,记得重新设置该文件为只读的哈。注意这个方法并不适合Vista或以上版本的Windows。

3、重启电脑并进入Grub手动引导模式
现在重启你的电脑。如果你原先的系统是Linux,那么你当然会直接进入Grub界面,如果你先前的系统是WinXP,那么你现在可以在你的操作系统选单中找到一项START GRUB4DOS,选择启动他进入GRUB。注意,如果你先前的系统是Linux请留意你的Grub版本是0.X还是1.X,WinXP用户无需留意,Grub4dos一定是0.X版本的。
请在当前Grub界面根据提示进入Grub的手动引导界面(Command Line)。可能你的Grub可选系统选单中有一项叫做Command Line,或者可能你需要按C键进入手动模式。
以下操作请注意区分Grub版本:
Grub 2 (版本号为1.X):
复制代码
  1. set root=(hd0,msdos1)
  2. linux   /linux
  3. initrd   /initrd.gz
  4. boot

Grub Lagacy(版本号为0.X):
复制代码
  1. root   (hd0,1)
  2. kernel   /linux
  3. initrd   /initrd.gz
  4. boot
4、Linux安装程序已经启动,请确保你的电脑已经网线(建议是在DHCP下可直接自动配置上网的环境)。并根据屏幕指示进行系统安装。