---
authors:
  - 
    author: 'Daniel Gerzo'
copyright: '2006 The FreeBSD Documentation Project'
description: 'Этот документ предоставляет информацию об инструментах NanoBSD, которые могут быть использованы для создания образов системы FreeBSD для встраиваемых приложений, подходящих для использования на USB-накопителе, карте памяти или других носителях данных.'
tags: ["nanobsd", "guide", "embedded", "FreeBSD"]
title: 'Введение в NanoBSD'
trademarks: ["freebsd", "general"]
---

= Введение в NanoBSD
:doctype: article
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:source-highlighter: rouge
:experimental:
:images-path: articles/nanobsd/

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]
Аннотация

Этот документ предоставляет информацию об инструментах NanoBSD, которые могут быть использованы для создания образов системы FreeBSD для встраиваемых приложений, подходящих для использования на USB-накопителе, карте памяти или других носителях данных.

'''

toc::[]

[[intro]]
== Введение в NanoBSD

NanoBSD — это инструмент, разработанный {phk} и в настоящее время поддерживаемый {imp}. Он создает образ системы FreeBSD для встраиваемых приложений, подходящий для использования на USB-накопителе, карте памяти или другом носителе данных.

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

Возможности NanoBSD включают:

* Порты и пакеты работают так же, как в FreeBSD — любое приложение может быть установлено и использовано в образе NanoBSD так же, как и в FreeBSD.
* Отсутствие недостающей функциональности — если что-то возможно сделать в FreeBSD, то это же можно сделать и в NanoBSD, за исключением случаев, когда определённые функции были явно удалены из образа NanoBSD при его создании.
* Всё доступно только для чтения во время работы — можно безопасно выдернуть шнур питания. Нет необходимости запускать man:fsck[8] после нештатного завершения работы системы.
* Простота сборки и настройки — используя всего один shell-скрипт и один файл конфигурации, можно создавать уменьшенные и настроенные образы, удовлетворяющие любым произвольным требованиям.

[[howto]]
== Инструкция по NanoBSD

[[design]]
=== Дизайн NanoBSD

После того как образ записан на носитель, можно загрузить NanoBSD. По умолчанию носитель данных разделён на три части:

* Два раздела с образами: `code#1` и `code#2`.
* Файловый раздел конфигурации, который может быть смонтирован в каталоге [.filename]#/cfg# во время выполнения.

Эти разделы обычно монтируются в режиме только для чтения.

Каталоги [.filename]#/etc# и [.filename]#/var# являются дисками man:md[4] (malloc).

Раздел конфигурации сохраняется в каталоге [.filename]#/cfg#. Он содержит файлы для каталога [.filename]#/etc# и кратковременно монтируется в режиме только для чтения сразу после загрузки системы, поэтому необходимо копировать изменённые файлы из [.filename]#/etc# обратно в каталог [.filename]#/cfg#, если требуется, чтобы изменения сохранялись после перезагрузки системы.

.Внесение постоянных изменений в [.filename]#/etc/resolv.conf#
[example]
====

[source, shell]
....
# vi /etc/resolv.conf
[...]
# mount /cfg
# cp /etc/resolv.conf /cfg
# umount /cfg
....

====

[NOTE]
====
Раздел, содержащий [.filename]#/cfg#, должен монтироваться только во время загрузки и при переопределении конфигурационных файлов.

Постоянное подключение [.filename]#/cfg# не является хорошей идеей, особенно если Система NanoBSD работает на носителе данных, который может быть повреждён из-за большого количества операций записи в раздел (например, когда синхронизатор файловой системы записывает данные на системные диски).
====

=== Создание образа NanoBSD

Для сборки NanoBSD необходим исходный код FreeBSD. Чтобы получить исходный код:

[source, shell]
....
# git clone https://git.FreeBSD.org/src.git /usr/src
....

Для более подробной информации выполните шаги, описанные extref:{handbook}cutting-edge#updating-src-obtaining-src[здесь].

Образ NanoBSD создаётся с помощью простого скрипта [.filename]#nanobsd.sh#, который находится в каталоге [.filename]#/usr/src/tools/tools/nanobsd#. Этот скрипт создаёт образ, который можно записать на носитель с помощью утилиты man:dd[1].

Необходимые команды для создания образа NanoBSD:

[source, shell]
....
# cd /usr/src/tools/tools/nanobsd <.>
# sh nanobsd.sh <.>
# cd /usr/obj/nanobsd.full <.>
# dd if=_.disk.full of=/dev/da0 bs=64k <.>
....

<.> Измените текущий каталог на базовый каталог скрипта сборки NanoBSD.

<.> Начните процесс сборки.

<.> Измените текущий каталог на место, где расположены собранные образы.

<.> Установите NanoBSD на носитель данных.

==== Параметры при сборке образа NanoBSD

При создании образа NanoBSD можно передать несколько параметров сборки в [.filename]#nanobsd.sh# через командную строку. Эти параметры могут существенно повлиять на процесс сборки.

Некоторые параметры предназначены для информирования в большем или меньшем объеме:

* `-h`: выводит страницу с краткой справкой.
* `-q`: делает вывод менее подробным.
* `-v`: делает вывод более подробным

Некоторые другие параметры могут использоваться для ограничения процесса сборки. Иногда нет необходимости пересобирать всё из исходников, особенно если образ уже был собран и внесены лишь небольшие изменения.

* `-k`: не собирать ядро
* `-w`: не собирать world
* `-b`: не собирать ни ядро, ни систему
* `-i`: не создавать образ диска. Поскольку файл не будет создан, его нельзя будет записать на носитель с помощью man:dd[1].
* `-f`: не создавать образ диска первого раздела (что полезно для целей обновления)
* `-n`: добавляет `-DNO_CLEAN` к `buildworld`, `buildkernel`. Кроме того, все файлы, которые уже были собраны в предыдущем запуске, сохраняются.

Файл конфигурации можно использовать для настройки множества элементов. Загрузите его с помощью `-c`

Последние параметры:

* `-K`: не устанавливать ядро. Образ диска без ядра не сможет выполнить нормальную последовательность загрузки.

==== Полный процесс сборки образа

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

. `run_early_customize`: команды, определенные в предоставленном файле конфигурации.
. `clean_build`: Просто очищает среду сборки, удаляя ранее созданные файлы.
. `make_conf_build`: Собрать make.conf из переменных `CONF_WORLD` и `CONF_BUILD`.
. `build_world`: Сборка системы.
. `build_kernel`: Собрать файлы ядра.
. `clean_world`: Очистить целевую директорию.
. `make_conf_install`: Собрать make.conf из переменных `CONF_WORLD` и `CONF_INSTALL`.
. `install_world`: Установить все файлы, собранные во время `buildworld`.
. `install_etc`: Установить необходимые файлы в директорию [.filename]#/etc#, используя команду `make distribution`.
. `setup_nanobsd_etc`: на этом этапе происходит первая специфичная для NanoBSD настройка. Создается [.filename]#/etc/diskless#, а корневая файловая система определяется как доступная только для чтения.
. `install_kernel`: устанавливаются файлы ядра и модулей.
. `run_customize`: будут вызваны все пользовательские процедуры настройки.
. `setup_nanobsd`: создаётся специальная структура конфигурационных каталогов. Каталог [.filename]#/usr/local/etc# перемещается в [.filename]#/etc/local#, а затем создаётся символическая ссылка из [.filename]#/etc/local# обратно в [.filename]#/usr/local/etc#.
. `prune_usr`: пустые директории в [.filename]#/usr# удаляются.
. `run_late_customize`: на этом этапе могут быть выполнены самые последние пользовательские скрипты.
. `fixup_before_diskimage`: Вывести список всех установленных файлов в metalog
. `create_diskimage`: создает образ диска на основе предоставленных параметров геометрии диска.
. `last_orders`: в настоящее время ничего не делает.

=== Настройка образа NanoBSD

Вероятно, это самая важная и интересная функция NanoBSD. Здесь же вы проведёте большую часть времени при разработке с NanoBSD.

Вызов следующей команды заставит [.filename]#nanobsd.sh# прочитать конфигурацию из файла [.filename]#myconf.nano#, расположенного в текущем каталоге:

[source, shell]
....
# sh nanobsd.sh -c myconf.nano
....

Настройка выполняется двумя способами:

* Параметры конфигурации
* Пользовательские функции

==== Параметры конфигурации

С помощью настроек конфигурации можно задать параметры, передаваемые как на этапах `buildworld`, так и `installworld` процесса сборки NanoBSD, а также внутренние параметры, передаваемые основному процессу сборки NanoBSD. Эти параметры позволяют сократить систему так, чтобы она помещалась всего на 64 МБ. Вы можете использовать конфигурационные опции для ещё большего урезания FreeBSD, пока она не будет состоять только из ядра и двух-трёх файлов в пользовательском пространстве.

Файл конфигурации состоит из параметров конфигурации, которые переопределяют значения по умолчанию. Наиболее важные директивы:

* `NANO_NAME` - Имя сборки (используется для формирования имен рабочих каталогов).
* `NANO_SRC` - Путь к исходному дереву, используемому для сборки образа.
* `NANO_KERNEL` - Имя файла конфигурации ядра, используемого для сборки ядра.
* `CONF_BUILD` - Параметры, передаваемые на этапе `buildworld` сборки.
* `CONF_INSTALL` - Параметры, передаваемые на этапе `installworld` при сборке.
* `CONF_WORLD` - Параметры, передаваемые на этапах `buildworld` и `installworld` сборки.
* `FlashDevice` - Определяет тип носителя для использования. Подробности смотрите в [.filename]#FlashDevice.sub#.

Существует множество дополнительных параметров конфигурации, которые могут быть актуальными в зависимости от типа NanoBSD.

===== Общая настройка

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

* `run_early_customize`: до выполнения любых других действий.
* `run_customize`: после того как все стандартные файлы будут размещены
* `run_late_customize`: в самом конце процесса, непосредственно перед созданием фактического образа NanoBSD.

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

Переменная `NANO_EARLY_CUSTOMIZE` используется на первом этапе процесса сборки. На данный момент нет примера того, что можно сделать с помощью этой переменной, но это может измениться в будущем.

Переменная `NANO_CUSTOMIZE` используется после установки ядра, системы и конфигурационных файлов etc, а также настройки файлов etc для установки NanoBSD. Таким образом, это правильный этап процесса сборки для изменения параметров конфигурации и добавления пакетов, как в примере cust_nobeastie.

Переменная `NANO_LATE_CUSTOMIZE` используется непосредственно перед созданием образа диска, поэтому это последний момент для внесения изменений. Помните, что процедура `setup_nanobsd` уже выполнена и каталоги [.filename]#etc#, [.filename]#conf# и [.filename]#cfg#, включая подкаталоги, уже изменены, поэтому сейчас не время их корректировать. Вместо этого можно добавить или удалить конкретные файлы.

===== Параметры загрузки

Существуют также переменные, которые могут изменить способ загрузки образа NanoBSD. Два параметра передаются в man:boot0cfg[8] для инициализации загрузочного сектора образа диска:

* `NANO_BOOT0CFG`
* `NANO_BOOTLOADER`

С помощью `NANO_BOOTLOADER` можно выбрать файл загрузчика. Наиболее распространённые варианты — [.filename]#boot0sio# и [.filename]#boot0#, в зависимости от наличия последовательного порта у устройства. Лучше не указывать другой загрузчик, но это возможно. Для этого рекомендуется предварительно ознакомиться с extref:{handbook}boot[главой FreeBSD Handbook] о процессе загрузки.

С помощью `NANO_BOOT0CFG` можно настроить процесс загрузки, например, выбрать раздел, с которого будет загружаться образ NanoBSD. Перед изменением значения этой переменной рекомендуется ознакомиться со страницей руководства man:boot0cfg[8]. Один из интересных параметров, который можно изменить, — это таймаут процедуры загрузки. Для этого переменную `NANO_BOOT0CFG` можно изменить на `"-o packet -s 1 -m 3 -t 36"`. В этом случае процесс загрузки начнётся примерно через 2 секунды, так как редко возникает необходимость ждать 10 секунд перед началом загрузки.

Хорошо знать: переменная `NANO_BOOT2CFG` используется только в подпрограмме `cust_comconsole`, которая может вызываться на этапе `NANO_CUSTOMIZE`, если устройство имеет последовательный порт и весь ввод и вывод консоли должен осуществляться через него. Обязательно проверьте соответствующие параметры последовательного порта, так как установка некорректного значения параметра может сделать его бесполезным.

===== Создание образа диска

В конце процесса загрузки происходит создание образа диска. На этом этапе скрипт NanoBSD предоставляет файл, который можно просто скопировать на диск для устройства, и это позволит ему загрузиться и запуститься.

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

* Переменная `NANO_DRIVE` должна быть установлена в имя накопителя носителя во время выполнения. Обычно ожидается, что значение по умолчанию `ada0`, которое представляет первое устройство `IDE`/`ATA`/`SATA` на устройстве, будет правильным, но также может использоваться другой тип накопителя — например, USB-ключ, в этом случае это скорее будет `da0`.
* Переменная `NANO_MEDIASIZE` должна быть установлена в значение размера (в секторах по 512 байт) носителя данных, который будет использоваться. Если задать её неправильно, образ NanoBSD может вообще не загрузиться, а во время загрузки появится сообщение о некорректной геометрии диска.

* Каталоги [.filename]#/etc#, [.filename]#/var# и [.filename]#/tmp# выделяются как диски man:md[4] (malloc) при загрузке; их размеры могут быть настроены в соответствии с потребностями устройства. Переменная `NANO_RAM_ETCSIZE` задаёт размер [.filename]#/etc#, а переменная `NANO_RAM_TMPVARSIZE` определяет размер как [.filename]#/var#, так и [.filename]#/tmp#, поскольку [.filename]#/tmp# символически ссылается на [.filename]#/var/tmp#. По умолчанию размер обоих дисков malloc установлен в 20 МБ каждый. Их можно изменить, но обычно [.filename]#/etc# не сильно увеличивается в размере, поэтому 20 МБ — хорошая начальная точка, тогда как [.filename]#/var# и особенно [.filename]#/tmp# могут стать значительно больше, если не следить за ними. Для систем с ограниченной памятью можно выбрать меньшие размеры файловых систем.
* Поскольку NanoBSD в основном предназначен для создания образа системы для устройства, предполагается, что используемые носители данных будут относительно небольшими. По этой причине файловая система настроена на использование небольшого размера блока (4 Кб) и небольшого размера фрагмента (512 байт). Параметры конфигурации файловой системы можно изменить с помощью переменной `NANO_NEWFS`, но синтаксис должен соответствовать формату команды man:newfs[8]. Кроме того, по умолчанию в файловой системе включены Soft Updates. Подробнее об этом можно узнать в extref:{handbook}[FreeBSD Handbook].
* Различные размеры разделов могут быть заданы с использованием `NANO_CODESIZE`, `NANO_CONFSIZE` и `NANO_DATASIZE` в виде кратного 512-байтным секторам. `NANO_CODESIZE` определяет размер первых двух разделов образа: `code#1` и `code#2`. Они должны быть достаточно большими, чтобы вместить все файлы, созданные в результате процессов `buildworld` и `buildkernel`. `NANO_CONFSIZE` определяет размер раздела для конфигурационных файлов, поэтому он не должен быть очень большим; однако не стоит делать его слишком маленьким, чтобы он мог вместить все конфигурационные файлы. Наконец, `NANO_DATASIZE` определяет размер дополнительного раздела, который может использоваться на устройстве. Последний раздел может быть использован, например, для хранения файлов, создаваемых на лету на диске.

==== Пользовательские Функции

Возможно тонко настроить NanoBSD с помощью функций оболочки в конфигурационном файле. Следующий пример иллюстрирует базовую модель пользовательских функций:

[.programlisting]
....
cust_foo () (
	echo "bar=baz" > \
		${NANO_WORLDDIR}/etc/foo
)
customize_cmd cust_foo
....

Более полезный пример функции настройки — следующий, который изменяет размер каталога [.filename]#/etc# по умолчанию с 5 МБ на 30 МБ:

[.programlisting]
....
cust_etc_size () (
	cd ${NANO_WORLDDIR}/conf
	echo 30000 > default/etc/md_size
)
customize_cmd cust_etc_size
....

Существует несколько предопределённых функций для настройки, готовых к использованию:

* `cust_comconsole` - Отключает man:getty[8] на VGA-устройствах (узлы устройств [.filename]#/dev/ttyv*#) и позволяет использовать последовательный порт COM1 в качестве системной консоли.
* `cust_allow_ssh_root` - Разрешить `root` входить через man:sshd[8].
* `cust_install_files` - Устанавливает файлы из каталога [.filename]#nanobsd/Files#, который содержит полезные скрипты для администрирования системы.
* `cust_pkgng` - Устанавливает пакеты из каталога [.filename]#nanobsd/Pkg# (также требуется пакет pkg-* для начальной загрузки).

==== Добавление пакетов

Пакеты могут быть добавлены в образ NanoBSD для обеспечения специфических функциональных возможностей устройства. Для этого можно:

* Добавьте `cust_pkgng` в переменную `NANO_CUSTOMIZE` или
* Добавьте команду `'customize_cmd cust_pkgng'` в настраиваемый конфигурационный файл.

Оба метода приводят к одному результату: запуск процедуры `cust_pkgng`. Эта процедура проверит каталог `NANO_PACKAGE_DIR` для поиска всех пакетов или только списка пакетов, указанных в переменной `NANO_PACKAGE_LIST`.

Обычно при установке приложений через pkg в стандартной среде FreeBSD процесс установки размещает конфигурационные файлы в каталоге [.filename]#usr/local/etc#, а скрипты запуска — в каталоге [.filename]#/usr/local/etc/rc.d#. Поэтому после установки необходимых пакетов их нужно настроить, чтобы они запускались сразу после установки. Для этого необходимо разместить соответствующие конфигурационные файлы в правильных каталогах. Это можно сделать, написав специализированные процедуры, или использовать общую процедуру `cust_install_files` для корректного размещения файлов из каталога [.filename]#/usr/src/tools/tools/nanobsd/Files#. Обычно также требуется добавить одну или несколько записей в файл [.filename]#/etc/rc.conf# для каждого пакета.

==== Пример файла конфигурации

Полный пример конфигурационного файла для создания пользовательского образа NanoBSD может выглядеть следующим образом:

[.programlisting]
....
NANO_NAME=custom
NANO_SRC=/usr/src
NANO_KERNEL=MYKERNEL
NANO_IMAGES=2

CONF_BUILD='
WITHOUT_KLDLOAD=YES
WITHOUT_NETGRAPH=YES
WITHOUT_PAM=YES
'

CONF_INSTALL='
WITHOUT_ACPI=YES
WITHOUT_BLUETOOTH=YES
WITHOUT_FORTRAN=YES
WITHOUT_HTML=YES
WITHOUT_LPR=YES
WITHOUT_MAN=YES
WITHOUT_SENDMAIL=YES
WITHOUT_SHAREDOCS=YES
WITHOUT_EXAMPLES=YES
WITHOUT_INSTALLLIB=YES
WITHOUT_CALENDAR=YES
WITHOUT_MISC=YES
WITHOUT_SHARE=YES
'

CONF_WORLD='
WITHOUT_BIND=YES
WITHOUT_MODULES=YES
WITHOUT_KERBEROS=YES
WITHOUT_GAMES=YES
WITHOUT_RESCUE=YES
WITHOUT_LOCALES=YES
WITHOUT_SYSCONS=YES
WITHOUT_INFO=YES
'

FlashDevice SanDisk 1G

cust_nobeastie() (
	touch ${NANO_WORLDDIR}/boot/loader.conf
	echo "beastie_disable=\"YES\"" >> ${NANO_WORLDDIR}/boot/loader.conf
)

customize_cmd cust_comconsole
customize_cmd cust_install_files
customize_cmd cust_allow_ssh_root
customize_cmd cust_nobeastie
....

Все параметры сборки и установки можно найти на странице Справочника man:src.conf[5], но не все параметры можно или следует использовать при создании образа NanoBSD. Параметры сборки и установки должны определяться в соответствии с потребностями создаваемого образа.

Например, FTP-клиент и сервер могут не потребоваться. Добавление `WITHOUT_FTP=TRUE` в файл конфигурации в разделе `CONF_BUILD` позволит избежать их сборки. Также, если устройство NanoBSD не будет использоваться для сборки программ, можно добавить `WITHOUT_BINUTILS=TRUE` в раздел `CONF_INSTALL`, но не в раздел `CONF_BUILD`, так как они будут использоваться для сборки образа NanoBSD.

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

=== Обновление NanoBSD

Процесс обновления NanoBSD относительно прост:

[.procedure]
====
. Соберите новый образ NanoBSD, как обычно.
. Загрузите новый образ в неиспользуемый раздел работающего устройства NanoBSD.
+
Важнейшее отличие этого шага от первоначальной установки NanoBSD заключается в том, что теперь вместо использования [.filename]#\_.disk.full# (который содержит образ всего диска), устанавливается образ [.filename]#_.disk.image# (который содержит образ одного системного раздела).
. Перезагрузите систему и запустите её с только что установленного раздела.
. Если все прошло успешно, обновление завершено.
. Если что-то пойдет не так, перезагрузитесь обратно в предыдущий раздел (который содержит старую, рабочую версию), чтобы восстановить работоспособность системы как можно быстрее. Исправьте все проблемы новой сборки и повторите процесс.
====

Для установки нового образа на работающую систему NanoBSD можно использовать скрипт [.filename]#updatep1# или [.filename]#updatep2#, расположенный в директории [.filename]#/root#, в зависимости от того, с какого раздела запущена текущая система.

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

==== Использование man:ftp[1]

Если скорость передачи данных стоит на первом месте, используйте этот пример:

[source, shell]
....
# ftp myhost
get _.disk.image "| sh updatep1"
....

==== Использование man:ssh[1]

Если предпочтителен безопасный способ передачи, рассмотрите следующий пример:

[source, shell]
....
# ssh myhost cat _.disk.image.gz | zcat | sh updatep1
....

==== Использование man:nc[1]

Попробуйте этот пример, если на удалённом хосте не запущены ни служба man:ftpd[8], ни служба man:sshd[8]:

[.procedure]
====
. Сначала откройте TCP-слушатель на хосте, обслуживающем образ, и настройте его на отправку образа клиенту:
+
[source, shell]
....
myhost# nc -l 2222 < _.disk.image
....
+
[NOTE]
======
Убедитесь, что используемый порт не заблокирован для приёма входящих подключений с хоста NanoBSD межсетевым экраном.
======
. Подключитесь к хосту, предоставляющему новый образ, и выполните скрипт [.filename]#updatep1#:
+
[source, shell]
....
# nc myhost 2222 | sh updatep1
....
====
