articles/nanobsd: Add section on customizing NanoBSD

nanobsd.sh can be passed several options, and having this documented is
a good idea, as it even includes the ability to customize the
third-party software on the NanoBSD image.

While here, fix up some uses of applications tags, and some incorrect
capitalization.

Submitted by:	Yoan Adida <yoanadida at gmail.com> (previous version)
Reviewed by:	bcr, imp, wblock (some of an earlier version),
Mina Galić <me@igalic.co>, PauAmma
Differential Revision:	https://reviews.freebsd.org/D7406
This commit is contained in:
Yoan Adida 2021-01-17 11:55:07 +01:00 committed by Daniel Ebdrup Jensen
parent 0d4371e5cc
commit f2a33a330d

View file

@ -28,8 +28,8 @@
<para>This document provides information about the
<application>NanoBSD</application> tools, which can be used to
create &os; system images for embedded applications, suitable
for use on a Compact Flash card (or other mass storage
medium).</para>
for use on a USB key, memory card or other mass
storage media.</para>
</abstract>
</info>
@ -38,10 +38,11 @@
<indexterm><primary>NanoBSD</primary></indexterm>
<para><application>NanoBSD</application> is a tool currently
developed by &a.phk.email;. It creates a &os; system image for
embedded applications, suitable for use on a Compact Flash card
(or other mass storage medium).</para>
<para><application>NanoBSD</application> is a tool developed by
&a.phk.email; and now maintained by &a.imp.email;. It
creates a &os; system image for embedded applications,
suitable for use on a USB key, memory card or other mass
storage media.</para>
<para>It can be used to build specialized install images, designed
for easy installation and maintenance of systems commonly called
@ -190,6 +191,148 @@
storage medium.</para>
</callout>
</calloutlist>
<sect3>
<title>Options When Building a NanoBSD Image</title>
<para>When building a <application>NanoBSD</application>
image, several build options can be passed to
<filename>nanobsd.sh</filename> on the
command line. These options can have a significant
impact on the build process.</para>
<para>Some options are for verbosity purposes:</para>
<itemizedlist>
<listitem>
<para><literal>-h</literal>: prints the help
summary page.</para>
</listitem>
<listitem>
<para><literal>-q</literal>: makes output quieter.</para>
</listitem>
<listitem>
<para><literal>-v</literal>: makes output more
verbose</para>
</listitem>
</itemizedlist>
<para>Some other options can be used to restrict the
building process. Sometimes it is not necessary to
rebuild everything from sources, especially if an
image has already been built, and only little change
is made.</para>
<itemizedlist>
<listitem>
<para><literal>-k</literal>: do not build the
kernel</para>
</listitem>
<listitem>
<para><literal>-w</literal>: do not build world</para>
</listitem>
<listitem>
<para><literal>-b</literal>: do not build either
kernel and world</para>
</listitem>
<listitem>
<para><literal>-i</literal>: do not build a disk
image at all. As a file will not be created, it
will not be possible to &man.dd.1; it to a
storage media.</para>
</listitem>
<listitem>
<para><literal>-f</literal>: do not build a disk
image of the first partition (which is useful for
upgrade purposes)</para>
</listitem>
<listitem>
<para><literal>-n</literal>: add <literal>-DNO_CLEAN</literal>
to <buildtarget>buildworld</buildtarget>,
<buildtarget>buildkernel</buildtarget>. Also,
all the files that have already been built in a
previous run are kept.</para>
</listitem>
</itemizedlist>
<para>A configuration file can be used to tweak as
many elements as desired. Load it with <option>-c</option></para>
<para>The last options are:</para>
<itemizedlist>
<listitem>
<para><literal>-K</literal>: do not install a kernel.
A disk image without a kernel will not be able
to achieve a normal boot sequence.
</para>
</listitem>
</itemizedlist>
</sect3>
<sect3>
<title>The Complete Image Building Process</title>
<para>The complete image building process is going through
a lot of steps. The exact steps taken will depend on the
chosen options when starting the script. Assuming the
script is run with no particular options, this is what
will happen.</para>
<orderedlist>
<listitem><para><literal>run_early_customize</literal>:
commands that are defined in a supplied configuration
file.</para></listitem>
<listitem><para><literal>clean_build</literal>: Just cleans
the build environment by deleting the previously built files.</para></listitem>
<listitem><para><literal>make_conf_build</literal>: Assemble
make.conffrom the <literal>CONF_WORLD</literal> and
<literal>CONF_BUILD</literal> variables.</para></listitem>
<listitem><para><literal>build_world</literal>: Build world.</para></listitem>
<listitem><para><literal>build_kernel</literal>: Build the
kernel files.</para></listitem>
<listitem><para><literal>clean_world</literal>: Clean the
destination directory.</para></listitem>
<listitem><para><literal>make_conf_install</literal>:
Assemble make.conf from the <literal>CONF_WORLD</literal>
and <literal>CONF_INSTALL</literal> variables.</para></listitem>
<listitem><para><literal>install_world</literal>: Install
all files built during <buildtarget>buildworld</buildtarget>.</para></listitem>
<listitem><para><literal>install_etc</literal>: Install
the necessary files in the <filename>/etc</filename>
directory, based on the <literal>make distribution</literal>
command.</para></listitem>
<listitem><para><literal>setup_nanobsd_etc</literal>: the
first configuration specific to <application>NanoBSD</application>
takes place at this stage. The <filename>/etc/diskless</filename> is
created and the root filesystem is defined as read-only.</para></listitem>
<listitem><para><literal>install_kernel</literal>: the
kernel and modules files are installed.</para></listitem>
<listitem><para><literal>run_customize</literal>: all
the customizing routines defined by the user will be called.</para></listitem>
<listitem><para><literal>setup_nanobsd</literal>: a special
configuration directory layout is setup. The
<filename>/usr/local/etc</filename> gets moved to
<filename>/etc/local</filename> and a symbolic link is
created back from <filename>/etc/local</filename> to
<filename>/usr/local/etc</filename>.</para></listitem>
<listitem><para><literal>prune_usr</literal>: the empty
directories from <filename>/usr</filename> are removed.</para></listitem>
<listitem><para><literal>run_late_customize</literal>:
the very last custom scripts can be run at this point.</para></listitem>
<listitem><para><literal>fixup_before_diskimage</literal>:
List all installed files in a metalog</para></listitem>
<listitem><para><literal>create_diskimage</literal>: creates
the actual disk image, based on the disk geometries provides
parameters.</para></listitem>
<listitem><para><literal>last_orders</literal>: does nothing
for now.</para></listitem>
</orderedlist>
</sect3>
</sect2>
<sect2>
@ -280,6 +423,184 @@
details.</para>
</listitem>
</itemizedlist>
<para>There are many more configuration options that could
be relevant depending upon the kind of
<application>NanoBSD</application> that is desired.</para>
<sect4>
<title>General Customization</title>
<para>There are three stages, by design, at which
it is possible to make changes that affect the
building process, just by setting up a variable in the
provided configuration file:</para>
<itemizedlist>
<listitem><para><literal>run_early_customize</literal>:
before anything else happens.</para></listitem>
<listitem><para><literal>run_customize</literal>: after all
the standard files have been laid out</para></listitem>
<listitem><para><literal>run_late_customize</literal>: at
the very end of the process, just before the actual
<application>NanoBSD</application> image is built.</para>
</listitem>
</itemizedlist>
<para>To customize a <application>NanoBSD</application> image, at any of these steps,
it is best to add a specific value to one of the corresponding
variables.</para>
<para>The <literal>NANO_EARLY_CUSTOMIZE</literal> variable is
used at the first step of the building process. At this point,
there is no example as to what can be done using that variable,
but it may change in the future.</para>
<para>The <literal>NANO_CUSTOMIZE</literal> variable is used
after the kernel, world and etc configuration files have been
installed, and the etc files have been setup as to be a
NanoBSD installation. So it is the correct step in the
building process to tweak configuration options and add
packages, like in the cust_nobeastie example.</para>
<para>The <literal>NANO_LATE_CUSTOMIZE</literal> variable is
used just before the disk image is created, so it is the very
last moment to change anything. Remember that the
<literal>setup_nanobsd</literal> routine already executed and
that the <filename>etc</filename>, <filename>conf</filename>
and <filename>cfg</filename>directories and subdirectories are
already modified, so it is not time to change them at this
point. Rather, it is possible to add or remove specific files.</para>
</sect4>
<sect4>
<title>Booting Options</title>
<para>There are also variables that can change the way the
NanoBSD image boots. Two options are passed to
&man.boot0cfg.8; to initialize the boot sector of the disk image:</para>
<itemizedlist>
<listitem><para><literal>NANO_BOOT0CFG</literal></para></listitem>
<listitem><para><literal>NANO_BOOTLOADER</literal></para></listitem>
</itemizedlist>
<para>With <literal>NANO_BOOTLOADER</literal> a bootloader
file can be chosen. The most common possible options are between
<filename>boot0sio</filename> and <filename>boot0</filename>
depending on whether the appliance has a serial port or not. It is best
to avoid supplying a different bootloader, but it is possible.
To do so, it is best to have checked the
<link xlink:href="&url.books.handbook;/boot.html">&os; Handbook</link>
chapter on the boot process.</para>
<para>With <literal>NANO_BOOT0CFG</literal>, the booting
process can be tweaked, like selecting on which partition the
<application>NanoBSD</application> image will actually boot.
It is best to check the &man.boot0cfg.8; page before changing
the default value of this variable. One option that could be
interesting to change is the timeout of the booting procedure.
To do so, the <literal>NANO_BOOT0CFG</literal> variable can be
changed to <literal>"-o packet -s 1 -m 3 -t 36"</literal>.
That way the booting process would start after approximately 2
seconds; because it is rare that waiting 10 seconds before
actually booting is desired.</para>
<para>Good to know: the <literal>NANO_BOOT2CFG</literal>
variable is only used in the <literal>cust_comconsole</literal>
routine that can be called at the
<literal>NANO_CUSTOMIZE</literal> step if the appliance has a
serial port and all console input and output has to take place through
it. Be sure to check the relevant parameters of the serial
port, as setting a bad parameter value can make it useless.</para>
</sect4>
<sect4>
<title>Disk Image Creation</title>
<para>In the end of the boot process is the disk image
creation. With this step, the <application>NanoBSD</application>
script provides a file that can simply be copied onto a disk
for the appliance, and that will make it boot and start.</para>
<para>There are many variable that need to be set just right
for the script to produce a usable disk image.</para>
<itemizedlist>
<listitem>
<para>The <literal>NANO_DRIVE</literal> variable must be set
to the drive name of the media at runtime. Usually, the
default value <literal>ada0</literal>, which represents the first
<literal>IDE</literal>/<literal>ATA</literal>/<literal>SATA</literal>
device on the appliance is expected to be the correct one, but
a different type of storage could also be used - like a USB
key, in which case, it would rather be da0.</para>
</listitem>
<listitem>
<para>The <literal>NANO_MEDIASIZE</literal> variable must be
set to the size (in 512 bytes sectors) of the storage media
that will be used. If you set it wrong, it is possible that
the <application>NanoBSD</application> image will not boot
at all, and a message at boot time will be warning about
incorrect disk geometry.</para>
</listitem>
</itemizedlist>
<itemizedlist>
<listitem>
<para>The <filename>/etc</filename>, <filename>/var</filename>,
and <filename>/tmp</filename> directories are allocated as
&man.md.4; (malloc) disks at boot time; so their sizes can be
tailored to suit the appliance needs. The <literal>NANO_RAM_ETCSIZE</literal>
variable sets the size of the <filename>/etc</filename>; and the
<literal>NANO_RAM_TMPVARSIZE</literal> variable sets the size of
both the <filename>/var</filename> and <filename>/tmp</filename>
directory, as <filename>/tmp</filename> is symbolically linked to
<filename>/var/tmp</filename>. By default, both malloc disks
sizes are set at 20MB each. They can always be changed, but
usually the <filename>/etc</filename> does not grow too much
in size, so 20MB is a good starting point, whereas the
<filename>/var</filename> and especially <filename>/tmp</filename>
can grow much larger if not careful about it. For
memory constrained systems, smaller filesystem sizes
may be chosen.
</para>
</listitem>
<listitem>
<para>As <application>NanoBSD</application> is
mainly designed to build a system image for an
appliance, it is assumed that the storage media used
will be relatively small. For that reason,
the filesystem that is laid out is configured to have
a small block size (4Kb) and a small fragment size (512b).
The configuration options of the filesystem can be
modified through the <literal>NANO_NEWFS</literal>
variable, but the syntax must respect the
&man.newfs.8; command format. Also, by default, the
filesystem has Soft Updates enabled. The
<link xlink:href="&url.books.handbook;">&os; Handbook</link>
can be checked about this.</para>
</listitem>
<listitem>
<para>The different partition sizes can be set through the
use of <literal>NANO_CODESIZE</literal>,
<literal>NANO_CONFSIZE</literal>, and <literal>NANO_DATASIZE</literal>
as a multiple of 512 bytes sectors.
<literal>NANO_CODESIZE</literal> defines the size of the first
two image partitions: <literal>code#1</literal> and
<literal>code#2</literal>. They have to be big enough to hold
all the files that will be produced as a result of the
<literal>buildworld</literal> and <literal>buildkernel</literal>
processes. <literal>NANO_CONFSIZE</literal> defines the size
of the configuration file partition, so it does not need to be
very big; but do not make it so small that it will not hold all
configuration files. Finally, <literal>NANO_DATASIZE</literal>
defines the size of an optional partition, that can be used
on the appliance. The last partition can be used,
for example, to keep files created on the fly on disk.</para>
</listitem>
</itemizedlist>
</sect4>
</sect3>
<sect3>
@ -337,20 +658,43 @@ customize_cmd cust_etc_size</programlisting>
<sect3>
<title>Adding Packages</title>
<para>Packages can be added to a
<application>NanoBSD</application> image using a custom
function. The following function will install all the
packages located in
<filename>/usr/src/tools/tools/nanobsd/packages</filename>:</para>
<para>Packages can be added to a <application>NanoBSD</application>
image, to provide specific functionalities on the
appliance. To do so, either:</para>
<itemizedlist>
<listitem>
<para>Add the <literal>cust_pkgng</literal> to the
<literal>NANO_CUSTOMIZE</literal> variable, or</para>
</listitem>
<listitem>
<para>Add a <literal>'customize_cmd cust_pkgng'</literal>
command in a customized configuration file.</para>
</listitem>
</itemizedlist>
<para>Both methods achieve the same result: launching
the <literal>cust_pkgng</literal> routine. This routine
will go through <literal>NANO_PACKAGE_DIR</literal>
directory to find either all packages or just the list of
packages in the <literal>NANO_PACKAGE_LIST</literal> variable.</para>
<para>It is common, when installing applications through
pkg on a standard &os; environment, that the install
process puts configuration files, in the
<filename>usr/local/etc</filename> directory, and
startup scripts in the <filename>/usr/local/etc/rc.d</filename>
directory. So, after the required packages have been
installed, they need to be configured in order
for them to start right out of the box. To do so,
the necessary configuration files have to be installed in the
correct directories. This can be achieved by writing
dedicated routines or the generic <literal>cust_install_files</literal>
routine can be used to lay out files properly from the
<filename><replaceable>/usr</replaceable>/src/tools/tools/nanobsd/Files</filename> directory.
Usually a statement, sometimes multiple statements,
in the <filename>/etc/rc.conf</filename> also needs to be
added for each package.</para>
<programlisting>install_packages () (
mkdir -p ${NANO_WORLDDIR}/packages
cp /usr/src/tools/tools/nanobsd/packages/* ${NANO_WORLDDIR}/packages
cp $(which pkg-static) ${NANO_WORLDDIR}/
chroot ${NANO_WORLDDIR} sh -c 'cd packages; /pkg-static add *;cd ..;'
rm -rf ${NANO_WORLDDIR}/packages ${NANO_WORLDDIR}/pkg-static
)
customize_cmd install_packages</programlisting>
</sect3>
<sect3>
@ -409,6 +753,29 @@ customize_cmd cust_comconsole
customize_cmd cust_install_files
customize_cmd cust_allow_ssh_root
customize_cmd cust_nobeastie</programlisting>
<para>All the build and install compilation options can be found in
the &man.src.conf.5; man page, but not all options can or should be
used when building a <application>NanoBSD</application> image.
The build and install options should be defined according to the
needs of the image being built.</para>
<para>For example, the ftp client and server might not be needed.
Adding <literal>WITHOUT_FTP=TRUE</literal> to a configuration file
in the <literal>CONF_BUILD</literal> section will avoid having
them built. Also, if the <application>NanoBSD</application>
appliance will not be used to build programs then it is possible
to add the <literal>WITHOUT_BINUTILS=TRUE</literal> in the
<literal>CONF_INSTALL</literal> section; but not
in the <literal>CONF_BUILD</literal> section as they will be
used to build the <application>NanoBSD</application> image.</para>
<para>Not building a particular set of programs &mdash;
through a compilation option &mdash; shortens the overall building
time and lowers the required size for the disk image,
whereas not installing the same specific set of programs
does not lower the overall building time.</para>
</sect3>
</sect2>