506 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			506 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| <!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
 | |
| <!ENTITY % articles.ent PUBLIC "-//FreeBSD//ENTITIES DocBook FreeBSD Articles Entity Set//EN">
 | |
| %articles.ent;
 | |
| ]>
 | |
| 
 | |
| <article>
 | |
|   <articleinfo>
 | |
|     <title>Introduction to NanoBSD</title>
 | |
| 
 | |
|     <authorgroup>
 | |
|       <author>
 | |
| 	<firstname>Daniel</firstname>
 | |
| 	<surname>Gerzo</surname>
 | |
| 	<!-- 14 March 2006 -->
 | |
|       </author>
 | |
|     </authorgroup>
 | |
| 
 | |
|     <pubdate>$FreeBSD$</pubdate>
 | |
| 
 | |
|     <copyright>
 | |
|       <year>2006</year>
 | |
|       <holder>The FreeBSD Documentation Project</holder>
 | |
|     </copyright>
 | |
| 
 | |
|     <legalnotice id="trademarks" role="trademarks">
 | |
|       &tm-attrib.freebsd;
 | |
|       &tm-attrib.general;
 | |
|     </legalnotice>
 | |
| 
 | |
|     <abstract>
 | |
|       <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>
 | |
|     </abstract>
 | |
|   </articleinfo>
 | |
| 
 | |
|   <sect1 id="intro">
 | |
|     <title>Introduction to NanoBSD</title>
 | |
| 
 | |
|     <indexterm><primary>NanoBSD</primary></indexterm>
 | |
| 
 | |
|     <para><application>NanoBSD</application> is a tool currently
 | |
|       developed by &a.phk;.  It creates a &os; system image for embedded
 | |
|       applications, suitable for use on a Compact Flash card (or other
 | |
|       mass storage medium).</para>
 | |
| 
 | |
|     <para>It can be used to build specialized install images, designed for
 | |
|       easy installation and maintenance of systems commonly
 | |
|       called <quote>computer appliances</quote>.  Computer appliances have
 | |
|       their hardware and software bundled in the product, which means all
 | |
|       applications are pre-installed.  The appliance is plugged into an
 | |
|       existing network and can begin working (almost) immediately.</para>
 | |
| 
 | |
|     <para>The features of <application>NanoBSD</application> include:</para>
 | |
| 
 | |
|     <itemizedlist>
 | |
|       <listitem>
 | |
| 	<para>Ports and packages work as in &os; — Every single
 | |
| 	  application can be installed and used in
 | |
| 	  a <application>NanoBSD</application> image, the same way as in
 | |
| 	  &os;.</para>
 | |
|       </listitem>
 | |
| 
 | |
|       <listitem>
 | |
| 	<para>No missing functionality — If it is possible to do
 | |
| 	  something with &os;, it is possible to do the same thing with
 | |
| 	  <application>NanoBSD</application>, unless the specific feature
 | |
| 	  or features were explicitly removed from
 | |
| 	  the <application>NanoBSD</application> image when it was
 | |
| 	  created.</para>
 | |
|       </listitem>
 | |
| 
 | |
|       <listitem>
 | |
| 	<para>Everything is read-only at run-time — It is safe to
 | |
| 	  pull the power-plug.  There is no necessity to run
 | |
| 	  &man.fsck.8; after a non-graceful shutdown of the system.</para>
 | |
|       </listitem>
 | |
| 
 | |
|       <listitem>
 | |
| 	<para>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.</para>
 | |
|       </listitem>
 | |
|     </itemizedlist>
 | |
|   </sect1>
 | |
| 
 | |
|   <sect1 id="howto">
 | |
|     <title>NanoBSD Howto</title>
 | |
| 
 | |
|     <sect2 id="design">
 | |
|       <title>The design of NanoBSD</title>
 | |
| 
 | |
|       <para>Once the image is present on the medium, it is possible to
 | |
| 	boot <application>NanoBSD</application>.  The mass storage
 | |
| 	medium is divided into three parts by default:</para>
 | |
| 
 | |
|       <itemizedlist>
 | |
| 	<listitem>
 | |
| 	  <para>Two image partitions: <literal>code#1</literal>
 | |
| 	    and <literal>code#2</literal>.</para>
 | |
| 	</listitem>
 | |
| 
 | |
| 	<listitem>
 | |
| 	  <para>The configuration file partition, which can be mounted
 | |
| 	    under the <filename class="directory">/cfg</filename> directory
 | |
