1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
<table class="head">
<tr>
<td class="head-ltitle">NANOBSD(8)</td>
<td class="head-vol">System Manager's Manual</td>
<td class="head-rtitle">NANOBSD(8)</td>
</tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">nanobsd.sh</code> —
<span class="Nd">create an embedded FreeBSD system image</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<table class="Nm">
<tr>
<td><code class="Nm">nanobsd.sh</code></td>
<td>[<code class="Fl">-BbfhIiKknpqvWwX</code>] [<code class="Fl">-c</code>
<var class="Ar">config-file</var>]</td>
</tr>
</table>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">The <code class="Nm">nanobsd.sh</code> utility is a script which
produces a minimal implementation of <span class="Ux">FreeBSD</span> (called
<code class="Nm">NanoBSD</code>), which typically fits on a small media such
as an SD card, or other mass storage medium. It can be used to build
specialized install images, designed for easy installation and
maintenance.</p>
<p class="Pp">The following options are available:</p>
<div class="Bd-indent">
<dl class="Bl-tag">
<dt id="B"><a class="permalink" href="#B"><code class="Fl">-B</code></a></dt>
<dd>Skip the install stages (both for kernel and world).</dd>
<dt id="b"><a class="permalink" href="#b"><code class="Fl">-b</code></a></dt>
<dd>Skip the build stages (both for kernel and world).</dd>
<dt id="c"><a class="permalink" href="#c"><code class="Fl">-c</code></a>
<var class="Ar">config-file</var></dt>
<dd>Specify the configuration file to use.</dd>
<dt id="f"><a class="permalink" href="#f"><code class="Fl">-f</code></a></dt>
<dd>Skip the code slice extraction.</dd>
<dt id="h"><a class="permalink" href="#h"><code class="Fl">-h</code></a></dt>
<dd>Display usage information.</dd>
<dt id="I"><a class="permalink" href="#I"><code class="Fl">-I</code></a></dt>
<dd>Build the disk image from an existing build/install.</dd>
<dt id="i"><a class="permalink" href="#i"><code class="Fl">-i</code></a></dt>
<dd>Skip the disk image build stage.</dd>
<dt id="K"><a class="permalink" href="#K"><code class="Fl">-K</code></a></dt>
<dd>Skip the <code class="Cm">installkernel</code> stage of the build.</dd>
<dt id="k"><a class="permalink" href="#k"><code class="Fl">-k</code></a></dt>
<dd>Skip the <code class="Cm">buildkernel</code> stage of the build.</dd>
<dt id="n"><a class="permalink" href="#n"><code class="Fl">-n</code></a></dt>
<dd>Do not cleanup before each build stage. This suppresses the normal cleanup
work done before the <code class="Cm">buildworld</code> stage and adds
-DNO_CLEAN to the make command line used for each build stage (world and
kernel).</dd>
<dt id="p"><a class="permalink" href="#p"><code class="Fl">-p</code></a></dt>
<dd>Don't prepare the image. Skip running of the customization and early
customization scripts for incremental image refinement from world, kernel,
or packages.</dd>
<dt id="q"><a class="permalink" href="#q"><code class="Fl">-q</code></a></dt>
<dd>Make output more quiet.</dd>
<dt id="v"><a class="permalink" href="#v"><code class="Fl">-v</code></a></dt>
<dd>Make output more verbose.</dd>
<dt id="W"><a class="permalink" href="#W"><code class="Fl">-W</code></a></dt>
<dd>Skip the <code class="Cm">installworld</code> stage of the build.</dd>
<dt id="w"><a class="permalink" href="#w"><code class="Fl">-w</code></a></dt>
<dd>Skip the <code class="Cm">buildworld</code> stage of the build.</dd>
<dt id="X"><a class="permalink" href="#X"><code class="Fl">-X</code></a></dt>
<dd>Make <code class="Cm">native-xtools</code>.</dd>
</dl>
</div>
<p class="Pp">The features of <code class="Nm">NanoBSD</code> include:</p>
<p class="Pp"></p>
<ul class="Bl-bullet Bd-indent Bl-compact">
<li>Ports and packages work as in <span class="Ux">FreeBSD</span>. Every
single application can be installed and used in a
<code class="Nm">NanoBSD</code> image, the same way as in
<span class="Ux">FreeBSD</span>.</li>
<li>No missing functionality. If it is possible to do something with
<span class="Ux">FreeBSD</span>, it is possible to do the same thing with
<code class="Nm">NanoBSD</code>, unless the specific feature or features
were explicitly removed from the <code class="Nm">NanoBSD</code> image
when it was created.</li>
<li>Everything is read-only at run-time. It is safe to pull the power-plug.
There is no necessity to run <a class="Xr">fsck(8)</a> after a
non-graceful shutdown of the system.</li>
<li>Easy to build and customize. Making use of just one shell script and one
configuration file it is possible to build reduced and customized images
satisfying any arbitrary set of requirements.</li>
</ul>
<section class="Ss">
<h2 class="Ss" id="NanoBSD_Media_Layout"><a class="permalink" href="#NanoBSD_Media_Layout">NanoBSD
Media Layout</a></h2>
<p class="Pp">The mass storage medium is divided into three parts by default
(which are normally mounted read-only):</p>
<p class="Pp"></p>
<ul class="Bl-bullet Bd-indent Bl-compact">
<li>Two image partitions: <code class="Li">code#1</code> and
<code class="Li">code#2</code>.</li>
<li>The configuration file partition, which can be mounted under the
<span class="Pa">/cfg</span> directory at run time.</li>
</ul>
<p class="Pp">The <span class="Pa">/etc</span> and <span class="Pa">/var</span>
directories are <a class="Xr">md(4)</a> (malloc backed) disks.</p>
<p class="Pp">The configuration file partition persists under the
<span class="Pa">/cfg</span> directory. It contains files for
<span class="Pa">/etc</span> directory and is briefly mounted read-only
right after the system boot, therefore it is required to copy modified files
from <span class="Pa">/etc</span> back to the <span class="Pa">/cfg</span>
directory if changes are expected to persist after the system restarts.</p>
</section>
</section>
<section class="Sh">
<h1 class="Sh" id="BUILDING_NanoBSD"><a class="permalink" href="#BUILDING_NanoBSD">BUILDING
<code class="Nm">NanoBSD</code></a></h1>
<p class="Pp">A <code class="Nm">NanoBSD</code> image is built using a simple
<code class="Nm">nanobsd.sh</code> shell script, which can be found in the
<span class="Pa">src/tools/tools/nanobsd</span> directory. This script
creates a bootable image, which can be copied on the storage medium using
the <a class="Xr">dd(1)</a> utility.</p>
<p class="Pp">The necessary commands to build and install a
<code class="Nm">NanoBSD</code> image are:</p>
<div class="Bd Pp Bd-indent Li">
<pre>cd /usr/src/tools/tools/nanobsd
sh nanobsd.sh
cd /usr/obj/nanobsd.full
dd if=_.disk.full of=/dev/da0 bs=64k</pre>
</div>
</section>
<section class="Sh">
<h1 class="Sh" id="CUSTOMIZING_NanoBSD"><a class="permalink" href="#CUSTOMIZING_NanoBSD">CUSTOMIZING
<code class="Nm">NanoBSD</code></a></h1>
<p class="Pp">This is probably the most important and most interesting feature
of <code class="Nm">NanoBSD</code>. This is also where you will be spending
most of the time when developing with <code class="Nm">NanoBSD</code>.</p>
<p class="Pp">Customization is done in two ways:</p>
<p class="Pp"></p>
<ul class="Bl-bullet Bd-indent Bl-compact">
<li>Configuration options.</li>
<li>Custom functions.</li>
</ul>
<p class="Pp">With configuration settings, it is possible to configure options
passed to both the <code class="Cm">buildworld</code> and
<code class="Cm">installworld</code> stages of the
<code class="Nm">NanoBSD</code> build process, as well as internal options
passed to the main build process of <code class="Nm">NanoBSD</code>. Through
these options it is possible to cut the system down, so it will fit on as
little as 64MB. You can use the configuration options to trim down the
system even more, until it will consist of just the kernel and two or three
files in the userland.</p>
<p class="Pp">The configuration file consists of configuration options, which
override the default values. The most important directives are:</p>
<div class="Bd-indent">
<dl class="Bl-tag">
<dt id="NANO_NAME"><var class="Va">NANO_NAME</var></dt>
<dd>Build name (used to construct the working directory names).</dd>
<dt id="NANO_SRC"><var class="Va">NANO_SRC</var></dt>
<dd>Path to the source tree used to build the image.</dd>
<dt id="NANO_KERNEL"><var class="Va">NANO_KERNEL</var></dt>
<dd>Name of the kernel configuration file used to build the kernel.</dd>
<dt id="NANO_ARCH"><var class="Va">NANO_ARCH</var></dt>
<dd>Machine processor architecture to build. Defaults to output of
<code class="Cm">uname -p</code>.</dd>
<dt id="NANO_BOOT0CFG"><var class="Va">NANO_BOOT0CFG</var></dt>
<dd>Controls the options passed to <a class="Xr">boot0cfg(8)</a>; these
dictate <code class="Nm">boot0</code>'s behaviour.</dd>
<dt id="NANO_BOOTLOADER"><var class="Va">NANO_BOOTLOADER</var></dt>
<dd>The <code class="Nm">boot0</code> loader to use relative to the
<var class="Va">NANO_WORLDDIR</var> variable. This defaults to
<span class="Pa">boot/boot0sio</span> and should be overridden to
<span class="Pa">boot/boot0</span> to provide a VGA console.</dd>
<dt id="CONF_BUILD"><var class="Va">CONF_BUILD</var></dt>
<dd>Options passed to the <code class="Cm">buildworld</code> stage of the
build.</dd>
<dt id="CONF_INSTALL"><var class="Va">CONF_INSTALL</var></dt>
<dd>Options passed to the <code class="Cm">installworld</code> stage of the
build.</dd>
<dt id="CONF_WORLD"><var class="Va">CONF_WORLD</var></dt>
<dd>Options passed to both the <code class="Cm">buildworld</code> and
<code class="Cm">installworld</code> stages of the build.</dd>
<dt id="FlashDevice"><var class="Va">FlashDevice</var></dt>
<dd>Defines the type of media to use. Check the
<span class="Pa">FlashDevice.sub</span> file for more details.</dd>
</dl>
</div>
<p class="Pp">For more configuration options, please check the
<code class="Nm">nanobsd.sh</code> script.</p>
<p class="Pp">To build <code class="Nm">NanoBSD</code> image using the
<span class="Pa">nanobsd.conf</span> configuration file, use the following
command:</p>
<div class="Bd Pp Bd-indent Li">
<pre>sh nanobsd.sh -c nanobsd.conf</pre>
</div>
<p class="Pp">It is possible to fine-tune <code class="Nm">NanoBSD</code> using
shell functions in the configuration file. The following example illustrates
the basic model of custom functions:</p>
<div class="Bd Pp Bd-indent Li">
<pre>cust_foo () (
echo "bar=topless" > \
${NANO_WORLDDIR}/etc/foo
)
customize_cmd cust_foo</pre>
</div>
<p class="Pp">There are a few pre-defined customization functions ready for
use:</p>
<div class="Bd-indent">
<dl class="Bl-tag">
<dt id="cust_comconsole"><a class="permalink" href="#cust_comconsole"><code class="Cm">cust_comconsole</code></a></dt>
<dd>Disables <a class="Xr">getty(8)</a> on the virtual
<a class="Xr">syscons(4)</a> or <a class="Xr">vt(4)</a> terminals
(<span class="Pa">/dev/ttyv*</span>) and enables the use of the first
serial port as the system console.</dd>
<dt id="cust_allow_ssh_root"><a class="permalink" href="#cust_allow_ssh_root"><code class="Cm">cust_allow_ssh_root</code></a></dt>
<dd>Allow root to log in via <a class="Xr">sshd(8)</a>.</dd>
<dt id="cust_install_files"><a class="permalink" href="#cust_install_files"><code class="Cm">cust_install_files</code></a></dt>
<dd>Installs files from the <span class="Pa">nanobsd/Files</span> directory,
which contains some useful scripts for system administration.</dd>
</dl>
</div>
</section>
<section class="Sh">
<h1 class="Sh" id="FILES"><a class="permalink" href="#FILES">FILES</a></h1>
<dl class="Bl-tag Bl-compact">
<dt><span class="Pa">src/tools/tools/nanobsd</span></dt>
<dd>Base directory of the <code class="Nm">NanoBSD</code> build script.</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1>
<p class="Pp">Making persistent changes to
<span class="Pa">/etc/resolv.conf</span>:</p>
<div class="Bd Pp Bd-indent Li">
<pre>vi /etc/resolv.conf
...
mount /cfg
cp /etc/resolv.conf /cfg
umount /cfg</pre>
</div>
<p class="Pp">A more useful example of a customization function is the
following, which changes the default size of the
<span class="Pa">/etc</span> directory from 5MB to 30MB:</p>
<div class="Bd Pp Bd-indent Li">
<pre>cust_etc_size () (
cd ${NANO_WORLDDIR}/conf
echo 30000 > default/etc/md_size
)
customize_cmd cust_etc_size</pre>
</div>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<p class="Pp"><a class="Xr">make.conf(5)</a>, <a class="Xr">boot(8)</a>,
<a class="Xr">boot0cfg(8)</a></p>
</section>
<section class="Sh">
<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
<p class="Pp">The <code class="Nm">nanobsd.sh</code> utility first appeared in
<span class="Ux">FreeBSD 6.0</span>.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
<p class="Pp"><code class="Nm">NanoBSD</code> was developed by
<span class="An">Poul-Henning Kamp</span>
<<a class="Mt" href="mailto:phk@FreeBSD.org">phk@FreeBSD.org</a>>.
This manual page was written by <span class="An">Daniel Gerzo</span>
<<a class="Mt" href="mailto:danger@FreeBSD.org">danger@FreeBSD.org</a>>.</p>
</section>
</div>
<table class="foot">
<tr>
<td class="foot-date">September 9, 2025</td>
<td class="foot-os">FreeBSD 15.0</td>
</tr>
</table>
|