设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

让FreeBSD和Gentoo Linux在ZFS存储卷上共存

2017-1-4 21:55| 发布者: joejoe0332| 查看: 571| 评论: 0|原作者: leoxu, LinuxWind, 被盗用户|来自: oschina

摘要: 我回归到 Librem 15 已经有段时间了。我一般会选择 FreeBSD 来处理所有的事情,但有时会要访问一个运行在 Librem 平台上的 Linux OS,以便用它对一些遗留的设备驱动进行移植 (比如 BYD 鼠标以及控制屏幕亮度的驱动程 ...

我回归到 Librem 15 已经有段时间了。我一般会选择 FreeBSD 来处理所有的事情,但有时会要访问一个运行在 Librem 平台上的 Linux OS,以便用它对一些遗留的设备驱动进行移植 (比如 BYD 鼠标以及控制屏幕亮度的驱动程序)。

为了将此进行实现,我安装了一个自己花时间开发的一个设置:那是一个在 ZFS 存储卷上共存的 FreeBSD 和 Gentoo Linux 双引导系统。本文描述了如何实现这项配置。

注意,本文是基于 EFI 引导加载程序的。如果你坚持要使用传统的 BIOS 引导程序,那么就需要对整个过程进行一下调整。

方案概述

该方案的基础是利用 ZFS 文件系统的通用功能 (即利用面向使用了基于 fstab 方法的 OS 数据集的挂载点功能) 结合 GRUB,实现一个双引导 OS。

ZFS 概述

ZFS 系统同 FreeBSD 和 Linux 上“典型的”ZFS设置有些微不同。某些数据集 (比如home目录) 是由两个操作系统共享的, 但是位于各自挂载点中的 OS 数据集则要依赖于我们所使用的OS,而因此 ZFS 特定的挂载点功能是不能有效使用的。

在本文中,假定存储卷的名字是 “data”。

整个方案看起来如下:

  • data/home 被挂载到 /home, 与其所有的子数据集一起使用 ZFS 挂载点系统;

  • data/freebsd 及其子数据集包含了 FreeBSD 系统,而其所有的挂载点都被设置成 legacy;

  • data/gentoo 及其子数据集包含了 Gentoo 系统,其所有的挂载点也都被设置成 legacy。

OS 和 GRUB 概述

两个 OS 都必须利用 /etc/fstab 方法来挂载他们大多数的文件系统, 因此我们不能使用 ZFS 挂载点功能。这样每个 OS 就都需要一个不同的 fstab。注意 data/home 数据集 (以及其它类似的数据集) 都会使用 ZFS 挂载点方法来进行挂载,而不是 fstab。

此外,两个OS都要通过一个特殊的顶层目录 (Gentoo 上是 /freebsd, FreeBSD 上是 /gentoo) 来访问另外一个系统的数据。

GRUB 引导加载程序可以被用来提供一个引导选择设施,而无需进行大的修改和配置 (不过要知道输入到 grub.cfg 文件中去的类型的神奇方式!)

设置过程

设置过程包括如下几个步骤:

  1. 使用 FreeBSD 安装器创建 GPT 和 ZFS 池;

  2. 使用 FreeBSD 启动加载程序安装并配置 FreeBSD;

  3. 启动并进入 FreeBSD, 创建 Gentoo Linux 数据集,安装 GRUB;

  4. 启动并进入 Gentoo Linux 安装器,安装 Gentoo;

  5. 启动并进入 Gentoo, 完成配置任务。

当然,你也可以将步骤倒着进行,先安装 Gentoo,然后再使用它的工具。只是上列顺序能使 FreeBSD 上 GPT 的创建和 GRUB 的安装顺利许多。

准备工作

要执行这个安装过程,你需要为两个OS安装 memstick 镜像。FreeBSD 的安装程序可从这里得到; Gentoo 的可以从这里得到 (使用 livedvd ISO 格式)。(当然,)你还需要有途径能进行互联网访问。

注意对于 Librem 15 或者类似的没有以太网连接的笔记本电脑, 你可能需要在主要的安装过程中对 Gentoo 无线工具以及 wpa_supplicant 的安装过程采取一些轻微的修改。

FreeBSD 安装程序

引导进入 FreeBSD 安装程序,通过引导程序菜单选择手动分区模式。这样做会让你进入一个 shell 操作环境,教你创建你的分区并将所有的东西挂载到 /mnt。

创建分区和 ZFS 池

第一件要做的事情就是使用 gpart 工具来创建你的分区。FreeBSD 的 man 页面就相当好,因此你可以使用 “man gpart” 来获取关于这个工具的指南。我在 Librem 15 上执行这个过程看起来是下面这个样子:

gpart create -s gpt ada0
gpart create -s gpt ada1
gpart add -t efi -l efi-system -s 200M ada0
gpart add -t freebsd-zfs -l zfs-data ada0
gpart add -t linux-swap -l swap -s 96G ada0
gpart add -t freebsd-zfs -l zfs-data-log -s 16G ada0
gpart add -t freebsd-zfs -l zfs-data-cache ada0

然后用新的分区来创建一个 ZFS 池,并使用 DOS 文件系统来对 EFI 系统分区进行格式化 (见鬼了,为什么我们还要用这玩意儿?):

newfs_msdos /dev/ada0p1
zpool create -m legacy -o atime=off -o checksum=sha256 data /dev/ada0p2 log /dev/ada0p2 cache /dev/ada0

注意我们已经将 atime (它可以大大降低磁盘的写入量)关掉了,并且将校验算法设置成了 sha256。

ada1 磁盘是一块我装进去的 SSD(固态硬盘)。如果你没有 SSD,那么做日志或者缓存方面的设置就没啥意义。16GB 的意向日志是有点多余,但是它可以减轻设备的压力。注意我们将根数据集的挂载点设置成了 “legacy”。

注意 Linux 有其自己的交换格式,因此我们不能将交换设备进行共享。

创建 ZFS 数据集

有了一个 ZFS 存储池后,接下来要做的就是创建数据集。我们先创建 FreeBSD 根目录(root)并对其进行挂载 (注意,它会从父目录继承 “legacy”挂载点):

zfs create -o compression=lz4 data/freebsd
mount -t zfs data/freebsd /mnt/

我们需要创建一些挂载点目录:

mkdir /mnt/home
mkdir /mnt/gentoo/
mkdir /mnt/tmp
mkdir /mnt/usr
mkdir /mnt/var

我使用一个相当精细的 ZFS 方案, 它对不同的目录设置不同的可执行性、权限和压缩比等属性。这样可以达到很显著的压缩比,有效的增加了磁盘的可用空间:

zfs create -o exec=on -o setuid=off -o compression=off data/freebsd/tmp
zfs create -o exec=on -o setuid=on -o compression=lz4 data/freebsd/usr
zfs create -o exec=off -o setuid=off -o compression=gzip data/freebsd/usr/include
zfs create -o exec=on -o setuid=off -o compression=lz4 data/freebsd/usr/lib
zfs create -o exec=on -o setuid=off -o compression=lz4 data/freebsd/usr/lib32
zfs create -o exec=on -o setuid=off -o compression=gzip data/freebsd/usr/libdata
zfs create -o exec=on -o setuid=on -o compression=lz4 data/freebsd/usr/local
zfs create -o exec=on -o setuid=off -o compression=gzip data/freebsd/usr/local/etc
zfs create -o exec=off -o setuid=off -o compression=gzip data/freebsd/usr/local/include
zfs create -o exec=on -o setuid=off -o compression=lz4 data/freebsd/usr/local/lib
zfs create -o exec=on -o setuid=off -o compression=lz4 data/freebsd/usr/local/lib32
zfs create -o exec=on -o setuid=off -o compression=gzip data=freebsd/usr/local/libdata
zfs create -o exec=on -o setuid=off -o compression=gzip data/freebsd/usr/local/share
zfs create -o exec=off -o setuid=off -o compression=off data/freebsd/usr/local/share/info
zfs create -o exec=off -o setuid=off -o compression=off data/freebsd/usr/local/share/man
zfs create -o exec=on setuid=on -o compression=lz4 data/freebsd/obj
zfs create -o exec=on -o setuid=on -o compression=lz4 data/freebsd/usr/ports
zfs create -o exec=off -o setuid=off -o compression=lz4 data/freebsd/usr/ports
zfs create -o exec=on -o setuid=off -o compression=gzip data/freebsd/usr/share
zfs create -o exec=off -o setuid=off -o compression=off data/freebsd/usr/share/info
zfs create -o exec=off -o setuid=off -o compression=off data/freebsd/usr/share/man
zfs create -o exec=off -o setuid=off -o compression=gzip data/freebsd/usr/src
zfs create -o exec=off -o setuid=off -o compression=lz4 data/freebsd/var
zfs create -o exec=off -o setuid=off -o compression=off data/freebsd/var/db
zfs create -o exec=off -o setuid=off -o compression=lz4 data/freebsd/var/db/pkg
zfs create -o exec=off -o setuid=off -o compression=gzip data/freebsd/var/log
zfs create -o exec=off -o setuid=off -o compression=off data/freebsd/var/empty
zfs create -o exec=off -o setuid=off -o compression=gzip data/freebsd/var/mail
zfs create -o exec=on -o setuid=off -o compression=off data/freebsd/var/tmp

因为 FreeBSD 对于某些文件的所在位置有着非常严格要求,所以这个方案效果很好。

你也可以将其细分,以达到你期望,比如在 /usr/share 下创建更多的子目录。

对于 Gentoo,由于 Linux 更倾向于宽松的文件定位,你可以采取一个更简单的方案:

zfs create -o exec=on -o setuid=off -o compression=off data/gentoo/tmp
zfs create -o exec=on -o setuid=on -o compression=lz4 data/gentoo/usr
zfs create -o exec=off -o setuid=off -o compression=lz4 data/gentoo/var

在 Gentoo 系统下需要细分子目录的用户权限,类似于我在 FreeBSD 下的操作。

最后的任务是手动挂载所有的文件系统,命令模版如下:

mount -t zfs data/freebsd/<path> /mnt/<path>

这个命令模板十分必要,它适合所有传统的挂载方式。另外,因显示所有命令要占据较大空间,在此我将其省略。

安装和配置 FreeBSD 系统

输入 “exit”后会返回到 FreeBSD 安装程序,同时所有的东西都被挂载在了 /mnt/。  安装过程中的提示信息直接明了。为了最后两项配置任务,你还需要进入一个 shell 环境。

进入 shell,然后进入新的 FreeBSD 系统:

chroot /mnt

创建 fstab

因为我们已将大多数的 ZFS 数据集挂载到了每个 OS 各自不同的路径下,所以需要为他们创建一个 /etc/fstab 文件。下面的 fstab 会将所有的数据集挂载到正确的位置上:

data/freebsd/tmp /tmp zfs rw 0 0
data/freebsd/usr /usr zfs rw 0 0
data/freebsd/usr/include /usr/include zfs rw 0 0
...
data/gentoo/ /gentoo zfs rw 0 0
data/gentoo/tmp /gentoo/tmp zfs rw 0 0
...
proc /proc procfs rw 0 0

注意,此处我已将许多条目信息省略掉。你需要按照上述操作,将每一个数据集映射到与其对应的合适路径上。

安装 FreeBSD 原生引导程序

我们需要 FreeBSD 引导加载程序来执行首次进入系统的操作。执行如下几个步骤进行安装:

mount -t msdosfs /dev/ada0p1 /mnt
mkdir /mnt/efi
mkdir /mnt/efi/BOOT
cp /boot/boot1.efi /mnt/efi/BOOT/BOOTX64.EFI

然后设置 zpool 上的 bootfs 参数, 以便 FreeBSD 引导加载程序可以选到正确的数据集:

zpool set -o bootfs=data/freebsd data

你可能还需要为某些硬件设置 EFI 系统分区上的 bootme 标识:

gpart set -a bootme -i 1 ada0

现在你的系统可以直接进入 OS 了。

FreeBSD 主要操作系统

现在你可以直接引导进入 FreeBSD 了。你还需要连接到一个与 wpa_supplicant 配置相关的网络。

在进行其他事项之前,先获取到新的源代码,有利于对全局以及内核进行重新构建,这样做能确保系统处于最新状态。你可能也需要获取到端口的集合等。与此类相关的内容,你可自行查看资料。

安装 GRUB

grub-efi 端口会安装一个兼容 EFI 系统的 GRUB 版本。这个端口要比在 Gentoo 上进行同等的操作简单得多。端口的安装方法如下:

cd /usr/ports/sysutils/grub2-efi
make install clean

你需要使用 grub-mkconfig 命令创建一个 grub.cfg 文件,过程中可能需要对该命令进行编辑。你也可以直接使用下面这个文件 (make sure it’s at /boot/grub/grub.cfg):

insmod part_gpt
insmod zfs

menuentry 'FreeBSD' --class freebsd --class bsd --class os {
  search.fs_label data ZFS_PART
  echo "Loading FreeBSD Kernel..."
  kfreebsd ($ZFS_PART)/freebsd/@/boot/kernel/kernel
  kfreebsd_loadenv ($ZFS_PART)/freebsd/@/boot/device.hints
  kfreebsd_module_elf ($ZFS_PART)/freebsd/@/boot/kernel/opensolaris.ko
  kfreebsd_module_elf ($ZFS_PART)/freebsd/@/boot/kernel/acl_nfs4.ko
  kfreebsd_module_elf ($ZFS_PART)/freebsd/@/boot/kernel/zfs.ko
  set kFreeBSD.vfs.root.mountfrom=zfs:data/freebsd
  set kFreeBSD.vfs.root.mountfrom.options=rw}

menuentry 'Gentoo Linux' {
  search.fs_label data ZFS_PART
  linux ($ZFS_PART)/gentoo@/boot/kernel dozfs=force root=ZFS=data/gentoo
  initrd ($ZFS_PART)/gentoo@/boot/initramfs
}

注意,此处我们已为 Gentoo 创建了一项配置。最后,你需要挂载 EFI 系统分区然后安装 GRUB:

mount -t msdosfs /dev/ada0p1 /mnt
grub-install --efi-directory=/mnt --disk-module=efi

这样做会将 GRUB 引导程序安装到 EFI 系统分区的 /efi/grub/grub.efi,你需要将它拷贝到相应位置。在此之前,我建议你先对 FreeBSD 本地的引导加载程序进行备份:

cp /mnt/efi/BOOT/BOOTX64.EFI /mnt/efi/BOOT/BOOTX64.BAK

这样能省去在操作有误时的回退操作。现在拷贝 GRUB 引导加载程序:

cp /mnt/efi/grub/grub.efi /mnt/efi/BOOT/BOOTX64.EFI

之后需要对 GRUB 引导加载程序进行测试,以确保它能有效的对系统进行重新启动,并引导进入 FreeBSD。

Gentoo 安装程序

下一个任务是安装 Gentoo 基础系统。 Gentoo 的安装可以通过命令行手动完成。Gentoo Handbook 提供了一份指南。注意,因为你使用了 ZFS 作为根文件系统,因此需要使用 genkernel 来安装内核。

挂载文件系统

要使用 FreeBSD, 你就会需要对文件系统进行挂载:

zpool import -f data
mount -t zfs data/gentoo /mnt/gentoo
mkdir /mnt/gentoo/tmp
mkdir /mnt/gentoo/usr
mkdir /mnt/gentoo/var
mount -t zfs data/gentoo/tmp /mnt/gentoo/tmp
mount -t zfs data/gentoo/usr /mnt/gentoo/usr
mount -t zfs data/gentoo/var /mnt/gentoo/var

现在可以按照 Gentoo 的安装步骤来进行。

创建 fstab

使用 FreeBSD 系统时, 你需要创建一个 /etc/fstab 文件,它与 FreeBSD 的版本类似, 不过 gentoo 文件系统被挂载到了根目录的相对位置下,而 FreeBSD 文件系统则被挂载到了 /freebsd 目录的相对位置下:

data/freebsd/tmp /freebsd/tmp zfs rw 0 0
data/freebsd/usr /freebsd/usr zfs rw 0 0
data/freebsd/usr/include /freebsd/usr/include zfs rw 0 0
...
data/gentoo/tmp /tmp zfs rw 0 0
data/gentoo/usr /usr zfs rw 0 0
...

这里我省略了文件中的一些重复部分。

构建内核、ZFS 模块以及 initramfs

因为我们是从根路径下的 ZFS 文件系统启动的,因此我们需要设置一个支持 ZFS 的内核。你可以在这里查看指南(跳转到 “配置内核(Configuring the Kernel)” 一节查阅)。

我已经将 GRUB 的安装放在 /boot/kernel 和 /boot/initramfs 之后。 Gentoo 会默认将其内核安装到 /boot/kernel-<版本信息>, initramfs 也是如此。然后,我们需要使用 /boot/kernel 和 /boot/initramfs 这两个名称来创建符号链接,或者自行将文件拷贝到正确的位置。

最后是 Gentoo 的安装

在重启之前,请务必阅读该小节。下列检查列出了一些必要操作,如有遗漏则需重新进入安装程序进行操作:

  • 设置一个根密码,这样才可以真正登录进去;

  • 安装可以使用无线网络的端口;

  • 不要漏掉 /etc/fstab 中的存储卷(如果遗漏了 /var, 系统间的互操作会很繁琐)。


启动进入 Gentoo

现在你可直接从 GRUB 启动进入 Gentoo,并成功在单 ZFS 文件系统里实现了双引导。但在创建用户主目录之前,你还需要为 /home 创建一个 ZFS 数据集。在 Gentoo 系统中,进行如下操作:

rm /home || rmdir /home
rm /freebsd/home || rmdir /freebsd/home
mkdir /home
mkdir /freebsd/home
zfs create -o mountpoint=/home -o exec=on -o setuid=off -o compression=lz4 data/home

你也许还想为特定的一些用户主目录(或其子目录)创建数据集,但我们已经将挂载点设置成 /home,这样做只会导致 ZFS 挂载点功能挂载这些数据集。因此没必要再添加一个 fstab 配置项。

总结

这样的设置相当强大且灵活,是内核高手及驱动开发者的福音。下面列出了是进行该设置的好处:

  • 可以从 FreeBSD 系统访问一个完整的 Linux 系统,包括内核的源代码;

  • 便于实验性质的系统间切换操作;

  • 在某个系统坏掉时可以有效地恢复机制。

当然,还有一些使用 FreeBSD 的 Linux 仿真层的有趣的探索。一般而言, FreeBSD 的 Linux 仿真端口只会安装一个 Linux 包的最小集合。我对子系统的了解不多,所以还不知道怎么做。希望你在深入了解后能安装一个完整的 Linux 系统。


酷毙

雷人

鲜花

鸡蛋

漂亮

最新评论

(200字以内)
验证问答 换一个 验证码 换一个

  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187  

返回顶部