| 	    at run time.</para>
 | |
| 	</listitem>
 | |
|       </itemizedlist>
 | |
| 
 | |
|       <para>These partitions are normally mounted read-only.</para>
 | |
| 
 | |
|       <para>The <filename class="directory">/etc</filename> and
 | |
| 	<filename class="directory">/var</filename> directories are
 | |
| 	&man.md.4; (malloc) disks.</para>
 | |
| 
 | |
|       <para>The configuration file partition persists under the
 | |
| 	<filename class="directory">/cfg</filename> directory.  It
 | |
| 	contains files for <filename class="directory">/etc</filename>
 | |
| 	directory and is briefly mounted read-only right after the
 | |
| 	system boot, therefore it is required to copy modified files
 | |
| 	from <filename class="directory">/etc</filename> back to the
 | |
| 	<filename class="directory">/cfg</filename> directory if changes
 | |
| 	are expected to persist after the system restarts.</para>
 | |
| 
 | |
|       <example>
 | |
| 	<title>Making persistent changes to <filename>/etc/resolv.conf</filename></title>
 | |
| 
 | |
| 	<screen>&prompt.root; <userinput>vi /etc/resolv.conf</userinput>
 | |
| [...]
 | |
| &prompt.root; <userinput>mount /cfg</userinput>
 | |
| &prompt.root; <userinput>cp /etc/resolv.conf /cfg</userinput>
 | |
| &prompt.root; <userinput>umount /cfg</userinput></screen>
 | |
|       </example>
 | |
| 
 | |
|       <note>
 | |
| 	<para>The partition containing
 | |
| 	  <filename class="directory">/cfg</filename> should be mounted
 | |
| 	  only at boot time and while overriding the configuration
 | |
| 	  files.</para>
 | |
| 
 | |
| 	<para>Keeping <filename class="directory">/cfg</filename> mounted at
 | |
| 	  all times is not a good idea, especially if
 | |
| 	  the <application>NanoBSD</application> system runs off a mass
 | |
| 	  storage medium that may be adversely affected by a large number
 | |
| 	  of writes to the partition (i.e. when the filesystem syncer
 | |
| 	  flushes data to the system disks).</para>
 | |
|       </note>
 | |
|     </sect2>
 | |
| 
 | |
|     <sect2>
 | |
|       <title>Building a NanoBSD image</title>
 | |
| 
 | |
|       <para>A <application>NanoBSD</application> image is built using a
 | |
| 	simple <filename>nanobsd.sh</filename> shell script, which can
 | |
| 	be found in the
 | |
| 	<filename class="directory"><replaceable>/usr</replaceable>/src/tools/tools/nanobsd</filename>
 | |
| 	directory.  This script creates an image, which can be copied on
 | |
| 	the storage medium using the &man.dd.1; utility.</para>
 | |
| 
 | |
|       <para>The necessary commands to build a
 | |
| 	<application>NanoBSD</application> image are:</para>
 | |
| 
 | |
|       <screen>&prompt.root; <userinput>cd /usr/src/tools/tools/nanobsd</userinput> <co id="nbsd-cd">
 | |
| &prompt.root; <userinput>sh nanobsd.sh</userinput> <co id="nbsd-sh">
 | |
| &prompt.root; <userinput>cd /usr/obj/nanobsd.full</userinput> <co id="nbsd-cd2">
 | |
| &prompt.root; <userinput>dd if=_.disk.full of=/dev/da0 bs=64k</userinput> <co id="nbsd-dd"></screen>
 | |
| 
 | |
|       <calloutlist>
 | |
| 	<callout arearefs="nbsd-cd">
 | |
| 	  <para>Change the current directory to the base directory of the
 | |
| 	    <application>NanoBSD</application> build script.</para>
 | |
| 	</callout>
 | |
| 
 | |
| 	<callout arearefs="nbsd-sh">
 | |
| 	  <para>Start the build process.</para>
 | |
| 	</callout>
 | |
| 
 | |
| 	<callout arearefs="nbsd-cd2">
 | |
| 	  <para>Change the current directory to the place where the built
 | |
| 	    images are located.</para>
 | |
| 	</callout>
 | |
| 
 | |
| 	<callout arearefs="nbsd-dd">
 | |
| 	  <para>Install <application>NanoBSD</application> onto the
 | |
| 	    storage medium.</para>
 | |
| 	</callout>
 | |
|       </calloutlist>
 | |
|     </sect2>
 | |
