移动硬盘启动linux引导,从USB移动硬盘上引导Portable Linux详解

慕容俭
2023-12-01

相应的内核也从2.4.20换成了现在用的2.6.21。

中间借用的工具也从开始用的VMWare换成了现在的qemu。

当然,不排除有优良的发行版本和更新的内核源码和工具可以不再用自己DIY,以下只是讲讲我自己动手的经历:

首先,要有一个可分区安装Linux的USB移动硬盘,理论上Flash U盘也可以,SD/XD等闪存卡+读卡器也可以,不过FLASH芯片的速度相对还是慢了些,实用程度远没有用移动硬盘高。这里还要提到移动硬盘最好是支持USB 2.0的,用的主板最好也如此,USB1.0和1.1的速度上,实用程度也很低。理论上用IEEE 1394火线接口的移动硬盘更快,只是我没有条件试过。

再首先,移动硬盘的USB/IDE转换板也有点讲究,我先后试过的几种移动硬盘转接板中,以那种标有IBM的小板子的移动硬盘盒最差,就算是在Windows下,也经常有硬盘离线的情况发生,一般用那种整块垫着硬盘的底板的移动硬盘盒不错,最好就是单口就能供电启动。

其次,准备一套发行版的Linux安装光盘,当然,ISO文件也成,这里假设的当然是我们从Windows环境下开始,如果当前用的是linux,可能还不用那么麻烦。

第三、准备一套可用的虚拟机环境,如果不在乎盗版或是你己经为之合法地付费,那么首选VMWare,这几乎是X86平台下虚拟X86平台的性能取好的虚拟机软件了,虚拟速度几乎达到1:1,如果一定要合法地使用软件,那么就用qemu吧,去哪里下载,请自己找。

第四、把移动硬盘连接到Windows 宿主机上来,正确地认出来,这里假设当前宿主机只有一块内部硬盘,移动硬盘是唯一连接的一个移动存储设备。正确地配置虚拟机,把移动硬盘(在Windows下,第二块硬盘的设备文件是\.PhysicalDrive1)完全交给虚拟机作为主要硬盘,VMWare下,通过向导你可以建立一个vmdk文件,但是仅仅是指明,这个虚拟硬盘就是宿主机上的移动硬盘,这都可以在GUI下实现。在Qemu下,指明将移动硬盘作为虚拟机的命令是:

qemu.exe -boot d -L . -m 256 -hda \.PhysicalDrive1 -cdrom d:CDIMGSFC-i386-CD1.ISO -localtime

这里我不想太多去讨论虚拟机的使用,否则就变成虚拟机操作的经验之谈了,这里最后只提一个小提示,使用qemu的话,安装kqemu可以得到相当程度的性能提高。

总而言之,我们建立一台使用USB硬盘作为主硬盘的虚拟机,并从光盘上引导或是从光盘镜像文件上引导它,顺利地安装了一套运行在虚拟机上的发行版本的Linux,这里又仅以FC 5 Linux为实例了,其实发行版本其实也大同小异。

第五、确保安装后运行在虚拟机中的Linux系统有完整的内核开发环境和内核源代码。这里又要扯到虚拟机的使用上去了,不管用什么办法,可能你需要安装开发环境、下载内核源代码的最近版本,可以正确地配置虚拟机直接上网下载、也可能利用宿主机下载后用FTP、Samba共享的办法甚至做成光盘镜像来让虚拟机终于可以配置和编译内核。

第六、开始配置新的内核,其中,重要的是要让这个内核支持USB移动存储驱动,而且还不能是内置在内核中,而是编译成内核驱动模块,由于存储驱动模块化,而又是引导时段需要的,因此,这个内核还必须支持引导过程的内存镜像盘(initrd)。于是,需要配置的内核部分包括:

至少必须的文件系统支持:ext3、ext2,反正都有initrd了,就配成模块方式。

至少必须支持的SCSI驱动:scsi、scsi-sd,这两个被VMWare 的虚拟Buslogic SCSI控制器和USB Storage驱动所依赖,配置成模块方式:

到少必须支持的USB驱动:usb支持、usb-storage即usb存储驱动。还有必须的uhci_hcd(基于intel系列芯片及VIA系列的的USB 1.0/1.1总线控制器)、ohci_hcd(基于AMD、nForce、ALI等兼容芯片的USB 1.0/1.1总线控制器)、ehci_hcd(扩展的USB 2.0总线控制器)。都配置模块方式。

至少必须支持的块设备:LoopBack Device Support,模块方式/内核方式都可以,2.4版本的内核使用Loop设备的方式来存放initrd镜像。 Ram disk支持,这个是必须,并且要编译在内核里。还有最重要的是Initrd的支持,需要编译到内核中,2.6的内核配置中,intitrd - Initial RAM filesystem and RAM disk (initramfs/initrd) support放在内核的General setup之下。

其它的部分,都可以按需定制。配置了内核之后,不外就是编译内核与内核模块、安装复制内核模块、安装新的内核。这些和通常的定制linux内核大同小异。把新的内核安装到当前系统上,并且加入到GRUB的选项中(这里又是假设了,假设当前使用的是GRUB作为Boot loader,至于LILO、syslinux这些,也是大同小异)。

中间提到一个有用的工具:BusyBox,如果有整个定制过程中出现麻烦,反复地修正和重启是个麻烦事,而把Bash整到启动过程中,依赖的各种库文件很是占用空间,先在虚拟系统内下载一个BusyBox编译安装绝对有益于后面定制过程中的手工调试。

