Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103639383
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: LINUX

2008-05-02 10:56:30

文章分类:

获得外置驱动器是一种为较老设备注入生机的极好方法,或者允许您在不能(或不想)改变内置硬盘驱动器的机器上运行 Linux。

假设您想在双引导系统中使用 Linux,但计算机硬盘驱动器中没有任何可用空间。一个解决方案就是使用“活动的”Linux 发行版,如 Knoppix,它可以直接从 CD 运行。如果是偶尔使用,这种方法确实可行,但是它有许多严重的缺点:

  • 您仍需要一些数据文件的永久存储。如果仅使用非常小的文件,可以使用软盘;对于中等大小的文件,USB 闪存盘可能就足够了,但是它们都不是理想的方法。
  • 当使用“活动的”CD 时,要安装自己的应用程序或定制现有应用程序会非常困难,甚至不可能。
  • 使用活动发行版会降低性能,最显著的就是当启动检测所有设备时 —— 但运行时也会降低性能(因为所有东西都必须从 CD 加载,这通常要比从硬盘驱动器加载慢得多)。

自然,还有其他选择。例如,可以买其他内置驱动器并在其中安装 Linux。但常见的情况是,机器中可能没有任何可用的驱动器托架(笔记本电脑更是如此,它通常仅允许一个内置硬盘驱动器)。

或者,您可以使用更大的驱动器替代当前的驱动器,并在由此得到的额外空间中安装 Linux。不过,这是一个花费时间的选择,因为它需要您在新的驱动器上重新安装现有 OS 系统,重新安装和重新配置所有应用程序及还原所有数据。

一种更好的解决方案是购买外置硬盘驱动器,并在其中安装 Linux。这使您可以不更改现有硬件和软件,仅在想使用 Linux 的时候连接外置驱动器即可。

可移动驱动器选项

可在其中安装 Linux 的移动设备的范围包括从软盘驱动器到 USB 闪存设备,再到 USB/FireWire 硬盘驱动器等等。

虽然的确可能将 Linux 安装在小容量的设备中,如 1.44 MB 软盘或 32 MB USB 盘,但这些通常(必然)都是专门的经过缩减的发行版,例如,用于拯救损坏的安装。

不过,外置硬盘驱动器以合理的成本为通用的 Linux 发行版提供最多的灵活性。

外置驱动器来自许多不同的制造商(Maxtor、Western Digital 等等),可以有各种不同的大小。这些驱动器都包含一个外置盒,放置标准 3-1/2 英寸或 2-1/2 英寸 IDE 驱动器。这些驱动器通常都通过 USB 或 IEEE1394(FireWire)连接到计算机上。

USB 有两个主要版本,1.1 和 2.0。版本 1.1 最大传输速度为 12 Mbit/s(兆比特/秒),而版本 2.0 支持最高达 480 Mbit/s 的传输速度。虽然大多数兼容 2.0 的驱动器都可向后兼容 1.1,但是一般最好避免使用 1.1,除非别无选择(因为它的速度比较慢)。

FireWire 标准还定义了许多不同的可能速度,但是实际上,无论何时人们说到 FireWire,他们都是指“FireWire400”,它支持最高达 400 Mbit/s 的传输。

从速度来看,在 USB 2.0 和 FireWire 之间没什么可选择的:虽然 USB 2.0 报出的速度较高,实际上因为协议不同,它们都是差不多的。如果您的计算机两者都有,或许使用 USB 更好,而不是 FireWire(后面我会讲明原因),但是如果仅有 FireWire,则当然只能选择 FireWire。为了获得最大的灵活性,从大量支持 USB 2.0 和 FireWire 的驱动器中选择一个(比如,我在本文稍后使用的驱动器)。

对于没有所需端口、PCI(对于台式电脑)和 PCMCIA(对于笔记本电脑)的计算机,可以很便宜地买到 FireWire 和 USB 2.0 卡:例如,我在本文后面使用的 PCMCIA FireWire 卡大概是用 10 GBP(不到 20 美元)买到的。

为了完成本文,我购买了 5-1/4 英寸外置驱动器盒。这是非常灵活的盘盒,它不与任何驱动器一起提供,可以装入任何标准 IDE 设备,包括 3-1/2 英寸硬盘驱动器和 5-1/4 英寸 IDE 设备,如 CD-RW/DVD-RW 驱动器。该盘盒具有 USB 2.0 和 FireWire 连接。

为了将盘盒连接到我的 IBM Thinkpad T30 笔记本电脑,我还购买了 PCMCIA FireWire 卡(内置 USB 端口仅支持 USB 1.1)。

