630 lines
		
	
	
	
		
			29 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			630 lines
		
	
	
	
		
			29 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| <!-- Copyright (c) 2001 The FreeBSD Documentation Project
 | |
| 
 | |
|      Redistribution and use in source (SGML DocBook) and 'compiled' forms
 | |
|      (SGML, HTML, PDF, PostScript, RTF and so forth) with or without
 | |
|      modification, are permitted provided that the following conditions
 | |
|      are met:
 | |
| 
 | |
|       1. Redistributions of source code (SGML DocBook) must retain the above
 | |
|          copyright notice, this list of conditions and the following
 | |
|          disclaimer as the first lines of this file unmodified.
 | |
| 
 | |
|       2. Redistributions in compiled form (transformed to other DTDs,
 | |
|          converted to PDF, PostScript, RTF and other formats) must reproduce
 | |
|          the above copyright notice, this list of conditions and the
 | |
|          following disclaimer in the documentation and/or other materials
 | |
|          provided with the distribution.
 | |
| 
 | |
|      THIS DOCUMENTATION IS PROVIDED BY THE FREEBSD DOCUMENTATION PROJECT "AS
 | |
|      IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
|      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
|      PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY
 | |
|      DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | |
|      DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | |
|      OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | |
|      HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | |
|      STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | |
|      ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
 | |
|      POSSIBILITY OF SUCH DAMAGE.
 | |
| 
 | |
|      $FreeBSD$
 | |
| -->
 | |
| 
 | |
| <!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
 | |
| <!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN">
 | |
| %man;
 | |
| <!ENTITY legalnotice SYSTEM "../../share/sgml/legalnotice.sgml">
 | |
| ]>
 | |
| 
 | |
| <article>
 | |
|   <articleinfo>
 | |
|     <title>FreeBSD and Solid State Devices</title>
 | |
| 
 | |
|     <authorgroup>
 | |
|       <author>
 | |
| 	<firstname>John</firstname>
 | |
| 	<surname>Kozubik</surname>
 | |
| 
 | |
| 	<affiliation>
 | |
| 	  <address><email>john@kozubik.com</email></address>
 | |
| 	</affiliation>
 | |
|       </author>
 | |
|     </authorgroup>
 | |
|     
 | |
|     <pubdate>$FreeBSD$</pubdate>
 | |
| 
 | |
|     <copyright>
 | |
|       <year>2001</year>
 | |
|       <holder>The FreeBSD Documentation Project</holder>
 | |
|     </copyright>
 | |
| 
 | |
|     &legalnotice;
 | |
|     
 | |
|     <abstract>
 | |
|       <para>This article covers the use of solid state disk devices in FreeBSD
 | |
| 	to create embedded systems.</para>
 | |
|     
 | |
|       <para>Embedded systems have the advantage of increased stability due to
 | |
| 	the lack of integral moving parts (hard drives).  Account must be
 | |
| 	taken, however, for the generally low disk space available in the
 | |
| 	system and the durability of the storage medium.</para>
 | |
| 
 | |
|       <para>Specific topics to be covered include the types and attributes of
 | |
| 	solid state media suitable for disk use in FreeBSD, kernel options
 | |
| 	that are of interest in such an environment, the
 | |
| 	<filename>rc.diskless</filename> mechanisms that automate the
 | |
| 	initialization of such systems and the need for read-only filesystems,
 | |
| 	and building filesystems from scratch.  The article will conclude
 | |
| 	with some general strategies for small and read-only FreeBSD
 | |
| 	environments.</para>
 | |
|     </abstract>
 | |
|   </articleinfo>
 | |
| 
 | |
|   <sect1 id="intro">
 | |
|     <title>Solid State Disk Devices</title>
 | |
| 
 | |
|     <para>The scope of this article will be limited to solid state disk
 | |
|       devices made from flash memory.  Flash memory is a solid state memory
 | |
|       (no moving parts) that is non-volatile (the memory maintains data even
 | |
|       after all power sources have been disconnected).  Flash memory can
 | |
|       withstand tremendous physical shock and is reasonably fast (the flash
 | |
|       memory solutions covered in this article are slightly slower than a EIDE
 | |
|       hard disk for write operations, and much faster for read operations).
 | |
|       One very important aspect of flash memory, the ramifications of which
 | |
|       will be discussed later in this article, is that each sector has a
 | |
|       limited rewrite capacity.  You can only write, erase, and write again to
 | |
|       a sector of flash memory a certain number of times before the sector
 | |