| 
 | |
|     <sect2>
 | |
|       <title>Customizing a NanoBSD image</title>
 | |
| 
 | |
|       <para>This is probably the most important and most interesting
 | |
| 	feature of <application>NanoBSD</application>.  This is also
 | |
| 	where you will be spending most of the time when
 | |
| 	developing with <application>NanoBSD</application>.</para>
 | |
| 
 | |
|       <para>Invocation of the following command will force the
 | |
| 	<filename>nanobsd.sh</filename> to read its configuration from
 | |
| 	the <filename>myconf.nano</filename> file located in the current
 | |
| 	directory:</para>
 | |
| 
 | |
|       <screen>&prompt.root; <userinput>sh nanobsd.sh -c myconf.nano</userinput></screen>
 | |
| 
 | |
|       <para>Customization is done in two ways:</para>
 | |
| 
 | |
|       <itemizedlist>
 | |
| 	<listitem>
 | |
| 	  <para>Configuration options</para>
 | |
| 	</listitem>
 | |
| 
 | |
| 	<listitem>
 | |
| 	  <para>Custom functions</para>
 | |
| 	</listitem>
 | |
|       </itemizedlist>
 | |
| 
 | |
|       <sect3>
 | |
| 	<title>Configuration options</title>
 | |
| 
 | |
|         <para>With configuration settings, it is possible to configure options
 | |
|           passed to both the <maketarget>buildworld</maketarget>
 | |
|           and <maketarget>installworld</maketarget> stages of the
 | |
|           <application>NanoBSD</application> build process, as well as internal
 | |
|           options passed to the main build process of
 | |
|           <application>NanoBSD</application>.  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 &os; even
 | |
|           more, until it will consists of just the kernel and two or three
 | |
|           files in the userland.</para>
 | |
| 
 | |
| 	<para>The configuration file consists of configuration options,
 | |
| 	  which override the default values.  The most important
 | |
| 	  directives are:</para>
 | |
| 
 | |
| 	<itemizedlist>
 | |
| 	  <listitem>
 | |
| 	    <para><literal>NANO_NAME</literal> — Name of build
 | |
| 	      (used to construct the workdir names).</para>
 | |
| 	  </listitem>
 | |
| 
 | |
| 	  <listitem>
 | |
| 	    <para><literal>NANO_SRC</literal> — Path to the source
 | |
| 	      tree used to build the image.</para>
 | |
| 	  </listitem>
 | |
| 
 | |
| 	  <listitem>
 | |
| 	    <para><literal>NANO_KERNEL</literal> — Name of kernel
 | |
| 	      configuration file used to build kernel.</para>
 | |
| 	  </listitem>
 | |
| 
 | |
| 	  <listitem>
 | |
| 	    <para><literal>CONF_BUILD</literal> — Options passed
 | |
| 	      to the <maketarget>buildworld</maketarget> stage of the build.</para>
 | |
| 	  </listitem>
 | |
| 
 | |
| 	  <listitem>
 | |
| 	    <para><literal>CONF_INSTALL</literal> — Options passed
 | |
| 	      to the <maketarget>installworld</maketarget> stage of the build.</para>
 | |
| 	  </listitem>
 | |
| 
 | |
| 	  <listitem>
 | |
| 	    <para><literal>CONF_WORLD</literal> — Options passed to both
 | |
| 	      the <maketarget>buildworld</maketarget> and
 | |
| 	      the <maketarget>installworld</maketarget> stage of the build.</para>
 | |
| 	  </listitem>
 | |
| 
 | |
| 	  <listitem>
 | |
| 	    <para><literal>FlashDevice</literal> — Defines what type of
 | |
| 	      media to use.  Check the <filename>FlashDevice.sub</filename>
 | |
| 	      file for more details.</para>
 | |
| 	  </listitem>
 | |
| 	</itemizedlist>
 | |
|       </sect3>
 | |
| 
 | |
|       <sect3>
 | |
| 	<title>Custom functions</title>
 | |
| 
 | |
| 	<para>It is possible to fine-tune
 | |
| 	  <application>NanoBSD</application> using shell functions in
 | |
| 	  the configuration file.  The following example illustrates the
 | |
| 	  basic model of custom functions:</para>
 | |
| 
 | |
| 	  <programlisting>cust_foo () (
 | |
| 	echo "bar=baz" > \
 | |
| 		${NANO_WORLDDIR}/etc/foo
 | |
| )
 | |