盘盒和 FireWire 卡都比较便宜(分别是 50 GBP 和 10 GBP)。

出于测试目的,我将盘盒与我准备的 13GB 3-1/2 英寸 IDE 驱动器连接 —— 在实际使用时,我会购买更大容量的驱动器,这些驱动器现在也非常便宜(大约每 GB 50 GBP!)

Linux 支持

正如您可能期望的那样,Linux 对这些盘盒的支持确实很好。任何遵守“大容量存储设备”的 SBP(Serial Bus Protocol)标准的设备都可以很容易地与 Linux 一起使用。

一般来说,要启用对这些设备的支持,内核需要支持许多内容(直接编译或通过模块)。

对于 USB 和 FireWire,SBP 设备支持都通过 SCSI 仿真实现 —— 即,设备显示给 Linux 就好像它们是 SCSI 磁盘一样。这是在 Linux 中抽象存储设备的一种通用方法(例如,IDE CD/DVD 驱动器也通常使用 SCSI 仿真连接)。因此,需要下列内核支持:

  • SCSI 支持
  • SCSI 仿真
  • SCSI 磁盘支持

另外,根据连接方法,还会需要下列支持:

  • 对于 FireWire
  • IEEE1394 支持
  • OHCI1394 支持
  • RAW1394 支持
  • SBP-2 支持
  • 对于 USB
  • (主机端)USB 支持
  • OHCI 支持
  • UHCI 支持
  • USB 大容量存储支持

显然,您必须完全正常支持其他硬件(显卡等等),根据您实际的硬件情况,可能还需要一些其他模块。

例如,我使用 PCMCIA (cardbus) FireWire 卡,所以需要添加:

  • PCMCIA 支持
  • cardbus 支持

安装

现在我们有了外置设备,将开始在其中安装 Linux。

现在安装 Linux 的最容易的方法(当然是我的观点)是连接所有硬件(在这里,包含插入 PCMCIA FireWire 卡、将 FireWire 线缆连到 PCMCIA 卡和驱动器上、打开驱动器的电源开关);然后使用您选择的发行版的安装 CD 来引导计算机。

我选择的发行版是 Gentoo(请参阅 参考资料获得相关链接),所以我使用最新的“Universal” x86 Live CD (2004.1)。其他发行版所需的步骤应该会比这里讲述的步骤多或者少。

一旦已经使用安装 CD 引导,如果幸运的话,它应该已经识别了您的驱动器。驱动器应该显示为 /dev/sdX 下的磁盘,其中 X 是从“a”开始的小写字母。在我的系统中,外置驱动器被检测为 /dev/sda,但是如果您有其他 SCSI 磁盘(模拟的 SCSI 磁盘),这将发生变化;在那种情况下,它可能是 /dev/sdb 或其他字母。如果驱动器没有被自动检测,可能需要进一步的步骤 —— 例如,您可能必须通过引导选项来启用 FireWire 或 PCMCIA,或者可能必须手工加载一些内核模块或类似的其他项(请参阅 参考资料获得故障排除指南的链接)。

一旦驱动器已经被识别,就考虑安装的其余部分而言,它应该确实像内置硬盘驱动器一样运转;所以您应该可以根据需要对其进行分区和像平常一样安装 Linux。

不过,提醒一句:当决定安装引导加载程序(通常是 GRUB 或 LILO)的位置时一定要小心 —— 我建议不要将其安装在 Master Boot Record (MBR)(通常默认就是这样)中。而是应该安装在外置驱动器的根分区(或引导分区,如果使用单独的引导加载程序)中。

现在我们已经在设备中安装了 Linux,接着要引导 Linux。从这里可以开始有一些技巧。

引导

在讨论引导新的驱动器之前,需要了解一些引导加载程序理论。

引导加载程序通常安装在计算机第一个硬盘的 MBR 中。调用引导加载程序时(BIOS 自动执行 MBR 中的代码),它通常显示可以引导的 OS 的菜单。选择一个给定 OS 引导。

关于此场景应该注意两点:

  • OS 选择菜单(通常)从磁盘加载。
  • 要引导相关 OS,引导加载程序需要从磁盘读取相关内核。

由于以上操作在加载 OS 之前发生,它意味着所有磁盘读取都必须通过 BIOS 调用的方式发生。这会涉及严重的问题:即为了直接引导磁盘,您的 BIOS 必须支持通过 FireWire 或 USB 连接的磁盘。这通常可以看作从这些类型的磁盘引导的一个 BIOS 选项。实际上 FireWire BIOS 支持当前很少见,但 USB 支持正在变得相当普遍。因此,如果您在相对较新的计算机中使用 USB,应该可以直接在 Linux 中引导驱动器。