|       becomes permanently unusable.  Although many flash memory products
 | |
|       automatically map bad blocks, and although some even distribute write
 | |
|       operations evenly throughout the unit, the fact remains that there
 | |
|       exists a limit to the amount of writing that can be done to the device.
 | |
|       Competitive units have between 1,000,000 and 10,000,000 writes per
 | |
|       sector in their specification.  This figure varies due to the
 | |
|       temperature of the environment.</para>
 | |
| 
 | |
|     <para>Specifically, we will be discussing ATA compatible compact-flash
 | |
|       units and the M-Systems Disk-On-Chip flash memory unit.  ATA compatible
 | |
|       compact-flash cards are quite popular as storage media for digital
 | |
|       cameras.  Of particular interest is the fact that they pin out directly
 | |
|       to the IDE bus and are compatible with the ATA command set.  Therefore,
 | |
|       with a very simple and low-cost adaptor, these devices can be attached
 | |
|       directly to an IDE bus in a computer.  Once implemented in this manner,
 | |
|       operating systems such as FreeBSD see the device as a normal hard disk
 | |
|       (albeit small).  The M-Systems Disk-On-Chip product is based on the same
 | |
|       underlying flash memory technology as ATA compatible compact-flash
 | |
|       cards, but resides in a DIP form factor and is not ATA compatible.  To
 | |
|       use such a device, not only must you install it on a motherboard that
 | |
|       has a Disk-On-Chip socket, you must also build the `fla` driver into any
 | |
|       FreeBSD kernel you wish to use it with.  Further, there is critical,
 | |
|       manufacturer-specific data residing in the boot sector of this device,
 | |
|       so you must take care not to install the FreeBSD (or any other) boot
 | |
|       loader when using this.</para>
 | |
| 
 | |
|     <para>Other solid state disk solutions do exist, but their expense,
 | |
|       obscurity, and relative unease of use places them beyond the scope of
 | |
|       this article.</para>
 | |
|   </sect1>
 | |
| 
 | |
|   <sect1 id="kernel">
 | |
|       <title>Kernel Options</title>
 | |
| 
 | |
|     <para>A few kernel options are of specific interest to those creating
 | |
|       an embedded FreeBSD system.</para>
 | |
| 
 | |
|     <para>First, all embedded FreeBSD systems that use flash memory as system
 | |
|       disk will be interested in memory disks and memory filesystems.  Because
 | |
|       of the limited number of writes that can be done to flash memory, the
 | |
|       disk and the filesystems no the disk will most likely be mounted
 | |
|       read-only.  In this environment, filesystems such as
 | |
|       <filename>/tmp</filename> and <filename>/var</filename> are mounted as
 | |
|       memory filesystems to allow the system to create logs and update
 | |
|       counters and temporary files.  Memory filesystems are a critical
 | |
|       component to a successful solid state FreeBSD implementation.</para>
 | |
| 
 | |
|     <para>You should make sure the following lines exist in your kernel
 | |
|       configuration file:</para>
 | |
| 
 | |
|     <programlisting>options         MFS             # Memory Filesystem
 | |
| options         MD_ROOT         # md device usable as a potential root device
 | |
| pseudo-device   md              # memory disk</programlisting>
 | |
| 
 | |
|     <para>Second, if you will be using the M-Systems Disk-On-Chip product, you
 | |
|       must also include this line:</para>
 | |
| 
 | |
|     <programlisting>device          fla0    at isa?</programlisting>
 | |
|   </sect1>
 | |
| 
 | |
|   <sect1 id="ro-fs">
 | |
|     <title><filename>rc.diskless</filename> and Read-Only Filesystems</title>
 | |
| 
 | |
|     <para>The post-boot initialization of an embedded FreeBSD system is
 | |
|       controlled by <filename>/etc/rc.diskless2</filename>
 | |
|       (<filename>/etc/rc.diskless1</filename> is for BOOTP diskless boot).
 | |
|       This initialization script is invoked by placing a line in
 | |
|       <filename>/etc/rc.conf</filename> as follows:</para>
 | |
| 
 | |
|     <programlisting>diskless_mount=/etc/rc.diskless2</programlisting>
 | |
| 
 | |
|     <para><filename>rc.diskless2</filename> mounts <filename>/var</filename>
 | |
|       as a memory filesystem, makes a configurable list of directories in
 | |
|       <filename>/var</filename> with the &man.mkdir.1; command, changes modes
 | |