| customize_cmd cust_foo</programlisting>
 | |
| 
 | |
|         <para>A more useful example of a customization function is the
 | |
|           following, which changes the default size of the
 | |
|           <filename class="directory">/etc</filename> directory
 | |
|           from 5MB to 30MB:</para>
 | |
| 
 | |
| 	<programlisting>cust_etc_size () (
 | |
| 	cd ${NANO_WORLDDIR}/conf
 | |
| 	echo 30000 > default/etc/md_size
 | |
| )
 | |
| customize_cmd cust_etc_size</programlisting>
 | |
| 
 | |
| 	<para>There are a few default pre-defined customization functions
 | |
| 	  ready for use:</para>
 | |
| 
 | |
| 	<itemizedlist>
 | |
| 	  <listitem>
 | |
| 	    <para><literal>cust_comconsole</literal> — Disables
 | |
| 	      &man.getty.8; on the VGA devices
 | |
| 	      (the <filename>/dev/ttyv*</filename> device nodes) and enables
 | |
| 	      the use of the COM1 serial port as the system console.</para>
 | |
| 	  </listitem>
 | |
| 
 | |
| 	  <listitem>
 | |
| 	    <para><literal>cust_allow_ssh_root</literal> — Allow
 | |
| 	      <username>root</username> to login via &man.sshd.8;.</para>
 | |
| 	  </listitem>
 | |
| 
 | |
| 	  <listitem>
 | |
| 	    <para><literal>cust_install_files</literal> —
 | |
| 	      Installs files from the
 | |
| 	      <filename class="directory">nanobsd/Files</filename>
 | |
| 	      directory, which contains some useful scripts for system
 | |
| 	      administration.</para>
 | |
| 	  </listitem>
 | |
| 	</itemizedlist>
 | |
|       </sect3>
 | |
| 
 | |
|       <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>
 | |
| 
 | |