在外置驱动器的 MBR 中安装了 GRUB 之后,当通过 USB 连接时,我可以直接引导该驱动器。当引导连接的磁盘时很简单地进入了 BIOS 设置程序。外置磁盘将显示为普通的硬盘驱动器:移动该磁盘使它在引导顺序中位于内置驱动器之前。

我也可以在内置驱动器的 MBR 中安装引导加载程序,并使用它引导 USB 驱动器(这时它在 GRUB 中显示为 hd1 in GRUB)。如果您使用 FireWire,有可能 BIOS 不能直接引导驱动器,将需要一些其他操作。

幸运地是,因为 Linux 的灵活性,如果您不能直接引导(使用 PCMCIA FireWire 卡,我的情况肯定是这样!),会有相当简单的解决方案。可以从支持的设备(如软盘驱动器、CD、USB key 或主驱动器上的微小分区)执行初始引导步骤,然后使用外置驱动器进行其他操作。

构建引导映像

可以使用两种方法引导:

  • 一阶段引导
    内核引导、安装根文件系统,并通过调用初始化脚本(通常是 /sbin/init)继续进行初始化。
  • 两阶段(initrd)引导
    内核引导、安装初始 ram 磁盘(initrd),执行进一步的可定制初始化,然后安装根文件系统并继续进行初始化(通常也是通过调用 /sbin/init)

这两种方法都有自己的优点和缺点。

一阶段引导

为了使用一阶段引导,我们需要构建内核,其具有安装内置根文件系统所需的所有驱动器(其他任何驱动器都可以在正常初始化过程中,在能够从根分区加载的模块中构建)。

如果我们要从非常小的设备引导(如软盘),最好的方法是构建的内核仅具有足够使我们可以安装根外置文件系统的内置驱动器 —— 然后将其他所有项构建为模块。例如,我内置了 SCSI 支持、PCMCIA 支持、IEE1394、SBP 和类似支持,但是其他所有项(包括显卡支持、网络设备支持等等)都作为模块构建,这些模块存储在根分区(在外置驱动器上)中,而不是软盘上。

使用简单(一阶段)引导过程,我们应该能够构建具有所需支持的内核,将其放在软盘驱动器中,在软盘中安装引导加载程序(我使用 GRUB,但还有其他选择,如 LILO),然后使用与此内核(对于 GRUB)相似的内核引导:

root (fd0)
kernel (fd0)/boot/bzImage root=/dev/sda1

这种方法基本上可以工作,但有两个问题:

  1. 因为 SBP 支持使用 SCSI 仿真,为了检测磁盘和允许安装 /dev/sda1,需要“重新扫描”仿真的 SCSI 总线。这种扫描使用一组简单的命令执行。不过,遗憾的是,使用一阶段引导,我们不能运行任何命令,直到内核已经完成引导,而内核直到安装了根文件系统才能完成引导 —— 典型的自相矛盾困境。令人感到高兴的是,对于导致 SCSI 总线在启动时被扫描的 2.4 内核有可用的修补程序(有关更多详细信息,请参阅 参考资料)。通过应用此修补程序,我可以使外置驱动器在引导过程中由内核自动检测,而不需要任何重新扫描命令。这使我们进入了下一个问题。
  2. 内核中有定时窗口,这意味着内核经常在其能够被正确的监测和初始化之前尝试安装根设备。对于此问题,也有可用的修补程序(请参阅 参考资料获得相关链接),它只是使内核在启动时等待很短的时间,并使其在安装根文件系统失败时重试(为外置驱动器提供时间识别)。

通过应用这两个修补程序,我可以成功地在可引导软盘上构建内核,其将引导,然后使用外置 FireWire 驱动器作为根。

这种方法的主要问题是需要我们给内核源码打补丁 —— 这最多是一件痛苦之事(当发行新的内核版本时),严重时会是个大问题(如果没有维护补丁程序与内核发生的其他更改保持一致的话)。

您可能已经想到如果我们的 BIOS 支持 USB 或 FireWire 且我们直接引导,我们就可以避免这两个问题。不幸的是,情况并不是这样:虽然此方法在引导过程中使用 BIOS 调用来访问磁盘,一旦内核开始初始化,将不再使用 BIOS,而是使用内核驱动器访问磁盘 —— 这样就会遇到相同的问题。

两阶段引导