|       on some of those directories, and extracts a list of device entries to
 | |
|       copy to a writable (again, a memory filesystem)
 | |
|       <filename>/dev</filename> partition.  In the execution of
 | |
|       <filename>/etc/rc.diskless2</filename>, one other
 | |
|       <filename>rc.conf</filename> variable comes into play -
 | |
|       <literal>varsize</literal>.  The <filename>/etc/rc.diskless2</filename>
 | |
|       file creates a <filename>/var</filename> partition based on the value of
 | |
|       this variable in <filename>rc.conf</filename>:</para>
 | |
| 
 | |
|     <programlisting>varsize=8192</programlisting>
 | |
| 
 | |
|     <para>Remember that this value is in sectors.  The creation of the
 | |
|       <filename>/dev</filename> partition by
 | |
|       <filename>/etc/rc.diskless2</filename>, however, is governed by a
 | |
|       hard-coded value of 4096 sectors.  It is trivial to change this entry in
 | |
|       the <filename>/etc/rc.diskless2</filename> file itself, although you
 | |
|       should not need more space than that for
 | |
|       <filename>/dev</filename>.</para>
 | |
| 
 | |
|     <para>It is important to remember that the
 | |
|       <filename>/etc/rc.diskless2</filename> script assumes that you have
 | |
|       already removed your conventional <filename>/tmp</filename> partition
 | |
|       and replaced it with a symbolic link to <filename>/var/tmp</filename>.
 | |
|       Because <filename>tmp</filename> is one of the directories created in
 | |
|       <filename>/var</filename> by the <filename>/etc/rc.diskless2</filename>
 | |
|       script, and because <filename>/var</filename> is a memory filesystem
 | |
|       (which is mounted read-write), <filename>/tmp</filename> will now be a
 | |
|       directory that is read-write as well.</para>
 | |
| 
 | |
|     <para>The fact that <filename>/var</filename> and
 | |
|       <filename>/dev</filename> are read-write filesystems is an important
 | |
|       distinction, as the <filename>/</filename> partition (and any other
 | |
|       partitions you may have on your flash media) should be mounted
 | |
|       read-only.  Remember that in <xref linkend="intro"> we detailed the
 | |
|       limitations of flash memory - specifically the limited write capability.
 | |
|       The importance of not mounting filesystems on flash media read-write,
 | |
|       and the importance of not using a swap file cannot be overstated.  A
 | |
|       swap file on a busy system can burn through a piece of flash media in
 | |
|       less than one year. Heavy logging or temporary file creation and
 | |
|       destruction can do the same.  Therefore, in addition to removing the
 | |
|       <literal>swap</literal> and <literal>/proc</literal> entries from your
 | |
|       <filename>/etc/fstab</filename> file, you should also change the Options
 | |
|       field for each filesystem to <literal>ro</literal> as follows:</para>
 | |
| 
 | |
|     <programlisting># Device                Mountpoint      FStype  Options         Dump    Pass#
 | |
| /dev/ad0s1a             /               ufs     ro              1       1</programlisting>
 | |
| 
 | |
|     <para>A few applications in the average system will immediately begin to
 | |
|       fail as a result of this change.  For instance, ports will not install
 | |
|       from the ports tree because the
 | |
|       <filename>/var/db/port.mkversion</filename> file does not exist.  cron
 | |
|       will not run properly as a result of missing cron tabs in the
 | |
|       <filename>/var</filename> created by
 | |
|       <filename>/etc/rc.diskless2</filename>, and syslog and dhcp will
 | |
|       encounter problems as well as a result of the read-only filesystem and
 | |
|       missing items in the <filename>/var</filename> that
 | |
|       <filename>/etc/rc.diskless2</filename> has created.  These are only
 | |
|       temporary problems though, and are addressed, along with solutions to
 | |
|       the execution of other common software packages in
 | |
|       <xref linkend="strategies">.</para>
 | |
| 
 | |
|     <para>An important thing to remember is that a filesystem that was mounted
 | |
|       read-only with <filename>/etc/fstab</filename> can be made read-write at
 | |
|       any time by issuing the command:</para>
 | |
| 
 | |
|     <screen>&prompt.root; <userinput>/sbin/mount -uw <replaceable>partition</replaceable></userinput></screen>
 | |
| 
 | |
|     <para>and can be toggled back to read-only with the command:</para>
 | |
| 
 | |
|     <screen>&prompt.root; <userinput>/sbin/mount -ur <replaceable>partition</replaceable></userinput></screen>
 | |