| 	<programlisting>install_packages () (
 | |
| mkdir -p ${NANO_WORLDDIR}/packages
 | |
| cp /usr/src/tools/tools/nanobsd/packages/* ${NANO_WORLDDIR}/packages
 | |
| chroot ${NANO_WORLDDIR} sh -c 'cd packages; pkg_add -v *;cd ..;'
 | |
| rm -rf ${NANO_WORLDDIR}/packages
 | |
| )
 | |
| customize_cmd install_packages</programlisting>
 | |
|       </sect3>
 | |
| 
 | |
|       <sect3>
 | |
| 	<title>Configuration file example</title>
 | |
| 
 | |
| 	<para>A complete example of a configuration file for building a
 | |
|           custom <application>NanoBSD</application> image can be:</para>
 | |
| 
 | |
| 	<programlisting>NANO_NAME=custom
 | |
| NANO_SRC=/usr/src
 | |
| NANO_KERNEL=MYKERNEL
 | |
| NANO_IMAGES=2
 | |
| 
 | |
| CONF_BUILD='
 | |
| NO_KLDLOAD=YES
 | |
| NO_NETGRAPH=YES
 | |
| NO_PAM=YES
 | |
| '
 | |
| 
 | |
| CONF_INSTALL='
 | |
| NO_ACPI=YES
 | |
| NO_BLUETOOTH=YES
 | |
| NO_CVS=YES
 | |
| NO_FORTRAN=YES
 | |
| NO_HTML=YES
 | |
| NO_LPR=YES
 | |
| NO_MAN=YES
 | |
| NO_SENDMAIL=YES
 | |
| NO_SHAREDOCS=YES
 | |
| NO_EXAMPLES=YES
 | |
| NO_INSTALLLIB=YES
 | |
| NO_CALENDAR=YES
 | |
| NO_MISC=YES
 | |
| NO_SHARE=YES
 | |
| '
 | |
| 
 | |
| CONF_WORLD='
 | |
| NO_BIND=YES
 | |
| NO_MODULES=YES
 | |
| NO_KERBEROS=YES
 | |
| NO_GAMES=YES
 | |
| NO_RESCUE=YES
 | |
| NO_LOCALES=YES
 | |
| NO_SYSCONS=YES
 | |
| NO_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</programlisting>
 | |
|       </sect3>
 | |
|     </sect2>
 | |
| 
 | |
|     <sect2>
 | |
|       <title>Updating NanoBSD</title>
 | |
| 
 | |
|       <para>The update process of <application>NanoBSD</application> is
 | |
|         relatively simple:</para>
 | |
| 
 | |
|       <procedure>
 | |
| 	<step>
 | |
| 	  <para>Build a new <application>NanoBSD</application> image, as
 | |
| 	    usual.</para>
 | |
| 	</step>
 | |
| 
 | |
| 	<step>
 | |
| 	  <para>Upload the new image into an unused partition of a
 | |
| 	    running <application>NanoBSD</application> appliance.</para>
 | |
| 
 | |
| 	  <para>The most important difference of this step from the
 | |
| 	    initial <application>NanoBSD</application> installation is that
 | |
| 	    now instead of using the <filename>_.disk.full</filename> file
 | |
| 	    (which contains an image of the entire disk),
 | |
| 	    the <filename>_.disk.image</filename> image is installed (which
 | |
| 	    contains an image of a single system partition).</para>
 | |
| 	</step>
 | |
| 
 | |
| 	<step>
 | |
| 	  <para>Reboot, and start the system from the newly installed
 | |
| 	    partition.</para>
 | |
| 	</step>
 | |
| 
 | |
| 	<step>
 | |
| 	  <para>If all goes well, the upgrade is finished.</para>
 | |
| 	</step>
 | |
| 
 | |
| 	<step>
 | |
| 	  <para>If anything goes wrong, reboot back into the previous
 | |
| 	  partition (which contains the old, working image), to restore system
 | |
| 	  functionality as fast as possible.  Fix any problems of the new
 | |
| 	  build, and repeat the process.</para>
 | |
| 	</step>
 | |
|       </procedure>
 | |
| 
 | |
|       <para>To install new image onto the running
 | |
| 	<application>NanoBSD</application> system, it is possible to use
 | |
| 	either the <filename>updatep1</filename> or
 | |
| 	<filename>updatep2</filename> script located in the
 | |
| 	<filename class="directory">/root</filename> directory, depending
 | |
| 	from which partition is running the current system.</para>
 | |
| 
 | |
|       <para>According to which services are available on host serving
 | |
| 	new <application>NanoBSD</application> image and what type of
 | |
| 	transfer is preferred, it is possible to examine one of these
 | |
| 	three ways:</para>
 | |
| 
 | |
|       <sect3>
 | |
| 	<title>Using &man.ftp.1;</title>
 | |
| 
 | |
| 	<para>If the transfer speed is in first place, use this
 | |
| 	  example:</para>
 | |
| 
 | |
| 	<screen>&prompt.root; <userinput>ftp myhost
 | |
| get _.disk.image "| sh updatep1"</userinput></screen>
 | |
|       </sect3>
 | |
| 
 | |
|       <sect3>
 | |
| 	<title>Using &man.ssh.1;</title>
 | |
| 
 | |
| 	<para>If a secure transfer is preferred, consider using this
 | |
| 	  example:</para>
 | |
| 
 | |
| 	<screen>&prompt.root; <userinput>ssh myhost cat _.disk.image.gz | zcat | sh updatep1</userinput></screen>
 | |
|       </sect3>
 | |
| 
 | |
|       <sect3>
 | |
| 	<title>Using &man.nc.1;</title>
 | |
| 
 | |
| 	<para>Try this example if the remote host is not running neither
 | |
| 	  &man.ftp.1; or &man.sshd.8; service:</para>
 | |
| 
 | |
| 	<procedure>
 | |
| 	  <step>
 | |
| 	    <para>At first, open a TCP listener on host serving the
 | |
| 	      image and make it send the image to client:</para>
 | |
| 
 | |
| 	    <screen>myhost&prompt.root; <userinput>nc -l <replaceable>2222</replaceable> < _.disk.image</userinput></screen>
 | |
| 
 | |
| 	    <note>
 | |
| 	      <para>Make sure that the used port is not blocked to
 | |
| 		receive incoming connections from
 | |
| 		<application>NanoBSD</application> host by
 | |
| 		firewall.</para>
 | |
| 	    </note>
 | |
| 	  </step>
 | |
| 	  <step>
 | |
| 	    <para>Connect to the host serving new image and execute
 | |
| 	      <filename>updatep1</filename> script:</para>
 | |
| 
 | |
| 	    <screen>&prompt.root; <userinput>nc myhost <replaceable>2222</replaceable> | sh updatep1</userinput></screen>
 | |
| 	  </step>
 | |
| 	</procedure>
 | |
|       </sect3>
 | |
|     </sect2>
 | |
|   </sect1>
 | |
| </article>
 |