---
authors:
  - 
    author: 'John Kozubik'
    email: john@kozubik.com
copyright: '2001 - 2021 The FreeBSD Documentation Project'
description: 'Использование твердотельных накопителей (SSD) в FreeBSD'
tags: ["Solid State", "embedded", "FreeBSD"]
title: 'FreeBSD и твердотельные устройства (SSD)'
trademarks: ["freebsd", "general"]
---

= FreeBSD и твердотельные устройства (SSD)
:doctype: article
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:source-highlighter: rouge
:experimental:
:images-path: articles/solid-state/

ifdef::env-beastie[]
ifdef::backend-html5[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
:imagesdir: ../../../images/{images-path}
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[.abstract-title]
Аннотация

В этой статье описывается использование твердотельных дисковых устройств для создания встраиваемых систем на основе FreeBSD.

Встраиваемые системы имеют преимущество в повышенной надёжности по причине отсутствия в них движущихся частей (жёстких дисков). Однако, следует принять во внимание, что системе, как правило, доступно очень малое дисковое пространство и ограниченный объём запоминающего устройства.

К отдельно рассматриваемым вопросам относятся типы и характеристики твердотельных носителей, подходящих для использования в качестве дисков во FreeBSD, параметры ядра, которые представляют интерес в таких условиях, механизмы [.filename]#rc.initdiskless#, автоматизирующие инициализацию таких систем и удовлетворяющие требованиям файловых систем, доступных только для чтения, а также построение файловых систем с нуля. Статья заканчивается описанием некоторых общих стратегий для случаев малых систем FreeBSD и работ в режиме только для чтения.

'''

toc::[]

[[intro]]
== Твердотельные дисковые устройства

Эта статья будет ограничиваться рассмотрением твердотельных дисковых устройств, которые делаются на основе флеш-памяти. Флеш-память является твердотельным (здесь нет движущихся частей) запоминающим устройством, которое является энергонезависимым (данные остаются в памяти даже после отключения всех источников питания). Флеш-память может быть нечувствительной к сильным физическим воздействиям и достаточно быстра (решения на основе флеш-памяти, описываемые в этой статье, гораздо медленнее, чем диски EIDE для операций записи, и гораздо быстрее их в случае выполнения операций чтения). Одним из очень важных свойств флеш-памяти, различные варианты которого будут рассмотрены далее в этой статье, является то, что каждый сектор имеет ограниченные возможности по перезаписыванию. Вы можете только записывать, стирать и снова записывать на сектор флеш-памяти определённое количество раз до того, как сектор станет полностью неработоспособным. Хотя многие продукты на основе флеш-памяти автоматически перенаправляют испорченные блоки, а некоторые даже распределяют операции записи по всему модулю, фактом является наличие ограничения на количество операций записи, которые могут выполняться с устройством. Современные модули имеют характеристики от 1,000,000 до 10,000,000 циклов записи на сектор. Эти характеристики могут зависеть от температуры рабочей среды.

В частности, мы обсудим компактные модули флеш-памяти, совместимые со стандартом ATA, которые стали весьма популярными в качестве носителя данных для цифровых камер. Особый интерес представляет тот факт, что они соответствуют шине IDE по контактам и совместимы с набором команд ATA. Таким образом, при помощи очень простого и дешевого адаптера такие устройства могут подключаться непосредственно к шине IDE компьютера. Если поступить таким образом, то такие операционные системы, как FreeBSD, распознают диск как обычный винчестер (весьма маленький).

Существуют и другие решения для твердотельных дисков, но их стоимость, безвестность и сравнительная сложность использования выводят их за рамки этой статьи.

[[kernel]]
== Параметры ядра

Для тех, кто создаёт встраиваемую систему FreeBSD, интерес представляют несколько параметров ядра.

Все встраиваемые системы FreeBSD, которые используют флеш-память в качестве системного диска, заинтересованы в использовании дисков в памяти и файловых систем в памяти. Из-за ограниченного количества циклов записи, которые можно выполнить с флеш-памятью, диск и файловые системы на нём будут, скорее всего, монтироваться в режиме доступа только для чтения. В таком случае файловые системы типа [.filename]#/tmp# и [.filename]#/var# монтируются как файловые системы в памяти для того, чтобы позволить системе создать журналы и обновить счетчики и временные файлы. Файловые системы в памяти являются критическим компонентом успешной работы FreeBSD на твердотельных устройствах.

Вы должны удостовериться, что в конфигурационном файле вашего ядра присутствуют следующие строки:

[.programlisting]
....
options         MD_ROOT         # md device usable as a potential root device
....

[[ro-fs]]
== Подсистема `rc` и файловые системы в режиме только чтения

Инициализация встраиваемой системы FreeBSD после загрузки управляется [.filename]#/etc/rc.initdiskless#.

[.filename]#/etc/rc.d/var# монтирует [.filename]#/var# как файловую систему в памяти, создаёт указываемый список каталогов в [.filename]#/var# при помощи команды man:mkdir[1], изменяет режимы доступа на некоторые из этих каталогов. В процессе выполнения [.filename]#/etc/rc.d/var# задействуется ещё одна переменная [.filename]#rc.conf# - `varsize`. Скрипт [.filename]#/etc/rc.d/var# создаёт раздел [.filename]#/var# на основе значения этой переменной из [.filename]#rc.conf#:

[.programlisting]
....
varsize=8192
....

Запомните, что по умолчанию это значение указано в секторах.

Факт использования файловой системы [.filename]#/var# в режиме чтения и записи является важным признаком, так как раздел [.filename]#/# (и любые другие разделы, которые могут находиться на флеш-носителе) должен монтироваться в режиме только для чтения. Вспомните, что в разделе crossref:solid-state[intro, Твердотельные дисковые устройства] мы касались ограничений флеш-памяти - особенно ограничений, касающихся возможностей записи. Важно не монтировать файловые системы на флеш-носителях в режимах чтения и записи, и важность отказа от файла подкачки не может быть переоценена. Файл подкачки на загруженной системе может пережечь кусок флеш-носителя менее чем за год. Частое журналирование и создание временных файлов приводят к тому же результату. Поэтому, кроме удаления записи `swap` из вашего файла [.filename]#/etc/fstab#, вы должны также изменить поле параметров каждой файловой системы на `ro` таким образом:

[.programlisting]
....
# Device                Mountpoint      FStype  Options         Dump    Pass#
/dev/ad0s1a             /               ufs     ro              1       1
....

В результате этих изменений в среднестатистической системе несколько приложений немедленно перестанут работать. Например, cron не будет нормально запускаться в результате отсутствия таблиц для него в каталоге [.filename]#/var#, созданном [.filename]#/etc/rc.d/var#, а syslog и dhcp будут испытывать проблемы из-за доступа файловой системы только для чтения, а также отсутствия записей в [.filename]#/var#, который был создан скриптом [.filename]#/etc/rc.d/var#. Хотя эти проблемы являются временными и обсуждаются вместе с решением проблем с запуском распространённых программных пакетов в разделе crossref:solid-state[strategies, Стратегии работы с системой для случаев небольших и доступных только для чтения файловых систем].

Важно помнить, что файловая система, которая была смонтирована только для чтения при помощи файла [.filename]#/etc/fstab#, в любой момент может быть сделана доступной по чтению и записи выдачей команды:

[source, shell]
....
# /sbin/mount -uw partition
....

и может быть возвращена к режиму доступа только для чтения по такой команде:

[source, shell]
....
# /sbin/mount -ur partition
....

== Создание файловой системы с нуля

Так как совместимые с ATA компактные флеш-карты распознаются во FreeBSD как обычные жёсткие диски IDE, то теоретически вы можете установить FreeBSD по сети при помощи дискет kern и mfsroot или с компакт-диска.

Однако даже маленькая установка FreeBSD при помощи обычных процедур установки может привести к созданию системы размером, превышающим 200 мегабайт. Так как большинство людей используют устройства флеш-памяти меньшего размера (128 мегабайт считается весьма большим - 32 или даже 16 мегабайт используются гораздо чаще), то установка обычным образом не подходит-просто на диске нет места даже для самой минимальной установки.

Самым простым способом обойти это ограничение на объём является установка FreeBSD обычным образом на обычный жёсткий диск. После окончания установки, обрежьте операционную систему до размера, который помещается на ваш флеш-носитель, а затем полностью заархивируйте файловую систему. Следующие шаги поведут вас через процесс подготовки части флеш-памяти для вашей заархивированной файловой системы. Запомните, что из-за того, что обычная установка не выполнялась, такие операции, как разбиение на разделы, разметка, создание файловой системы и так далее должны быть выполнены вручную. Кроме дискет kern и mfsroot вам также нужно воспользоваться дискетой fixit.

[.procedure]
====
. Разбиение вашего флеш-носителя на разделы
+
После загрузки при помощи дискет kern и mfsroot, выберите пункт `custom` из меню установки. Из следующего пункта меню выберите `partition`. В меню работы с разделами вы должны удалить все существующие разделы при помощи клавиши kbd:[d]. После удаления всех имеющихся разделов создайте раздел при помощи клавиши kbd:[c] и согласитесь с предлагаемым по умолчанию размером раздела. Когда вы будете опрошены на предмет типа раздела, удостоверьтесь, что значение типа равно `165`. Теперь запишите эту таблицу разделов на диск, нажав клавишу kbd:[w] (на этом экране эта опция скрыта). Если вы используете компактную флеш-карту, совместимую с ATA, вы должны выбрать FreeBSD Boot Manager. Теперь нажмите клавишу kbd:[q] для выхода из меню работы с разделами. Должно быть выдано ещё раз меню для выбора менеджера загрузки - повторите то, что вы выбирали ранее.
. Создание файловых систем на вашем устройстве флеш-памяти
+
Выйдите из меню установки custom, и из главного меню установки выберите пункт `fixit`. После входа в режим работы fixit, введите следующую команду:
+
[source, shell]
....
# disklabel -e /dev/ad0c
....
+
В этот момент вы войдете в редактор vi из-под команды disklabel. Затем, вам нужно добавить строку `a:` в конце файла. Эта строка `a:` должна выглядеть примерно так:
+
[.programlisting]
....
a:      123456  0       4.2BSD  0       0
....
+
Здесь _123456_ является числом, в точности совпадающим с тем, что характеризует размер имеющейся записи для `c:`. В общем, вы копируете существующую строку для `c:` для строки `a:`, не забывая определить fstype как `4.2BSD`. Сохраните файл и завершите редактирование.
+
[source, shell]
....
# disklabel -B -r /dev/ad0c
# newfs /dev/ad0a
....

. Размещение вашей файловой системы на флеш-носителе
+
Смонтируйте только что подготовленный флеш-носитель:
+
[source, shell]
....
# mount /dev/ad0a /flash
....
+
Подключите эту машину к сети, чтобы можно было перенести наш tar-файл и распаковать его в файловую систему на флеш-носителе. Вот пример того, как это можно сделать:
+
[source, shell]
....
# ifconfig xl0 192.168.0.10 netmask 255.255.255.0
# route add default 192.168.0.1
....
+
Теперь, когда машина находится в сети, перепишите ваш tar-файл. Здесь вы можете столкнуться с некоторой проблемой - если объём вашей флеш-памяти равен, к примеру, 128 мегабайтам, а ваш tar-файл превышает 64 мегабайта, то вы не можете одновременно разместить tar-файл на флеш-носителе и распаковать его - вам не хватит места. Одним из решений этой проблемы, если вы используете FTP, является распаковка файла во время его передачи по FTP. Если вы передаёте файл именно так, то вы никогда не получите на диске одновременно архивный файл и его содержимое:
+
[source, shell]
....
ftp> get tarfile.tar "| tar xvf -"
....
+
Если ваш файл обработан утилитой gzip, вы также можете этого добиться:
+
[source, shell]
....
ftp> get tarfile.tar "| zcat | tar xvf -"
....
+
После того, как вы получили содержимое вашей заархивированной файловой системы на файловой системе флеш-памяти, вы можете размонтировать флеш-память и выполнить перезагрузку:
+
[source, shell]
....
# cd /
# umount /flash
# exit
....
+
При условии, что вы правильно настроили файловую систему при её создании на обычном жёстком диске (с монтированием файловых систем в режиме только для чтения и с необходимыми опциями, встроенными в ядро), ваша встраиваемая система FreeBSD теперь должна успешно загружаться.
====

[[strategies]]
== Стратегии работы с системой для случаев небольших и доступных только для чтения файловых систем

В разделе crossref:solid-state[ro-fs, Подсистема `rc` и файловые системы в режиме только чтения] было указано, что файловая система [.filename]#/var#, создаваемая скриптом [.filename]#/etc/rc.d/var#, и наличие корневой файловой системы, доступной только для чтения, приводят к проблемам при работе многих распространённых программных пакетов, используемых во FreeBSD. В этой статье будут даны рекомендации по настройке нормальной работы cron и syslog, установке портов и веб-сервера Apache.

=== Cron

Во время загрузки содержимое каталогa [.filename]#/var# формируется скриптом [.filename]#/etc/rc.d/var# используя данные из [.filename]#/etc/mtree/BSD.var.dist#, поэтому в нём создаётся несколько стандартных каталогов, в числе которых - [.filename]#cron#, [.filename]#cron/tabs#, [.filename]#at#.

Однако это не решает проблему с сохранением cron-таблиц между перезагрузками. Когда система перезагружается, то файловая система [.filename]#/var#, которая располагается в памяти, будет уничтожена, вместе со всеми cron-таблицами, которые вы могли там иметь. Поэтому одним из решений может стать создание cron-таблиц для пользователей, которым они нужны, монтирование вашей файловой системы [.filename]#/# в режиме чтения и записи, и копирование этих cron-таблиц в безопасное место, например, в [.filename]#/etc/tabs#, и последующее добавление строки в конец скрипта [.filename]#/etc/rc.initdiskless# для копирования этих cron-таблиц в каталог [.filename]#/var/cron/tabs# после его создания во время инициализации системы. Вам может также потребоваться добавить строку, которая изменяет режимы доступа и права на каталоги, которые вы создали, и на файлы, которые вы скопировали в скрипте [.filename]#/etc/rc.initdiskless#.

=== Syslog

В файле [.filename]#syslog.conf# задано местоположение некоторых файлов протоколов, которые имеются в каталоге [.filename]#/var/log#. Эти файлы не создаются скриптом [.filename]#/etc/rc.d/var# во время инициализации системы. Поэтому где-нибудь в скрипте [.filename]#/etc/rc.d/var#, после секции, создающей каталоги в [.filename]#/var#, вам нужно добавить нечто вроде следующего:

[source, shell]
....
# touch /var/log/security /var/log/maillog /var/log/cron /var/log/messages
# chmod 0644 /var/log/*
....

=== Установка портов

Перед тем, как обсудить изменения, которые нужно сделать для успешного использования дерева портов, необходимо напомнить о том, что ваши файловые системы на флеш-носителях доступны только для чтения. Поэтому вам нужно временно монтировать их в режиме чтения и записи, используя параметры командной строки, как это показано в crossref:solid-state[ro-fs, Подсистема `rc` и файловые системы в режиме только чтения]. Вы всегда должны перемонтировать эти файловые системы в режим только для чтения после окончания работ - излишние записи на флеш носитель могут значительно сократить его срок эксплуатации.

Чтобы можно было войти в каталог с портами и успешно выполнить команду make `install`, необходимо создать каталог для пакетов в файловой системе, не располагающейся в памяти, где будут храниться пакеты между перезагрузками. Так как для установки пакета в любом случае требуется монтирование ваших файловых систем для чтения и записи, имеет смысл выделить область флеш-носителя также и для записи информации о пакете.

Прежде всего создайте каталог с базой данных о пакетах. Обычно это каталог [.filename]#/var/db/pkg#, но мы не можем разместить базу именно здесь, так как она исчезнет после перезагрузки системы.

[source, shell]
....
# mkdir /etc/pkg
....

Теперь в скрипт [.filename]#/etc/rc.d/var# добавьте строку, которая связывает каталог [.filename]#/etc/pkg# с [.filename]#/var/db/pkg#. Например:

[source, shell]
....
# ln -s /etc/pkg /var/db/pkg
....

Теперь каждый раз при монтировании ваших файловых систем для чтения и записи и установки пакета, команда make `install` будет работать, а информация о пакете будет успешно записана в каталог [.filename]#/etc/pkg# (так как файловая система будет в это время смонтирована для чтения и записи), который всегда будет доступным операционной системе как [.filename]#/var/db/pkg#.

=== Веб-сервер Apache

[NOTE]
====
Шаги, описанные в этой части статьи, необходимо выполнить лишь в том случае, если Apache настроен сохранять свой pid или журнал вне каталога [.filename]#/var#. С настройками по умолчанию Apache формирует свой pid файл в [.filename]#/var/run/httpd.pid#, а файлы журналов - в [.filename]#/var/log#.
====

Далее в статье подразумевается, что Apache сохраняет свои файлы журналов в каталог [.filename]#apache_log_dir# вне каталога [.filename]#/var#. Когда этот каталог расположен на файловой системе, смонтированной в режиме только для чтения, Apache не сможет сохранять файлы журналов, что в свою очередь может вызывать проблемы в работе веб-сервера. В таком случае необходимо добавить новый каталог к списку каталогов из [.filename]#/etc/rc.d/var# для их создания в каталоге [.filename]#/var# и связать [.filename]#apache_log_dir# с [.filename]#/var/log/apache#. Нужно также задать права доступа и владельца нового каталога.

Сначала добавьте каталог `log/apache` к списку каталогов, создаваемых скриптом [.filename]#/etc/rc.d/var#.

Затем добавьте в скрипт [.filename]#/etc/rc.d/var# после секции создания каталогов такие команды:

[source, shell]
....
# chmod 0774 /var/log/apache
# chown nobody:nobody /var/log/apache
....

И наконец, удалите существующий каталог [.filename]#apache_install/logs# и замените его ссылкой:

[source, shell]
....
# rm -rf apache_log_dir
# ln -s /var/log/apache apache_log_dir
....