|   </sect1>
 | |
| 
 | |
|   <sect1>
 | |
|     <title>Building a File System From Scratch</title>
 | |
| 
 | |
|     <para>Because ATA compatible compact-flash cards are seen by FreeBSD as
 | |
|       normal IDE hard drives, as is a M-Systems Disk-On-Chip product (when you
 | |
|       are running a kernel with the fla driver built in) you could
 | |
|       theoretically install FreeBSD from the network using the kern and
 | |
|       mfsroot floppies or from a CD.  Other than the fact that you should not
 | |
|       write a boot-loader of any kind to the M-Systems device, no special
 | |
|       instructions are needed.</para>
 | |
| 
 | |
|     <para>However, even a small installation of FreeBSD using normal
 | |
|       installation procedures can produce a system in size of greater than 200
 | |
|       megabytes.  Because most people will be using smaller flash memory
 | |
|       devices (128 megabytes is considered fairly large - 32 or even 16
 | |
|       megabytes is common) an installation using normal mechanisms is not
 | |
|       possible—there is simply not enough disk space for even the
 | |
|       smallest of conventional installations.</para>
 | |
| 
 | |
|     <para>The easiest way to overcome this space limitation is to install
 | |
|       FreeBSD using conventional means to a normal hard disk.  After the
 | |
|       installation is complete, pare down the operating system to a size that
 | |
|       will fit onto your flash media, then tar the entire filesystem.  The
 | |
|       following steps will guide you through the process of preparing a piece
 | |
|       of flash memory for your tarred filesystem.  Remember, because a normal
 | |
|       installation is not being performed, operations such as partitioning,
 | |
|       labeling, file-system creation, etc. need to be performed by hand.  In
 | |
|       addition to the kern and mfsroot floppy disks, you will also need to use
 | |
|       the fixit floppy.  If you are using a M-Systems Disk-On-Chip, the kernel
 | |
|       on your kern floppy must have the <literal>fla</literal> option detailed
 | |
|       in <xref linkend="kernel"> compiled into it.  Please see
 | |
|       <xref linkend="kern.flp"> for instructions on creating a new kernel for
 | |
|       <filename>kern.flp</filename>.</para>
 | |
| 
 | |
|     <procedure>
 | |
|       <step>
 | |
| 	<title>Partitioning your flash media device</title>
 | |
| 
 | |
| 	<para>After booting with the kern and mfsroot floppies, choose
 | |
| 	  <literal>custom</literal> from the installation menu.  In the custom
 | |
| 	  installation menu, choose <literal>partition</literal>.  In the
 | |
| 	  partition menu, you should delete all existing partitions using the
 | |
| 	  <keycap>d</keycap> key.  After deleting all existing partitions,
 | |
| 	  create a partition using the <keycap>c</keycap> key and accept the
 | |
| 	  default value for the size of the partition.  When asked for the
 | |
| 	  type of the partition, make sure the value is set to
 | |
| 	  <literal>165</literal>.  Now write this partition table to the disk
 | |
| 	  by pressing the <keycap>w</keycap> key (this is a hidden option on
 | |
| 	  this screen).  When presented with a menu to choose a boot manager,
 | |
| 	  take care to select <literal>None</literal> if you are using an
 | |
| 	  M-Systems Disk-On-Chip.  If you are using a ATA compatible compact
 | |
| 	  flash card, you should choose the FreeBSD Boot Manager.  Now press
 | |
| 	  the <keycap>q</keycap> key to quit the partition menu.  You will be
 | |
| 	  shown the boot manager menu once more - repeat the choice you made
 | |
| 	  earlier.</para>
 | |
|       </step>
 | |
| 
 | |
|       <step>
 | |
| 	<title>Creating filesystems on your flash memory device</title>
 | |
| 
 | |
| 	<para>Exit the custom installation menu, and from the main
 | |
| 	  installation menu choose the <literal>fixit</literal> option.  After
 | |
| 	  entering the fixit environment, enter the following commands:</para>
 | |
| 
 | |
| 	<informaltable frame="none">
 | |
| 	  <tgroup cols="2">
 | |
| 	    <thead>
 | |
| 	      <row>
 | |
| 		<entry align="center">ATA compatible</entry>
 | |
| 
 | |
| 		<entry align="center">Disk-On-Chip</entry>
 | |
| 	      </row>
 | |
| 	    </thead>
 | |
| 	    <tbody>
 | |
| 	      <row>
 | |