到了内核版本 2.0.X,向 Linux 内核添加了一项引人注意的能力 —— 使用“initial RAM disk”(或 initrd)提供两阶段引导过程。

简而言之,内核像平常一样引导;但不安装“真实的”根文件系统,而是在 RAM 中创建微型根文件系统并安装该系统。在安装真实的根、切换为使用真实的根并销毁 initial RAM disk 之前,任何步骤都可以在此初始环境中执行。

这在各种环境中都有用,但是为了便于说明,我们将仅使用我们的迷你环境重新扫描 SCSI 总线,等待外置磁盘被识别,然后切换为使用该磁盘作为真实的根继续引导。

为了使用这种方法,我们需要创建两项,内核和 initrd 映像。

内核就是具有内置 initrd 支持的普通内核。initrd 映像是包含我们的迷你根文件系统的回送文件系统映像(此映像可以使用 gzip 进行压缩以减少其大小)。

有关创建或定制自己的 initrd 映像的详细信息,可以查看 参考资料部分。

在 initrd 映像中,有一个名为 linuxrc 的文件。当加载 initrd 时会执行此文件,所以确保其具有执行权限!我们为了进行说明,所以 linuxrc 非常简单:


清单 1. initrd linuxrc


#!/bin/sh
REAL_ROOT=/dev/sda1
# mount the /proc filesystem
mount -t proc none /proc

#for scsi-emulation
# modprobe sd_mod

#for pcmcia
# modprobe pcmcia_core

#for FireWire
# modprobe ieee1394
# modprobe ohci1394
# modprobe raw1394
# modprobe sbp2

#for USB
# modprobe usbcore
# modprobe ohci-hcd
# modprobe uhci-hcd
# modprobe usb-storage

# loop rescanning the scsi bus + rerunning devfsd
retries=5
i=1
until [ -e $REAL_ROOT ]
do
  if [ $i -gt $retries ]
  then
     echo "Unable to mount real root ($REAL_ROOT) - Giving up!"
     /bin/ash
     exit
  fi

  echo "Real root ($REAL_ROOT) not found, retrying ($i)"
  sleep 1
  echo "scsi add-single-device 0 0 0" > /proc/scsi/scsi
  echo "scsi add-single-device 1 0 0" > /proc/scsi/scsi
  echo "scsi add-single-device 2 0 0" > /proc/scsi/scsi
  /bin/devfsd /dev -np
  i=$((i+1))
done

#umount /proc as it will be remounted by the normal init process
umount /proc

#now we simply exit, and the normal boot process should continue
exit 0

我们做的所有操作都是加载适当的模块来支持外置驱动器:它们应该根据需要被解注。(我在内核中构建了所有必需的支持,因此不需要任何模块。)然后我们进行循环,重新扫描 SCSI 总线(通过将命令回送到 /proc pseudo-filesystem 中的特殊文件,并调用 devfsd ),直到出现根设备(我的例子中为 /dev/sda1)。在我的例子中,讨论的仿真 FireWire SCSI 总线是 1 0 0 ,不过也可以尝试其他的,而不会有任何负面影响 —— 如果您知道要使用的总线,可以裁剪脚本。同样,如果您有其他 SCSI 设备(或仿真 SCSI 设备),驱动器可能会有不同的字母(例如,/dev/sdb1)。如果不使用外置驱动器的第一个分区,则需要使用不同的编号(例如, /dev/sda2)。

现在所需要做的就是将相关文件复制到 initrd 映像中(可以使用 mount -o loop 命令安装未压缩的映像)。特别地,需要确保具有 linuxrc 文件、在其中使用的所有命令和那些命令依靠的所有库。然后,(未装载的)映像可以进行压缩。

接着把内核(bzImage)和 initrd 映像(initrd.gz)复制到(bootable, ext3)软盘中。

最后一步是在软盘中安装引导加载程序,并使用下列选项引导内核: kernel bzImage root=/dev/sda1 initrd=initrd.gz

现在应该可以使用软盘进行引导:它将从软盘加载内核,将 initrd 映像加载到 RAM 中,等待识别根设备,然后像平常一样从那里继续引导。从此以后,可以移除软盘。

如果软盘不适合(例如,如果计算机没有软盘驱动器),则可以使用能够通过 BIOS 引导的任何设备。就个人而言,为了写作本文,我使用小的 32Mb USB 盘。或者,如果您不介意改变内置硬盘驱动器的话,为了更便于引导,可以在其中创建小的分区。

原文链接:http://www-128.ibm.com/developerworks/cn/linux/l-fireboot.html

阅读(120) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~