当系统在虚拟机中测试完毕,就可以将其移植到U盘上了。本系统是在U盘上实现的,如在其他载体上类同。
首先将U盘分区格式化。可用Linux下的fdisk分区工具进行分区,用mkfs工具进行格式化。本人就一块32MB的U盘,还要用来保存一些windows文件,故将其分为两个区,一个linux分区,一个windows分区。
#fdisk /dev/sdc
利用fdisk命令对U盘进行分区。
Disk /dev/sdc: 32 MB, 32768000 bytes
3 heads, 32 sectors/track, 666 cylinders
Units = cylinders of 96 * 512 = 49152 bytes
device Boot Start End Blocks Id System
/dev/sdc1 1 600 28784 83 Linux
/dev/sdc2 601 666 3168 5 Extended
/dev/sdc5 601 666 3152 4 FAT16 <32M
分区中sdc1是用来装linux系统的(28M)
sdc5
是fat16格式,主要用来下载网页用。
#mkfs
–
t ext2 /dev/sdc1
#mkfs
–
t vfat /dev/sdc5
用mkfs对分区格式化。
如果在系统剪裁中进行了第四步剪裁,即压缩了根文件系统,将内核模拟成硬盘使用,将不必考虑U盘的初始化问题。如不进行第四步,虽然usb-storage模块已包括在内核,但是由于U盘的初始化过程比执行/sbin/init慢,导致内核已经启动完成了,优盘还没有完成初始化工作,因此根文件系统没有加载,这时执行/sbin/init命令肯定不成功。有两种方式能使内核等待3秒等待U盘初始化完毕再启动。
(1)利用busybox重新构造initrd.
在启动内核时加载initrd.img文件到内存中,利用initrd文件中的busybox的sleep命令,使内核等待3秒使U盘完成初始化工作,再执行/sbin/init指令。该方式需要自己构造initrd文件,而且会增大initrd文件(增大300kb)。
①建立initrd.img文件
#mkdir -p /mnt/initrd
#cd /tmp
#cp /usr/src/linux-2.6.0/drivers/scsi/BusLogic.ko /lib/modules/2.6.0/kernel/drivers/scsi
//mkinitrd
需要BusLogic.ko
# mkinitrd /tmp/initrd.gz 2.6.0
②编译busybox
由于initrd中没有
libc.so.6
和ld-linux.so.2两个库文件,所以在编译busybox时要把选择不带共享库,因这里只用到它的sleep命令功能,所以编译选项中只选sleep选项。具体详见文件系统剪裁中busybox的使用方法。
③解压initrd.img文件,修改启动脚本linuxrc
#gunzip initrd.gz
#mount -o loop /tmp/initrd /mnt/initrd
#cp /sbin/busybox /mnt/initrd/bin
#cd /mnt/initrd/bin
#ln -s busybox sleep
#vi /mnt/initrd/linuxrc
加入如下内容:
echo 'wait 3 seconds.....'
/bin/sleep 3
④重新生成initrd.img文件
由于缺省建立的initrd文件比较大(为4MB),为了加快优盘的启动,必须减小它。具体操作如下:
#mkdir -p /mnt/initrdusb
#cd /tmp
#dd if =/dev/zero of= /tmp/initrdusb bs=1M count=1
#mke2fs -m 0 initrdusb
#mount -o loop /tmp/initrdusb /mnt/initrdusb
#cp -a /mnt/initrd/* /mnt/initrdusb
#cd /mnt/initrdusb
#rm ./bin/insmod //
因不用加载模块,故不//insmod可节省200K空间。
#rm ./bin/modporbe
//同上
#rm ./lib/BusLogic.ko // BusLogic.ko已编入内核,//故可删。
#cd /
# umount /mnt/initrd
# umount /mnt/initrdusb
# cd /tmp
# gzip -9 initrdusb
# cp initrdusb.gz /boot/initrd-2.6.0-usb.img
(2)通过更改linux2.6.0/init/do_mounts.c内核文件,再重新编译内核,使系统初始化时等3秒。该方式不会增大initrd文件,但需要修改内核文件。文件修改如下(+号后面为添加的内容):
void __init mount_block_root(char *name, int flags)
{
char *fs_names = __getname();
char *p;
char b[BDEVNAME_SIZE];
get_fs_names(fs_names);
+ printk("Please wait for 3 seconds....../n");
+ __set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ __set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ __set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
当完成U盘初始化initrd的构造后(也可以重新编译内核或采用ramdisk),就可以在U盘上整合系统了。
(1)
将测试好的系统打包
#mount /dev/sdb1 /mnt/sdb1
#cd /mnt/sdb1
#tar cvzf /mnt/hgfs/windows/redhat9-usb-ok.tar.gz *
(2)
将打包好的系统恢复到U盘上(被系统识为sdd)
#mkdir p /mnt/sdd1
#mount /dev/sdd1 /mnt/sdd1
#cd /mnt/sdd1
#tar zxvf /mnt/hgfs/windows/redhat9-usb-ok.tar.gz
(3)
修改U盘系统中的grub.conf文件
改为:
default=0
timeout=10
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
title Red Hat Linux (2.6.0)
root (hd0,0)
kernel /boot/vmlinuz-2.6.0 ro root=LABEL=/
initrd /boot/initrd-2.6.0.img
(4)
增加根目录标识
#e2label /dev/sdc1 /
如不进行这步,系统将无法启动。
mount: error 6 mounting ext2
pivotroot pivot_root(/sysroot,/sysroot/initrd) failed:2
umount /initrd/proc
的错误提示。
(5)
安装grub
因为系统最终将在机器上运行,不是在虚拟机上运行,故安装grub应在真实的linux下进行。而且虚拟机上的BOIS不支持从U盘启动。在机器上启动Redhat9.0
#grub
grub>root (hd1,0)
grub>setup (hd1)
(6)
设置BIOS
在BIOS中设置
Advanced BIOS Features
First Boot Device (USB-HDD)
First Boot Device (HDD-0)
这需要你的主板支持从U盘启动。
最后
插入
U
盘
,
重新启动系统。测试系统的网络功能和安全服务是否正常运转。
本章主要介绍了嵌入式操作系统如何在U盘上实现的,其中详细介绍了如何实现U盘的初始化以使内核在U盘上能正常启动,简单说明了在整合系统时要注意的几个要点。