| 		<entry><para><screen>&prompt.root; <userinput>mknod /dev/ad0a c 116 0</userinput>
 | |
| &prompt.root; <userinput>mknod /dev/ad0c c 116 2</userinput>		      
 | |
| &prompt.root; <userinput>disklabel -e /dev/ad0c</userinput></screen></para></entry>
 | |
| 
 | |
| 		<entry><para><screen>&prompt.root; <userinput>mknod /dev/fla0a c 102 0</userinput>
 | |
| &prompt.root; <userinput>mknod /dev/fla0c c 102 2</userinput>
 | |
| &prompt.root; <userinput>disklabel -e /dev/fla0c</userinput></screen></para></entry>
 | |
| 	      </row>
 | |
| 	    </tbody>
 | |
| 	  </tgroup>
 | |
| 	</informaltable>
 | |
| 
 | |
| 	<para>At this point you will have entered the vi editor under the
 | |
| 	  auspices of the disklabel command.  If you are using Disk-On-Chip,
 | |
| 	  the first step will be to change the type value near the beginning
 | |
| 	  of the file from <literal>ESDI</literal> to
 | |
| 	  <literal>DOC2K</literal>.  Next, regardless of whether you are using
 | |
| 	  Disk-On-Chip or ATA compatible compact flash media, you need to add
 | |
| 	  an a: line at the end of the file.  This <literal>a:</literal> line
 | |
| 	  should look like:</para>
 | |
| 
 | |
| 	<programlisting>a:      <replaceable>123456</replaceable>  0       4.2BSD  0       0</programlisting>
 | |
| 
 | |
| 	<para>Where <replaceable>123456</replaceable> is a number that is
 | |
| 	  exactly the same as the number in the existing <literal>c:</literal>
 | |
| 	  entry for size. Basically you are duplicating the existing
 | |
| 	  <literal>c:</literal> line as an <literal>a:</literal> line, making
 | |
| 	  sure that fstype is <literal>4.2BSD</literal>.  Save the file and
 | |
| 	  exit.</para>
 | |
| 
 | |
| 	<informaltable frame="none">
 | |
| 	  <tgroup cols="2">
 | |
| 	    <thead>
 | |
| 	      <row>
 | |
| 		<entry align="center">ATA compatible</entry>
 | |
| 
 | |
| 		<entry align="center">Disk-On-Chip</entry>
 | |
| 	      </row>
 | |
| 	    </thead>
 | |
| 	    <tbody>
 | |
| 	      <row>
 | |
| 		<entry><para><screen>&prompt.root; <userinput>disklabel -B -r /dev/ad0c</userinput>
 | |
| &prompt.root; <userinput>newfs /dev/ad0a</userinput></screen></para></entry>
 | |
| 
 | |
| 		<entry><para><screen>&prompt.root; <userinput>disklabel -B -r /dev/fla0c</userinput>
 | |
| &prompt.root; <userinput>newfs /dev/fla0a</userinput></screen></para></entry>
 | |
| 	      </row>
 | |
| 	    </tbody>
 | |
| 	  </tgroup>
 | |
| 	</informaltable>
 | |
|       </step>
 | |
| 
 | |
|       <step>
 | |
| 	<title>Placing your filesystem on the flash media</title>
 | |
| 
 | |
| 	<para>Mount the newly prepared flash media:</para>
 | |
| 
 | |
| 	<informaltable frame="none">
 | |
| 	  <tgroup cols="2">
 | |
| 	    <thead>
 | |
| 	      <row>
 | |
| 		<entry align="center">ATA compatible</entry>
 | |
| 
 | |
| 		<entry align="center">Disk-On-Chip</entry>
 | |
| 	      </row>
 | |
| 	    </thead>
 | |
| 	    <tbody>
 | |
| 	      <row>
 | |
| 		<entry><para><screen>&prompt.root; <userinput>mount /dev/ad0a /flash</userinput></screen></para></entry>
 | |
| 
 | |
| 		<entry><para><screen>&prompt.root; <userinput>mount /dev/fla0a /flash</userinput></screen></para></entry>
 | |
| 	      </row>
 | |
| 	    </tbody>
 | |
| 	  </tgroup>
 | |
| 	</informaltable>
 | |
| 	
 | |
| 	<para>Bring this machine up on the network so we may transfer our tar
 | |
| 	  file and explode it onto our flash media filesystem.  One example of
 | |
| 	  how to do this is:</para>
 | |
| 
 | |
| 	<screen>&prompt.root; <userinput>ifconfig xl0 192.168.0.10 netmask 255.255.255.0</userinput>
 | |
| &prompt.root; <userinput>route add default 192.168.0.1</userinput></screen>
 | |
| 
 | |
| 	<para>Now that the machine is on the network, transfer your tar file.
 | |
| 	  You may be faced with a bit of a dilemma at this point - if your
 | |
| 	  flash memory part is 128 megabytes, for instance, and your tar file
 | |
| 	  is larger than 64 megabytes, you cannot have your tar file on the
 | |
| 	  flash media at the same time as you explode it - you will run out of
 | |
| 	  space.  One solution to this problem, if you are using FTP, is to
 | |
| 	  untar the file while it is transferred over FTP.  If you perform
 | |
| 	  your transfer in this manner, you will never have the tar file and
 | |
| 	  the tar contents on your disk at the same time:</para>
 | |
| 
 | |
| 	<screen><prompt>ftp></prompt> <userinput>get tarfile.tar "| tar xvf -"</userinput></screen>
 | |
| 
 | |
| 	<para>If your tarfile is gzipped, you can accomplish this as
 | |
| 	  well:</para>
 | |
| 
 | |
| 	<screen><prompt>ftp></prompt> <userinput>get tarfile.tar "| zcat | tar xvf -"</userinput></screen>
 | |
| 
 | |
| 	<para>After the contents of your tarred filesystem are on your flash
 | |
| 	  memory filesystem, you can unmount the flash memory and
 | |
| 	  reboot:</para>
 | |
| 
 | |
| 	<screen>&prompt.root; <userinput>cd /</userinput>
 | |
| &prompt.root; <userinput>umount /flash</userinput>
 | |
| &prompt.root; <userinput>exit</userinput></screen>
 | |
| 
 | |
| 	<para>Assuming that you configured your filesystem correctly when it
 | |
| 	  was built on the normal hard disk (with your filesystems mounted
 | |
| 	  read-only, and with the necessary options compiled into the kernel)
 | |
| 	  you should now be successfully booting your FreeBSD embedded
 | |
| 	  system.</para>
 | |
|       </step>
 | |
|     </procedure>
 | |
|   </sect1>
 | |
| 
 | |
|   <sect1 id="kern.flp">
 | |
|     <title>Building a <filename>kern.flp</filename> Installation Floppy with
 | |
|       the fla Driver</title>
 | |
| 
 | |
|     <note>
 | |
|       <para>This section of the article is relevant only to those using
 | |
| 	M-Systems Disk-On-Chip flash media.</para>
 | |
|     </note>
 | |
| 
 | |
|     <para>It is possible that your <filename>kern.flp</filename> boot floppy
 | |
|       does not have a kernel with the <devicename>fla</devicename> driver
 | |
|       compiled into it necessary for the system to recognize the Disk-On-Chip.
 | |
|       If you have booted off of the installation floppies and are told that no
 | |
|       disks are present, then you are probably lacking the
 | |
|       <devicename>fla</devicename> driver in your kernel.</para>
 | |
| 
 | |
|     <para>After you have built a kernel with <devicename>fla</devicename>
 | |
|       support that is smaller than 1.4 megabytes, you can create a custom
 | |
|       <filename>kern.flp</filename> floppy image with it by following these
 | |
|       instructions:</para>
 | |
| 
 | |
|     <procedure>
 | |
|       <step>
 | |
| 	<para>Obtain an existing kern.flp image file</para>
 | |
|       </step>
 | |
| 
 | |
|       <step>
 | |
| 	<para><screen>&prompt.root; <userinput>vnconfig vn0c kern.flp</userinput></screen></para>
 | |
|       </step>
 | |
| 
 | |
|       <step>
 | |
| 	<para><screen>&prompt.root; <userinput>mount /dev/vn0c /mnt</userinput></screen></para>
 | |
|       </step>
 | |
|       
 | |
|       <step>
 | |
| 	<para>Place your kernel file into <filename>/mnt</filename>, replacing
 | |
| 	  the existing one</para>
 | |
|       </step>
 | |
| 
 | |
|       <step>
 | |
| 	<para><screen>&prompt.root; <userinput>vnconfig -d vn0c</userinput></screen></para>
 | |
|       </step>
 | |
|     </procedure>
 | |
| 
 | |
|     <para>Your <filename>kern.flp</filename> file now has your new kernel on it.</para>
 | |
|   </sect1>
 | |
| 
 | |
|   <sect1 id="strategies">
 | |
|     <title>System Strategies for Small and Read Only Environments</title>
 | |
| 
 | |
|     <para>In <xref linkend="ro-fs">, it was pointed out that the
 | |
|       <filename>/var</filename> filesystem constructed by
 | |
|       <filename>/etc/rc.diskless2</filename> and the presence of a read-only
 | |
|       root filesystem causes problems with many common software packages used
 | |
|       with FreeBSD.  In this article, suggestions for successfully running
 | |
|       cron, syslog, ports installations, and the Apache web server will be
 | |
|       provided.</para>
 | |
| 
 | |
|     <sect2>
 | |
|       <title>cron</title>
 | |
| 
 | |
|       <para>In <filename>/etc/rc.diskless2</filename> there is a variable
 | |
| 	named <literal>var_dirs</literal>.  This variable consists of a
 | |
| 	space-delimited list of directories that will be created inside of
 | |
| 	<filename>/var</filename> after it is mounted as a memory filesystem.
 | |
| 	<filename>cron</filename> and <filename>cron/tabs</filename> are not
 | |
| 	in that list, and without those directories, cron will complain.  By
 | |
| 	inserting <literal>cron</literal>, <literal>cron/tabs</literal>, and
 | |
| 	perhaps even <literal>at</literal>, and <literal>at/jobs</literal> as
 | |
| 	elements of that variable, you will facilitate the running of the
 | |
| 	&man.cron.8; and &man.at.1; daemons.</para>
 | |
| 
 | |
|       <para>However, this still does not solve the problem of maintaining cron
 | |
| 	tabs across reboots.  When the system reboots, the
 | |
| 	<filename>/var</filename> filesystem that is in memory will disappear
 | |
| 	and any cron tabs you may have had in it will also disappear.
 | |
| 	Therefore, one solution would be to create cron tabs for the users
 | |
| 	that need them, mount your <filename>/</filename> filesystem as
 | |
| 	read-write and copy those cron tabs to somewhere safe, like
 | |
| 	<filename>/etc/tabs</filename>, then add a line to the end of
 | |
| 	<filename>/etc/rc.diskless2</filename> that copies those crontabs into
 | |
| 	<filename>/var/cron/tabs</filename> after that directory has been
 | |
| 	created during system initialization.  You may also need to add a line
 | |
| 	that changes modes and permissions on the directories you create and
 | |
| 	the files you copy with <filename>/etc/rc.diskless2</filename>.</para>
 | |
|     </sect2>
 | |
| 
 | |
|     <sect2>
 | |
|       <title>syslog</title>
 | |
| 
 | |
|       <para><filename>syslog.conf</filename> specifies the locations of
 | |
| 	certain log files that exist in <filename>/var/log</filename>.  These
 | |
| 	files are not created by <filename>/etc/rc.diskless2</filename> upon
 | |
| 	system initialization. Therefore, somewhere in
 | |
| 	<filename>/etc/rc.diskless2</filename>, after the section that creates
 | |
| 	the directories in <filename>/var</filename>, you will need to add
 | |
| 	something like this:</para>
 | |
| 
 | |
|       <screen>&prompt.root; <userinput>touch /var/log/security /var/log/maillog /var/log/cron /var/log/messages</userinput>
 | |
| &prompt.root; <userinput>chmod 0644 /var/log/*</userinput></screen>
 | |
| 
 | |
|       <para>You will also need to add the log directory to the list of
 | |
| 	directories that <filename>/etc/rc.diskless2</filename>
 | |
| 	creates.</para>
 | |
|     </sect2>
 | |
| 
 | |
|     <sect2>
 | |
|       <title>ports installation</title>
 | |
| 
 | |
|       <para>Before discussing the changes necessary to successfully use the
 | |
| 	ports tree, a reminder is necessary regarding the read-only nature of
 | |
| 	your filesystems on the flash media.  Since they are read-only, you
 | |
| 	will need to temporarily mount them read-write using the mount syntax
 | |
| 	shown in <xref linkend="ro-fs">.  You should always remount those
 | |
| 	filesystems read-only when you are done with any maintenance - it is
 | |
| 	dangerous to leave them in read-write mode lest a process begin
 | |
| 	logging or otherwise writing regularly to the flash media and wearing
 | |
| 	it out over time.</para>
 | |
| 
 | |
|       <para>To make it possible to enter a ports directory and successfully
 | |
| 	run <command>make install</command>, it is necessary for the file
 | |
| 	<filename>/var/db/port.mkversion</filename> to exist, and that it have
 | |
| 	a correct date in it.  Further, we must create a packages directory on
 | |
| 	a non-memory filesystem that will keep track of our packages across
 | |
| 	reboots. Because it is necessary to mount your filesystems as
 | |
| 	read-write for the installation of a package anyway, it is sensible to
 | |
| 	assume that an area on the flash media can also be used for package
 | |
| 	information to be written to.</para>
 | |
| 
 | |
|       <para>First, create a package database directory.  This is normally in
 | |
| 	<filename>/var/db/pkg</filename>, but we cannot place it there as it
 | |
| 	will disappear every time the system is booted.</para>
 | |
| 
 | |
|       <screen>&prompt.root; <userinput>mkdir /etc/pkg</userinput></screen>
 | |
| 
 | |
|       <para>Now, add a line to <filename>/etc/rc.diskless2</filename> that
 | |
| 	links the <filename>/etc/pkg</filename> directory to
 | |
| 	<filename>/var/db/pkg</filename>.  An example:</para>
 | |
| 
 | |
|       <screen>&prompt.root; <userinput>ln -s /etc/pkg /var/db/pkg</userinput></screen>
 | |
|       
 | |
|       <para>Add another line in <filename>/etc/rc.diskless2</filename> that
 | |
| 	creates and populates
 | |
| 	<filename>/var/db/port.mkversion</filename></para>
 | |
| 
 | |
|       <screen>&prompt.root; <userinput>touch /var/db/port.mkversion</userinput>
 | |
| &prompt.root; <userinput>chmod 0644 /var/db/port.mkversion</userinput>
 | |
| &prompt.root; <userinput>echo <replaceable>20010412</replaceable> >> /var/db/port.mkversion</userinput></screen>
 | |
| 
 | |
|       <para>where <replaceable>20010412</replaceable> is a date that is
 | |
| 	appropriate for your particular release of FreeBSD</para>
 | |
| 
 | |
|       <para>Now, any time that you mount your filesystems as read-write and
 | |
| 	install a package, the <command>make install</command> will work
 | |
| 	because it finds a suitable
 | |
| 	<filename>/var/db/port.mkversion</filename>, and package information
 | |
| 	will be written successfully to <filename>/etc/pkg</filename> (because
 | |
| 	the filesystem will, at that time, be mounted read-write) which will
 | |
| 	always be available to the operating system as
 | |
| 	<filename>/var/db/pkg</filename>.</para>
 | |
|     </sect2>
 | |
| 
 | |
|     <sect2>
 | |
|       <title>Apache Web Server</title>
 | |
| 
 | |
|       <para>Apache keeps pid files and logs in
 | |
| 	<filename><replaceable>apache_install</replaceable>/logs</filename>.
 | |
| 	Since this directory no doubt exists on a read-only filesystem, this
 | |
| 	will not work.  It is necessary to add a new directory to the
 | |
| 	<filename>/etc/rc.diskless2</filename> list of directories to create
 | |
| 	in <filename>/var</filename>, to link
 | |
| 	<filename><replaceable>apache_install</replaceable>/logs</filename> to
 | |
| 	<filename>/var/log/apache</filename>.  It is also necessary to set
 | |
| 	permissions and ownership on this new directory.</para>
 | |
| 
 | |
|       <para>First, add the directory <literal>log/apache</literal> to the list
 | |
| 	of directories to be created in
 | |
| 	<filename>/etc/rc.diskless2</filename>.</para>
 | |
|       
 | |
|       <para>Second, add these commands to
 | |
| 	<filename>/etc/rc.diskless2</filename> after the directory creation
 | |
| 	section:</para>
 | |
| 
 | |
|       <screen>&prompt.root; <userinput>chmod 0774 /var/log/apache</userinput>
 | |
| &prompt.root; <userinput>chown nobody:nobody /var/log/apache</userinput></screen>
 | |
| 
 | |
|       <para>Finally, remove the existing
 | |
| 	<filename><replaceable>apache_install</replaceable>/logs</filename>
 | |
| 	directory, and replace it with a link:</para>
 | |
| 
 | |
|       <screen>&prompt.root; <userinput>rm -rf (apache_install)/logs</userinput>
 | |
| &prompt.root; <userinput>ln -s /var/log/apache (apache_install)/logs</userinput></screen>
 | |
|     </sect2>
 | |
|   </sect1>
 | |
| </article>
 | |
| 
 |