当然,对于最终结果来说,BusyBox不是必须的。

到这里,虚拟机里己经安装了一个新的内核,如果你愿意,不妨用它在虚拟机里引导一下,看看它是否工作良好。

第七才开始进入正题,动手对付这个新内核的initrd镜像,让它能正确地联接在主机上从USB盘上启动起来,而不是在虚拟机里启动。先把/boot/initrd-2.6.21.img 复制到你的工作目录下来,并把它更名成.gz文件,解开到一个定制的目录中,这里我是这么做的:

#cd

3cp /boot/initrd-2.6.21.1.img hd.gz

#mkdir newinitrd

#gunzip hd.gz

#cd newinitrd

#cpio -i --make-Directories < ../hd

这个时候,newinitrd目录下就是整个initrd文件内被打包压缩了的文件。

这里扯一下:发行版内的mkinitrd工具,来自于mkinitrd软件包,你可以用mkinitrd --version查一下,编译核心的最后一步make install这个过程的最后一步就是mkinitrd,这是一个shell脚本,有耐心和兴趣的可以仔细读一下,在我用的5.0.32版本的mkinitrd工具中,linux的开发者也己经试图加入了生成从usb盘引导linux的功能,只可惜,似乎生成的initrd并不能正常从USB移动硬盘上引导,最后还是得我们自己定制。

第八:把需要用的内核模块从/lib/modules/当前版本/kernel/drivers....等目录中复制到当前initrd解开后的目录的lib目录下。在这之前,先看看里面有什么,不同的情况下,还是有一些差别的。

接着上面的shell环境:

#cd lib

#ls -l

-rw-r--r-- 1 root root 69348 07-24 05:13 BusLogic.ko

-rw-r--r-- 1 root root 144796 07-24 05:13 ext3.ko

-rw-r--r-- 1 root root 75736 07-24 05:13 jbd.ko

-rw-r--r-- 1 root root 24564 07-24 05:13 ub.ko

-rw-r--r-- 1 root root 148040 07-24 05:13 usbcore.ko

-rw-r--r-- 1 root root 102960 07-24 05:13 usb-storage.ko

哦?己经帮我把usb等模块都复制上去了,还带了一个BusLogic的SCSI驱动。仔细比较这些ko文件,有不少还是被strip过的,比/lib/modules下的缩水小了很多。但是......

少了总线驱动,它以为我把usb总线控制器编译到内核中了?没办法,这里只好老老实实地先把总线驱动文件先复制过来。

接着上面的shell环境:

#cp /lib/modules/2.6.21.1/kernel/drivers/usb/host/ehci-hcd.ko .

#cp /lib/modules/2.6.21.1/kernel/drivers/usb/host/uhci-hcd.ko .

它们可以去掉内部的一些符号以缩小体积:

#strip ehci-hcd.ko

#strip uhci-hcd.ko

还少了必须的scsi disk 支持模块:

#cp /lib/modules/2.6.21.1/kernel/drivers/scsi/sd_mod.ko .

这个不就必strip了,似乎strip它的话,会加载不上。

除此之外,我们还得准备一个sleep,取代linux引导时用的nash中的sleep内部命令,那个不能有效地进行延时,于是到再到bin目录下:

这里还是得保留在我们的newinitrd目录下:

#cd ../bin

#cp /bin/sleep .

除此之外,还得也准备好sleep所依赖的库文件:

#ldd ./sleep

linux-gate.so.1 => (0xffffe000)

libc.so.6 => /lib/libc.so.6 (0x00c44000)

/lib/ld-linux.so.2 (0x003b7000)

它需要lib目录下要有libc.so.6和ld-linux.so.2,找到它们,复制到lib目录下

#cd ../lib

#cp /lib/ld-linux.so.2 .

#cp /lib/libc.so.6 .

到这里,必须的文件就准备好了。

以上也有补充:sleep也可以由BusyBox取代,虽说下载一个BusyBox再编译多一些功夫,可是我还是很开心地编译了BusyBox并把它复制到newinitrd 的 bin目录下,并给它建了几个有用的链接,以下是用BusyBox的可选过程,就不用上面的sleep了:

(先进到newinitrd/bin下)

#cp /root/busybox-1.6.0/busybox . (这里是我下载的busybux,并编译了支持ash,一个小型的shell)

#ln -s busybox ash

#ln -s busybox sleep

可以试一下整个newinitrd目录作为根的效果了:

#cd (回到用户目录下)

#chroot newinitrd /bin/ash

BusyBox v1.6.0 (2007-06-12 22:55:20 CST) Built-in shell (ash)

Enter 'help' for a list of built-in commands.

# exit

退出回到原来的bash和原来的根上面。(busybox同样依赖于ld-linux.so.2和libc.so.6,请参考上面的方法把依赖的库文件复制到lib目录下)

第九:修改newinitrd目录下的init脚本,让它启动运行时正确依次加载文件系统支持模块、scsi支持模块、scsi-disk支持模块、usb支持模块、usb-storage支持模块、USB1.0/1.1总线驱动、USB2.0总线驱动,并在总线驱动的加载之间延时等待设备连入总线、发现与就序。由于usb驱动需要使用proc文件系统,还要确保先向根挂载了proc文件系统。

 类似资料: