FreeBSD 和固态硬盘
最后更新于
最后更新于
原文:
本文讨论了在 FreeBSD 上使用固态磁盘设备来创建嵌入式系统。
嵌入式系统由于缺少固有的活动部件(如硬盘),因此具有更高的稳定性。然而,需要考虑的是,系统中的磁盘空间通常较小,并且存储介质的耐用性问题。
本文将涵盖以下具体内容:适合在 FreeBSD 中使用的固态存储介质的类型和属性,相关内核选项,自动初始化这些系统的 rc.initdiskless
机制,文件系统只读需求,以及从零开始构建文件系统。最后,文章将总结一些适用于小型和只读 FreeBSD 环境的通用策略。
本文的范围将仅限于基于闪存的固态磁盘设备。闪存是一种固态存储介质(没有活动部件),并且具有非易失性(即使断电,数据仍能保持)。闪存可以承受巨大的物理冲击,且读写速度相对较快(本文讨论的闪存解决方案在写操作上略慢于 EIDE 硬盘,但在读取操作上要快得多)。闪存的一个非常重要的特性,是每个扇区具有有限的重写次数。每个扇区只能进行有限次数的写入、擦除和重写,超过这个次数后,扇区将变得无法使用。尽管许多闪存产品会自动映射坏块,并且一些产品甚至会将写操作均匀分布到整个设备上,但无法忽视设备的写入次数限制。竞争性产品的规格通常为每个扇区支持 1,000,000 到 10,000,000 次写入,这个数字会受到环境温度的影响。
本文特别讨论的对象是 ATA 兼容的紧凑型闪存单元,这些设备广泛用于数字相机存储。其特别之处在于它们直接与 IDE 总线连接,并且兼容 ATA 命令集。因此,使用非常简单且低成本的适配器,这些设备可以直接连接到计算机的 IDE 总线。这样连接后,FreeBSD 等操作系统会将该设备视作一个正常的硬盘(虽然容量较小)。
其他类型的固态磁盘解决方案虽然存在,但由于它们的高昂价格、相对不常见以及使用难度,超出了本文的讨论范围。
对于那些创建嵌入式 FreeBSD 系统的人来说,有一些特定的内核选项值得关注。
所有使用闪存作为系统磁盘的嵌入式 FreeBSD 系统都应关注内存磁盘和内存文件系统。由于闪存的写入次数有限,磁盘和文件系统通常会被挂载为只读。在这种环境中,/tmp
和 /var
等文件系统通常会挂载为内存文件系统,以便系统能够创建日志、更新计数器和临时文件。内存文件系统是成功实现固态 FreeBSD 系统的关键组件。
在内核配置文件中,你应确保以下行存在:
rc
子系统与只读文件系统嵌入式 FreeBSD 系统的启动后初始化是由 /etc/rc.initdiskless
控制的。
请记住,该值默认为以扇区为单位。
需要记住的是,使用 /etc/fstab
挂载的只读文件系统,可以随时通过以下命令切换为读写模式:
如果需要切换回只读模式,可以使用以下命令:
由于 ATA 兼容的紧凑型闪存卡被 FreeBSD 视为普通的 IDE 硬盘,因此理论上,你可以通过网络使用 kern 和 mfsroot 启动盘安装 FreeBSD,或使用 CD 安装。
然而,即使是通过常规安装程序进行的小型 FreeBSD 安装,也会生成超过 200MB 的系统大小。大多数人会使用较小的闪存设备(128MB 被认为相对较大,32MB 甚至 16MB 都是常见的),因此使用常规机制进行安装是不可行的——因为空间根本不足以容纳最小的传统安装。
克服这一空间限制的最简单方法是,通过常规方式将 FreeBSD 安装到普通硬盘上。在安装完成后,将操作系统精简至适合闪存媒体的大小,然后将整个文件系统打包成 tar 文件。以下步骤将指导你如何为 tar 打包的文件系统准备闪存。请记住,因为没有执行常规安装,所以需要手动进行分区、标签和文件系统创建等操作。除了 kern 和 mfsroot 启动盘外,你还需要使用 fixit 启动盘。
在使用 kern 和 mfsroot 启动盘启动后,从安装菜单中选择 custom
。在自定义安装菜单中,选择 partition
。在分区菜单中,使用 d 删除所有现有分区。删除所有现有分区后,使用 c 创建一个新分区,并接受分区大小的默认值。当询问分区类型时,请确保将其设置为 165
。然后通过按 w 将分区表写入磁盘(这是该屏幕上的隐藏选项)。如果你使用的是 ATA 兼容的紧凑型闪存卡,请选择 FreeBSD 启动管理器。然后按 q 退出分区菜单。启动管理器菜单将再次出现——重复之前的选择。
退出自定义安装菜单后,从主安装菜单选择 fixit
选项。进入 fixit 环境后,输入以下命令:
此时,你将进入 vi 编辑器,进行 disklabel
命令的编辑。接下来,你需要在文件的末尾添加一个 a:
行。这个 a:
行应该类似于以下内容:
其中,123456 是与现有 c:
项的大小相同的数字。基本上,你是将现有的 c:
行复制为 a:
行,确保文件系统类型为 4.2BSD
。保存文件并退出。
挂载刚刚准备好的闪存设备:
将这台机器接入网络,以便我们可以传输 tar 文件并将其解压到闪存文件系统中。以下是一个示例:
现在机器已经接入网络,传输你的 tar 文件。在这个过程中,你可能会遇到一些问题——例如,如果你的闪存介质为 128MB,并且 tar 文件大于 64MB,你就不能同时将 tar 文件和解压后的内容放在闪存中——这时你会遇到空间不足的问题。如果你使用 FTP 进行传输,解决方案之一是,在传输过程中直接解压 tar 文件。如果你以这种方式进行传输,tar 文件和解压后的内容就不会同时存在于磁盘上:
如果你的 tar 文件是 gzipped 的,你可以这样做:
在 tar 文件的内容被解压到闪存文件系统后,你可以卸载闪存并重启:
假设你在正常硬盘上构建文件系统时正确配置了文件系统(包括将文件系统挂载为只读,并将必要的选项编译到内核中),你现在应该能够成功启动你的 FreeBSD 嵌入式系统。
在启动时,/var 会通过 /etc/rc.d/var 根据 /etc/mtree/BSD.var.dist 中的列表进行填充,因此 cron、cron/tabs、at 以及一些其他标准目录将被创建。
然而,这并不能解决跨重启维护 cron 表的问题。当系统重启时,内存中的 /var 文件系统将消失,你可能在其中的 cron 表也会消失。因此,一个解决方案是为需要的用户创建 cron 表,将 / 文件系统挂载为读写,并将这些 cron 表复制到一个安全的位置,例如 /etc/tabs,然后在 /etc/rc.initdiskless 的末尾添加一行,将这些 cron 表在系统初始化期间创建 /var/cron/tabs 目录后复制进去。你可能还需要添加一行,使用 /etc/rc.initdiskless 来更改你创建的目录和复制的文件的模式和权限。
syslog.conf 指定了存在于 /var/log 中的某些日志文件的位置。这些文件在系统初始化时不会由 /etc/rc.d/var 创建。因此,你需要在 /etc/rc.d/var 中的某个位置,在创建 /var 中的目录后,添加如下内容:
为了能够进入 Port 目录并成功运行make install
,我们必须在一个非内存文件系统上创建一个包数据库目录,该目录将跨重启跟踪我们的包。由于安装包时需要将文件系统挂载为读写,因此可以合理地假设,闪存媒体上的某个区域也可以用来写入包信息。
首先,创建一个包数据库目录。通常这是在 /var/db/pkg 中,但由于它会在每次系统启动时消失,因此我们不能将其放在那里。
接下来,在 /etc/rc.d/var 中添加一行,将 /etc/pkg 目录链接到 /var/db/pkg。示例如下:
现在,每次你将文件系统挂载为读写并安装包时,make install
将正常工作,包信息将成功写入 /etc/pkg(因为在此时,文件系统将挂载为读写),并将始终以 /var/db/pkg 的形式可供操作系统访问。
注意
本节中的步骤仅在 Apache 设置为将其 pid 或日志信息写入 /var 之外时需要。默认情况下,Apache 将其 pid 文件保存在 /var/run/httpd.pid 中,并将其日志文件保存在 /var/log 中。
现在假设 Apache 将其日志文件保存在 apache_log_dir 目录中,该目录位于 /var 之外。当此目录位于只读文件系统上时,Apache 将无法保存任何日志文件,并可能出现无法正常工作的情况。如果是这样,就需要在 /etc/rc.d/var 中将 /var 中的目录创建列表中添加一个新目录,并将 apache_log_dir 链接到 /var/log/apache。还需要对这个新目录设置权限和所有权。
首先,将 log/apache
目录添加到 /etc/rc.d/var 中要创建的目录列表中。
其次,在 /etc/rc.d/var 中的目录创建部分后添加以下命令:
最后,删除现有的 apache_log_dir 目录,并将其替换为链接:
/etc/rc.d/var
会将 /var
挂载为内存文件系统,并使用 命令创建 /var 下的配置目录,并更改某些目录的权限。在执行 /etc/rc.d/var
时,另一个与之相关的 rc.conf 变量 varsize
会发挥作用。/var
分区会根据此变量的值在 rc.conf 中由 /etc/rc.d/var
创建:
/var
是一个可读写的文件系统,这一点非常重要,因为 /
分区(以及你可能在闪存介质上创建的其他分区)应该挂载为只读。请记住,在 部分,我们详细介绍了闪存的限制,尤其是写入次数的限制。不能强调的是,不应该将闪存上的文件系统挂载为读写模式,同时应避免使用交换文件。因为在一个繁忙的系统中,交换文件可能会在不到一年内把闪存烧坏。大量的日志记录或临时文件的创建和销毁也会造成类似的影响。因此,除了从 /etc/fstab
中移除 swap
条目外,还应将每个文件系统的选项字段更改为 ro
,如下所示:
由于这个更改,系统中的一些应用程序将立即出现故障。例如,由于缺少 cron 表,cron
将无法正常运行,syslog
和 dhcp
等程序也会遇到问题,因为 /var
中缺少 /etc/rc.d/var
创建的项。这些问题仅是暂时的,在 中,我们会介绍如何解决这些问题,并让其他常见软件包正常运行。
在 中,指出了由 /etc/rc.d/var 构建的 /var 文件系统以及只读根文件系统的存在,会导致许多与 FreeBSD 一起使用的常见软件包出现问题。在本文中,将提供一些成功运行 cron、syslog、 Port 安装和 Apache web 服务器的建议。
在讨论成功使用 Port 树所需的更改之前,必须提醒你有关闪存媒体上文件系统只读性质的事项。由于它们是只读的,你需要使用 中显示的挂载语法暂时将其挂载为读写。在完成任何维护后,你应始终将这些文件系统重新挂载为只读——不必要的写入闪存媒体可能会大大缩短其使用寿命。