當系統在虛擬機中測試完畢,就可以將其移植到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盤上能正常啓動,簡單說明了在整合系統時要注意的幾個要點。