本文主要描述如何在FreeBSD系统下使用独立的USB存储设备制作便携式系统维护盘。
制作完成的系统维护盘除了包含完整的FreeBSD操作系统外,还能够实现以下主要功能:
-
修复或安装FreeBSD
-
引导进入其他各种LiveCD
-
安装其他操作系统
考虑到实用及便携性需求,建议使用大小为32G、接口为USB 3.0的U盘制作(以下简称U盘)。
1. 准备分区
1.1 获取设备信息
插上U盘后,首先确认其设备路径:
# camcontrol devlist <ST31000528AS CC46> at scbus0 target 0 lun 0 (ada0,pass0) <ST31000528AS CC46> at scbus4 target 0 lun 0 (ada1,pass1) <ALPHACHI USB DISK> at scbus7 target 0 lun 0 (da0,pass2)
在这里,U盘对应的设备路径为/dev/da0;由此可以获取U盘的基本信息:
# diskinfo -v /dev/da0 /dev/da0 512 # sectorsize 31610372096 # mediasize in bytes (29G) 61739008 # mediasize in sectors 0 # stripesize 0 # stripeoffset 3843 # Cylinders according to firmware. 255 # Heads according to firmware. 63 # Sectors according to firmware. 1292621180710063 # Disk ident.
这里需要注意sectorsize与stripesize的数值:前者为逻辑扇区大小,后者为物理扇区大小,两者单位均为字节;而只有stripesize为4096的设备在分区时才需要设置4K对齐。
1.2 创建分区
有了这些信息,即可开始分区:
# gpart destroy -F /dev/da0 清除U盘之前的分区信息 da0 destroyed # gpart create -s MBR /dev/da0 创建新的MBR分区表 da0 created # gpart add -t fat32 -s 4g da0 添加一个大小为4GB的FAT32分区 da0s1 added # gpart add -t freebsd da0 剩余分区将用于安装FreeBSD da0s2 added # gpart create -s BSD /dev/da0s2 在剩余分区上创建新的BSD分区表 da0s2 created # gpart add -t freebsd-ufs da0s2 添加UFS分区 da0s2a added # gpart show da0 查看创建的MBR分区表 => 63 62530561 da0 MBR (29G) 63 8388576 1 fat32 (4G) 8388639 54141948 2 freebsd (25G) 62530587 37 - free - (18k) # gpart show da0s2 查看创建的BSD分区表 => 0 54141948 da0s2 BSD (25G) 0 54141948 1 freebsd-ufs (25G)0
这里需要注意两点:
-
为了使第一个FAT32分区能够在绝大多数Windows系统下使用,应该创建MBR分区表而非GPT分区表。
-
直接将FreeBSD安装至第二个分区上会无法引导,需要在第二个分区中嵌套一个BSD分区表。
更多有关分区的信息,详见分配磁盘空间。
2. 安装引导管理器
由于FreeBSD自带的引导管理器无法满足稍后的需求,在这里需要使用GRUB 2。
2.1 安装GRUB 2
首先通过Ports安装GRUB 2:
# portsnap fetch update ... (省略无关输出,下同) # cd /usr/ports/sysutils/grub2/ # make install clean ...
然后将GRUB 2的引导管理器安装至U盘:
# newfs_msdos -L USB /dev/da0s1 格式化分区并添加卷标USB以便于之后挂载 ... # mount_msdosfs /dev/da0s1 /mnt/ 这里不能使用卷标挂载,否则GRUB 2安装后会无法引导 # grub-install --root-directory=/mnt /dev/da0 安装GRUB 2的引导管理器 ...
2.2 基本配置
安装完成后,创建配置文件/mnt/boot/grub/grub.cfg:
set timeout=60 引导菜单超时秒数 set pager=1 输出内容过多时自动分屏 insmod part_gpt 预读模块part_gpt以识别使用GPT分区方案的存储设备 menuentry "Continue" { 跳过GRUB 2引导管理器 set root=(hd1) chainloader +1 } menuentry "Reboot" { 重启 reboot } menuentry "Shutdown" { 关机 halt }
目前仅需以上这些配置即可,编辑完成后执行下列命令:
# rm /mnt/boot/grub/device.map device.map是根据当前机器自动生成的,可以删除 # mkdir /mnt/iso/ 此目录用于放置各LiveCD对应的映像文件 # umount /mnt/ 安全卸除挂载的分区
3. 安装系统
默认情况下,FreeBSD系统的安装是通过sysinstall(9.0之前)或bsdinstall(9.0开始)所开启的交互模式进行的;但在这里,直接使用分发包安装会更加方便。下面以9.1-RELEASE amd64为例具体说明。
3.1 使用分发包安装
如果之前已经下载过安装映像文件FreeBSD-9.1-RELEASE-amd64-memstick.img,那么可以从其中直接提取分发包进行安装:
# newfs -L usb -j /dev/da0s2a 格式化分区并添加卷标usb以便于之后挂载 ... -j表示为UFS文件系统开启soft updates journaling # mount /dev/da0s2a /mnt/ # mdconfig memstick.img 文件memstick.img对应于之前下载的安装映像文件 md0 通过mdconfig命令用其创建内存盘 # mount /dev/md0a /media/ 挂载创建的内存盘 # tar -C /mnt/ -xvf /media/usr/freebsd-dist/base.txz 解包并写入系统文件 ... 作为基系统的base.txz与kernel.txz必须安装 # tar -C /mnt/ -xvf /media/usr/freebsd-dist/kernel.txz 同目录下的其他包则可以根据需要选择安装 ... # cp -Riv /media/usr/freebsd-dist/ /mnt/install/ 将分发包复制到U盘以用于在其他机器上安装系统 ... # umount /media/ # mdconfig -d -u 0 安全移除创建的内存盘
如果还没有下载过安装映像文件,可以通过FTP直接获取需要的分发包:
# ftp -a ftp.freebsd.org 若访问速度过慢,可更换为ftp.cn.freebsd.org ... ftp> cd pub/FreeBSD/releases/amd64/amd64/9.1-RELEASE/ 250 CWD command successful. ftp> ls 229 Entering Extended Passive Mode (|||63772|) 150 Opening ASCII mode data connection for '/bin/ls'. total 307588 -rw-r--r-- 1 1006 1006 782 Dec 4 10:10 MANIFEST -rw-r--r-- 1 1006 1006 59854248 Dec 4 10:09 base.txz -rw-r--r-- 1 1006 1006 1443284 Dec 4 10:10 doc.txz -rw-r--r-- 1 1006 1006 1117428 Dec 4 10:10 games.txz -rw-r--r-- 1 1006 1006 58045476 Dec 4 10:10 kernel.txz -rw-r--r-- 1 1006 1006 9743636 Dec 4 10:10 lib32.txz -rw-r--r-- 1 1006 1006 87926876 Dec 4 10:10 ports.txz -rw-r--r-- 1 1006 1006 96450488 Dec 4 10:10 src.txz 226 Transfer complete. ftp> mget base.txz kernel.txz 下载基系统包,其他包可根据需要选择下载 mget base.txz [anpqy?]? a 输入a后回车以全部确认 ...
有关各分发包的说明,详见介绍bsdinstall。
3.2 系统配置
经过以上操作,当前系统中的/mnt/即为将来U盘系统的根目录。现在仅需做一些必要的配置即可完成安装,而其他额外的配置可以在进入新系统后再做。
1) 创建交换文件:
# dd if=/dev/zero of=/mnt/swap bs=256m count=1 ... # chmod 0600 /mnt/swap
在这里使用交换文件替代传统的交换分区。因为空间有限,与单独的交换分区相比,能够按需调整大小的交换文件会更具弹性;注意交换文件不应小于256MB。
2) 创建/mnt/boot/loader.conf并添加以下内容:
tmpfs_load="YES" 开启内存文件系统
3) 创建/mnt/etc/fstab并添加以下内容:
/dev/ufs/usb / ufs rw 1 1 /dev/msdosfs/USB /media msdosfs rw 0 0 tmpfs /tmp tmpfs rw 0 0
4) 创建/mnt/etc/make.conf并添加以下内容:
WRKDIRPREFIX=/tmp 在内存文件系统中编译Ports;不仅能够显著提升编译速度,更能够避免对U盘不必要的读写 但需注意及时make clean以防止空间耗尽
5) 创建/mnt/etc/rc.conf并添加以下内容:
swapfile="/swap" 使用交换文件 powerd_enable="YES" hostname="FreeBSD"
更多内容可以参考/etc/defaults/rc.conf。
6) 使用命令chroot /mnt/切换根目录后,通过命令tzsetup设置时区,通过命令passwd设置root密码。操作完成后退出并卸除/mnt/上挂载的分区。
3.3 添加引导信息
挂载之前的FAT32分区以编辑GRUB 2配置文件:
# mount_msdosfs /dev/msdosfs/USB /mnt/ # vi /mnt/boot/grub/grub.cfg
在grub.cfg中为U盘系统添加对应的引导菜单:
menuentry "FreeBSD" { 设置所显示的菜单名称 set root=(hd0,2,a) 指定系统根目录所在分区 kfreebsd /boot/loader 指定系统加载器 }
4. 安装LiveFS
虽然之前安装的系统已经完全可以实现LiveFS的功能,但在这里仍会添加一个基于mfsBSD的LiveFS,原因在于:
-
如果U盘本身的系统出现了故障,进入此LiveFS即可进行修复
-
mfsBSD能够被完全读入内存,非常适合大批量本地或远程部署FreeBSD
安装此LiveFS的操作非常简单,首先下载对应版本的mfsBSD映像文件并将其复制到/mnt/iso/,然后在/mnt/boot/grub/grub.cfg中添加对应的引导菜单:
menuentry "LiveFS" { loopback loop (hd0,1)/iso/mfsbsd-9.1-RELEASE-amd64.iso 使用loopback功能将ISO文件“模拟”为分区(loop) kfreebsd (loop)/boot/kernel/kernel.gz 由于系统被读入内存,因此启动完成后可直接拔掉U盘 kfreebsd_module (loop)/mfsroot.gz type=mfs_root }
mfsBSD登录时root密码为mfsroot,其他相关信息请参见其官方网站。
[注] 目前测试发现,9.1版本的iso文件使用此种方式引导某些机器时会报错,此问题修正前可暂时使用9.0版本。
5. 添加LiveCD
完整的系统及各种Ports,已经足以满足FreeBSD的维护需求,但对于其他的操作系统,可能还需要各种LiveCD作为补充。
有别于传统的刻录或dd命令写入方式,这里通过GRUB 2自带的loopback功能,能够非常容易的实现多个LiveCD共存:只要将LiveCD对应的iso文件置于/media/iso/,然后在/media/boot/grub/grub.cfg中添加引导菜单即可;而/media/位于FAT32分区,可以在任何系统下操作。
以下将列出一些常用的LiveCD所对应的引导菜单,未列出的可以在其对应的网站上查询。对于很多采用Syslinux引导的LiveCD,可能需要将其引导菜单手动转换为GRUB 2引导菜单。
5.1 独立式LiveCD
1) GParted(分区操作)
menuentry "GParted" { set root=(hd0,1) set file="/iso/gparted.iso" 将下载后的iso文件更名为gparted.iso loopback loop $file linux (loop)/live/vmlinuz boot=live config union=aufs noswap noprompt ip=frommedia toram=filesystem.squashfs findiso=$file initrd (loop)/live/initrd.img }
这里更名文件的目的在于:新版本的LiveCD发布时,只要下载对应的iso文件并覆盖即可完成升级,无需再次修改引导菜单。
2) Clonezilla(磁盘镜像与克隆)
menuentry "Clonezilla" { set root=(hd0,1) set file="/iso/clonezilla.iso" loopback loop $file linux (loop)/live/vmlinuz boot=live live-config noswap nolocales edd=on nomodeset ocs_live_run=\"ocs-live-general\" ocs_live_extra_param=\"\" ocs_live_keymap=\"\" ocs_live_batch=\"no\" ocs_lang=\"\" ip=frommedia nosplash toram=filesystem.squashfs findiso=$file initrd (loop)/live/initrd.img }
3) DBAN(数据擦除)
menuentry "DBAN" { loopback loop (hd0,1)/iso/dban.iso linux (loop)/DBAN.BZI nuke="dwipe" }
5.2 集成式LiveCD
1) SystemRescueCd(基于Gentoo Linux)
menuentry "SystemRescueCd" { set root=(hd0,1) set file="/iso/systemrescuecd.iso" loopback loop $file linux (loop)/isolinux/rescue64 isoloop=$file docache setkmap=us dostartx #linux (loop)/isolinux/altker64 isoloop=$file nomodeset initrd (loop)/isolinux/initram.igz }
2) Parted Magic OS(基于Slackware)
menuentry "PartedMagicOS" { set root=(hd0,1) set file="/iso/pmagic.iso" loopback loop $file linux (loop)/pmagic/bzImage edd=off load_ramdisk=1 prompt_ramdisk=0 rw loglevel=9 max_loop=256 vmalloc=320MiB iso_filename=$file initrd (loop)/pmagic/initrd.img }
6. 维护实例
6.1 安装FreeBSD
安装FreeBSD时若无需多系统共存,强烈建议使用GPT而非MBR分区表,因为GPT不仅结构简练,而且没有2T容量的限制。以下为具体步骤:
1) 使用此U盘启动机器,选择FreeBSD菜单后以root登录。
2) 通过获取设备信息一节的方法获取硬盘信息,以下假设目标硬盘为/dev/ada0。
3) 输入gpart destroy -F /dev/ada0清空之前的分区信息,注意如果存在嵌套的子分区表(可通过命令gpart show检查)也应一并删除。
4) 输入gpart create -s GPT /dev/ada0创建新的GPT分区表。
5) 输入gpart add -t freebsd-boot -s 64k ada0添加大小为64KB的引导分区,若需要设置4K对齐可在命令中添加参数-a 4k。
6) 输入gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada0在引导分区中写入引导记录。
7) 输入gpart add -t freebsd-swap -s 4g -l swap ada0添加大小为4GB(可按需设置)的交换分区,若需要设置4K对齐可在命令中添加参数-a 4k;注意这里通过-l swap给分区添加了标签swap以便于挂载。
8) 输入gpart add -t freebsd-ufs -l sys ada0将剩余空间全部划分给系统,若需要设置4K对齐可在命令中添加参数-a 4k;注意这里通过-l sys给分区添加了标签sys以便于挂载。
9) 输入newfs -j /dev/ada0p3格式化系统分区,其中-j表示开启soft updates journaling;若为固态硬盘还可添加参数-t以开启TRIM。
10) 输入mount /dev/ada0p3 /mnt/将格式化好的系统分区挂载至/mnt/后,依次执行tar -C /mnt/ -xvf /install/base.txz与tar -C /mnt/ -xvf /install/kernel.txz安装基系统;注意/install/下的其他分发包也可根据需要酌情安装。
11) 参考系统配置一节进行必要的系统配置;因为这里已经添加了独立的交换分区,所以无需再配置交换文件,另外注意/mnt/etc/fstab应写为:
/dev/gpt/sys / ufs rw 1 1 dev/gpt/swap none swap sw 0 0 tmpfs /tmp tmpfs rw 0 0
12) 配置完成后,重新启动并从硬盘引导,即可进入安装好的系统。
6.2 安装Linux
绝大多数Linux发行版都会提供ISO格式的LiveCD,同时支持从LiveCD安装系统;也就是说,只要通过添加LiveCD一节的方法引导至LiveCD即可。
例如,使用此U盘安装Gentoo Linux时,对应的GRUB 2引导菜单可写作:
menuentry "Install Gentoo" { set root=(hd0,1) set file="/iso/gentoo.iso" 将下载后的iso文件更名为gentoo.iso loopback loop $file linux (loop)/isolinux/gentoo root=/dev/ram0 init=/linuxrc dokeymap looptype=squashfs loop=/image.squashfs cdroot initrd=gentoo.igz isoboot=$file initrd (loop)/isolinux/gentoo.igz }
使用此种方式引导个别Linux发行版所提供的LiveCD可能会出现一些问题,需要执行额外的修正操作。例如,下面的菜单用于引导openSUSEKDE LiveCD:
menuentry "openSUSE KDE LiveCD" { set root=(hd0,1) set file="/iso/opensuse-kde.iso" 将下载后的iso文件更名为opensuse-kde.iso loopback loop $file linux (loop)/boot/x86_64/loader/linux kiwidebug=1 initrd (loop)/boot/x86_64/loader/initrd }
但此菜单仅能引导至LiveCD的的Debug模式(命令行界面),必须继续手动输入以下命令来引导至图形界面:
# mkdir /livecd/ # mount /dev/sdb1 /mnt/ # mount -o loop /mnt/iso/opensuse-kde.iso /cdrom/ # mount -o loop /mnt/iso/opensuse-kde.iso /livecd/ # exit
6.3 安装Windows
由于GRUB 2并不能直接引导Windows安装所用的iso文件,因此需要使用另外一种方式。这里假设iso文件名为win.iso,目标硬盘为/dev/ada0,以下为具体步骤:
1) 使用独立式LiveCD一节的方法为此U盘添加GParted并引导进入。
2) 使用GParted为/dev/sda(即FreeBSD下的/dev/ada0)创建msdos分区表,然后划分出系统所在分区并格式化为ntfs,最后将其flag设置为boot。
3) 重启并引导进入U盘上的FreeBSD系统,使用Ports安装p7zip与fusefs-ntfs。
4) 挂载之前创建的Windows系统分区并写入Windows安装文件:
# kldload /usr/local/modules/fuse.ko 加载ntfs-3g所需的模块 # ntfs-3g /dev/ada0s1 /mnt/ 这里假设之前创建的Windows系统所在分区为/dev/ada0s1 # 7z x win.iso -o{/mnt/} 由于绝大部分Windows安装盘均为UDF格式,因此无法使用tar解压 ...
5) 重启并选择Continue菜单从目标硬盘引导后,即可正常安装Windows。
整个过程中需要注意两点:
-
之所以使用GParted,是因为在FreeBSD中无法格式化NTFS分区(fusefs-ntfs自带的mkntfs命令格式化时会卡在99%)。
-
一旦引导进入了Windows安装环境,系统分区下除sources文件夹外的所有内容均可删除,而安装完成后sources文件夹也可删除。
6.4 多系统共存
以上分别描述了如何单独安装FreeBSD、Linux与Windows,本节将说明怎样使用此U盘实现多系统共存。
使用传统方式在同一硬盘上安装多系统的难点在于:为了协调各系统启动管理器之间的关系,必须谨慎考虑安装的先后次序。使用此U盘安装则会简单很多:首先以任意顺序单独安装各系统,最后统一调整引导信息;除此之外,在任何时刻均可非常容易的修改甚至替换引导管理器。
以下为具体的安装步骤,最终实现的效果为:一块硬盘包括三个分区,使用FreeBSD自带的MBR启动管理器引导,F1、F2、F3分别对应于FreeBSD、Linux、Windows。
1) 执行安装FreeBSD一节的前3步以初始化目标硬盘,这里假设其为/dev/ada0,容量250GB。
2) 输入gpart create -s MBR /dev/ada0创建新的MBR分区表。
3) 输入gpart add -t freebsd -s 100g ada0添加大小为100GB的freebsd分区以安装FreeBSD,若需要设置4K对齐可在命令中添加参数-a 4k。
4) 输入gpart create -s BSD /dev/ada0s1嵌套BSD分区表后,输入gpart add -t freebsd-ufs ada0s1在其中添加freebsd-ufs分区,若需要设置4K对齐可在命令中添加参数-a 4k。
5) 输入gpart add -t linux-data -s 64g ada0添加大小为64GB的linux-data分区以安装Linux,若需要设置4K对齐可在命令中添加参数-a 4k。
6) 输入gpart add -t ntfs ada0将剩余空间划分为ntfs分区以安装Windows。
7) 使用安装Linux一节的方法在硬盘的第2个分区(即Linux下的/dev/sda2)上安装Linux。
8) 使用独立式LiveCD一节的方法为此U盘添加GParted并引导进入后,将硬盘的第3个分区(即GParted下的/dev/sda3)格式化为ntfs,并将其flag设置为boot。
9) 执行安装Windows一节的后3步以在ntfs分区上安装Windows。
10) 重启并引导进入U盘上的FreeBSD系统后,在硬盘的第1个分区上安装FreeBSD:
# newfs -L sys -j /dev/ada0s1a 格式化分区并添加卷标sys以便于之后挂载 ... 若为固态硬盘还可添加-t以开启TRIM # mount /dev/ada0s1a /mnt/ # tar -C /mnt/ -xvf /install/base.txz 解包并写入系统文件 ... 作为基系统的base.txz与kernel.txz必须安装 # tar -C /mnt/ -xvf /install/kernel.txz 同目录下的其他包则可以根据需要选择安装 ...
11) 参考系统配置一节进行必要的系统配置;注意为简化分区结构这里并未划分单独的交换分区,所以应按需设置交换文件(普通使用4GB即可),当然也可直接拆出freebsd-swap分区。
12) 安装FreeBSD自带的MBR启动管理器:
# gpart bootcode -b /boot/boot0 ada0 安装boot0引导管理器 bootcode written to ada0 # gpart set -a active -i 1 ada0 激活引导 active set on adaos1 # gpart bootcode -b /boot/boot ada0s1 写入bootstrap bootcode written to ada0s1 # boot0cfg -t 182 /dev/ada0 设置引导菜单等待时间,注意数字单位为tick(即滴答,18.2滴答约为1秒)
整个过程中需要注意两点:
-
各系统所在分区及安装顺序随意,只要最后安装启动管理器即可,另外F1、F2、F3键始终依次对应第1、2、3分区。
-
一般硬盘的每磁道为63个扇区,MBR信息位于编号为0的首个扇区,而gpart会要求分区按照柱面对齐(不跨磁道),因此首个分区至少应跳过MBR所在磁道(第0至62扇区)从第63扇区开始,也就是说添加首个分区时需要在gpart命令中使用-b 63;对于支持4K对齐的硬盘,则应使用-b 504 -a 4k,其中504为4096/512与63的最小公倍数。
6.5 固件更新
对于以iso文件提供的固件更新,也可以使用类似的方式进行,但可能需要MEMDISK辅助(下载Syslinux分发包后将文件memdisk解压至/media/iso/)。
1) 更新Seagate硬盘Firmware(所需文件*.iso可从Seagate Download Finder页面查询并下载)
menuentry "Seagate Firmware" { set root=(hd0,1) loopback loop (hd0,1)/iso/*.iso linux16 /iso/memdisk initrd16 (loop)/*.ima;1 *.ima;1位于*.iso根目录中,具体名称可通过tar -tvf *.iso获取 }
2) 更新ThinkPad笔记本BIOS(所需文件*.iso可从ThinkPad网站查询并下载)
menuentry "ThinkPad BIOS" { set root=(hd0,1) linux16 /iso/memdisk iso 注意这里需添加引导参数iso initrd16 /iso/*.iso }
3) 某些固件的更新可能仅提供了DOS方式,此时可使用FreeDOS:
menuentry "FreeDOS" { set root=(hd0,1) linux16 /iso/memdisk iso 注意提前将固件更新所需的相关文件置于/media/ initrd16 /iso/freedos.iso 引导成功后需要在安装过程中取消安装才能够进入Live模式执行固件更新 }