This page contains a PicoBSD user/starter FAQ aimed primarily at first-time PicoBSD users who intend to experiment with embedded systems. PicoBSD is a version of FreeBSD built in such a way that it can be useful when you need a ``real'' BSD and TCP/IP stack in a complete system small enough to fit on a floppy. Once booted, PicoBSD runs out of RAM-disk. PicoBSD need not boot from a floppy; it can be used to boot from flash devices, to create a single ``self-contained'' and ``self-extracting'' netbootable file , etc.. PicoBSD is suitable for many PC-based embedded OS projects.
The primary purpose of this FAQ is to describe the PicoBSD build process under FreeBSD 4.3 Stable sufficiently for a new user to build and use PicoBSD for experimental embedded systems. Under different versions of FreeBSD these procedures may differ.
§ Operational tech notes
What is PicoBSD?
Building PicoBSD:
Quick! How do I build one of the standard PicoBSD systems?
Quick! How do I build my own version of PicoBSD?
What are some common errors and how do I deal with them?
How do I clean-up after a PicoBSD build?
What is the default PicoBSDrootpassword?
Thepicobsdbuild script:
What is the most current description of thepicobsdscript command?
What is the syntax of thepicobsdscript command?
What can I do with the script's main interactive dialog menu?
Whatvndevice housekeeping should I do?
PicoBSD configuration:
What is in a PicoBSD configuration directory?
What are the predefined ``reference'' configurations? Which one should I use?
Booting PicoBSD and editing boot scripts:
How does the PicoBSDrcboot script work?
How do I edit PicoBSD/etcscripts?
How do I edit or add new files to an existing floppy image file?
Using PicoBSD:
What are some command-line differences between FreeBSD and PicoBSD?
How do I include my own binary application in PicoBSD, that is, include them with the ``crunched'' applications in thekernelfile?
How do I write a binary application that I can download individually to PicoBSD without being ``crunched''?
How big is PicoBSD?
Does PicoBSD support hard disks?
How do I see how much space is used in PicoBSD filesystems?
§ Requirements
What ``host'' environment do I need to do embedded PicoBSD development?
What versions of FreeBSD doespicobsdrun under?
How do I get PicoBSD (FreeBSD)?
§ Internals and customization
How does the ``picobsd'' script work (how does all this happen)?
What istinyware?
What isoinit?
Where do the PicoBSD boot files on the floppy come from?
What makefile invokes the actual PicoBSD kernel compile?
How can I build a number of related PicoBSD systems?
How do I make a floppy from an existing PicoBSD floppy image file?
How do I compare FreeBSD and PicoBSD kernel images?
How do I find a string in an ELF kernel section?
§ Older/historical/related tech notes
What's an older way to build PicoBSD?
Can I download a bootable PicoBSD image?
Are there other ways to make small FreeBSD systems?
§ History and some non-tech notes
Who maintains PicoBSD?
Who developed PicoBSD?
What type of license is PicoBSD under?
What should I know about industrial and embedded PCs?
What are some university and academic groups using PicoBSD?
What are some disadvantages of PicoBSD?
What are some advantages of PicoBSD?
§ Documentation and Web resources
Whatmanpages should I read?
Where is the PicoBSD documentation?
How do I subscribe to thefreebsd-small@freebsd.orgmailing list?
How do I browse thefreebsd-small@freebsd.orgmailing list archives?
What PicoBSD-related web resources are available?
What are some academic references and web sites that describe research using PicoBSD?
§ A few useful embedded PicoBSD procedures (most will also work on FreeBSD)
How do I make PicoBSD on a PC run ``headless'' (without monitor and keyboard)?
How do I use PicoBSD to make a cheap diskless web server?
How do I use PicoBSD to make a cheap Internet-enabled instrument?
How do I directly access I/O devices from an application program (useinandoutinstructions)?
How do I put PicoBSD on a flash disk?
How do I put PicoBSD on a hard disk?
How can I debug kernel code using polled serial I/O?
PicoBSD is primarily just FreeBSD running from RAM-disk,
with all needed executable programs packed into a single executable
ELF file in the RAM-disk.
An entire PicoBSD system consists of a single bootable
kernel file, by default named kernel.
The initial contents of the RAM-disk,
which include the entire root filesystem,
are stored inside
the kernel file.
Because a PicoBSD system is usually compiled with
a ``minimal'' FreeBSD configuration that only
includes needed features,
and because there is only a single
ELF application file,
the kernel file can fit on a single floppy.
Additionally,
the kernel file is typically compressed
and is then uncompressed on boot.
PicoBSD is not another operating
system. PicoBSD is built from the same
sources as FreeBSD.
PicoBSD is built entirely using standard tools
and utilities available under FreeBSD.
The normal FreeBSD procedure to compile a
kernel is wrapped by a picobsd
script which builds a so-called crunched
application binary that contains all required
executable application programs.
The picobsd script builds
a root file system image that includes the crunched
applications and all required startup
scripts and configuration files.
It then inserts the file system image
into the kernel file itself.
A PicoBSD build is driven by a
private configuration directory which contains a
slightly embellished FreeBSD kernel configuration
file named PICOBSD.
A number of other
files in the configuration directory specify device
node names, desired filesystem directory structure,
script files, and the executable files to be included in
the kernel. The build itself
is driven by the
picobsd master script.
The picobsd script copies the
PICOBSD configuration file to the
configuration directory
normally used for FreeBSD x86 kernel compiles,
namely
/usr/src/sys/i386/conf.
(This document assumes the FreeBSD source tree has
been installed in /usr, if yours is
located elsewhere, adjust accordingly.)
The picobsd script is effectively the
definition of PicoBSD. It is located at:
/usr/src/release/picobsd/build/picobsd
The FreeBSD
crunchgen
program does the ``crunch'' of all application object files;
it essentially relabels the main()
entry points in all the application's object files
and creates a
single application main() that dispatches
to the required program based on the name by which
the program is invoked. All object files are
linked together to produce a single ELF executable file.
Virtual filesystems are created using the FreeBSD vn
(Virtual Node)
driver.
The vn driver
enables a file to be treated as a device (you can then
mount a suitable initialized file).
The filesystem created by the picobsd script
contains a root directory tree and files
as specified by an mtree configuration
file and a directory
tree rooted in the user's private configuration directory. This
virtual filesystem image is
copied into a reserved space in the kernel
image file.
After the kernel file is created, a second filesystem
is created
on a virtual device file
named ``picobsd.bin''.
This file corresponds to a floppy device image. The kernel
file is compressed and placed in this filesystem,
bootblocks are copied to the floppy image, and the entire
floppy image is then physically copied to a floppy.
The FreeBSD boot program (which is really a very
small operating system in it's own right) simply scans the root
directory of the device it boots from searching for
a file named kernel (or a file of another
name, if so indicated by the user entering a filename
in response to the boot prompt's ``count-down''). This
is the file that is loaded (and uncompressed, if necessary).
This process is entirely driven by the kernel's filename (there are
no hard-coded ``magic pointers'' to the code of
the kernel to be
loaded and started, although there are hard-coded pointers
to the boot system's code).
A number of predefined ``private'' PicoBSD configuration directories are provided which build standard configurations of PicoBSD and serve as examples, templates, and starting points. In this document, these are called reference configurations and reference directories. These directories are used for reference builds, and produce reference PicoBSD systems.
In practice, PicoBSD is often used as a starting point for forking your own custom embedded system projects. That is, rather than simply deploying the predefined standard reference configurations, it may well be that most serious users of PicoBSD historically have been software engineers who have a valid reason to fork their own unique embedded system code-base. This can be a very reasonable thing to do because commercial embedded systems often have very long product lifecycles (decades) while potentially requiring maintenance at any level during the entire deployment of the product. The entire PicoBSD environment is flavored in many ways by this expectation.
There have been numerous custom variations of PicoBSD, and variations on this entire scheme. For instance, you could have more than one file of crunched applications, putting each such file on a seperate floppy image and distributing your system on multiple floppies.
The PicoBSD sources in
/usr/src/release/picobsd
contain a number
of ``preconfigured'' PicoBSD configurations.
These configurations
each correspond to an existing reference configuration directory.
The current reference directories are
bridge,
custom,
net,
dial,
install,
isp,
and
router.
These may not work ``as-is'', so treat them
as starter kits (these reference configurations are, however,
maintained, so notify the
``freebsd-small@freebsd.org''
mailing list if you encounter a problem).
* Assure you are running
a version of FreeBSD 4.3 Stable
that includes the
vn device. Check the
current system's kernel configuration file for:
pseudo-device vnYou may have to recompile the FreeBSD kernel and possibly rebuild the ``
/dev/vn*'' device nodes (UseMAKEDEV. This is normally not required.)
* Verify that you have a free vn device
using:
#mountIf you see a mounted filesystem of the form ``
/dev/vn0c on /tmp/picobsd.c2OlSJv7sk'', it is likely that a previous build ofpicobsdhas failed. See the section on freeing avndevice that has been left in an in-use state.
* You will need a formatted blank floppy for a standard PicoBSD build. Insert the floppy in the drive, but do not mount the floppy.
* Select which configuration you want to build. The attributes of the various configurations are explained in more detail in the section that discusses the predefined reference configurations.
* Copy the PicoBSD build script
/usr/src/release/picobsd/build/picobsd
into your path, for instance, into
/usr/bin or /usr/local/bin:
#su #cp /usr/src/release/picobsd/build/picobsd /usr/local/sbin #rehashObviously, you only need to do this step once.
* Build your selected configuration.
For instance, to build the
PicoBSD router reference system
located in
/usr/src/release/picobsd/router,
do the following in the directory that you want to become
the ``root'' of your PicoBSD work:
#su
#picobsd router
You have to be root to run the
picobsdscript. At the start of the script's execution, you will be prompted by a dialog menu. Hit return to continue. A FreeBSD kernel-build will then occur, followed by object file crunching. Finally a second menu will appear. Assure the floppy is physically inserted and hit return to write the floppy with a bootable image.
* Take the floppy to
the system on which you want to run PicoBSD, and
boot the floppy (or reboot the running system,
if you want to simply bring up a sample PicoBSD).
You do not have to umount the floppy.
Be sure to check the machine's
BIOS settings and assure that it is
set to boot from the floppy.
That's it...
After a successful PicoBSD build, in addition
to putting a bootable image on the floppy, there
will be a bootable file named
kernel in the build directory
located in the directory in which the picobsd
script was run.
For instance, if a router
configuration build was done,
the directory
build_dir-router will exist
in the
directory from which you ran picobsd.
A binary image of the bootable floppy, named ``picobsd.bin'',
will also exist in this build_dir-router
directory. The complete directory name
depends on the name of your configuration
(in this case, router).
If you [Cancel] from the last menu (use Tab
to select the [Cancel] button and then press Enter),
the kernel and ``picobsd.bin'' files will both
be created but the floppy will not be written.
§ Host Requirements.
* Assure you are running
a version of FreeBSD 4.3 Stable
that includes the
vn device. Check the
current system's kernel configuration file for:
pseudo-device vnYou may have to recompile the FreeBSD kernel and possibly rebuild the ``
/dev/vn*'' device nodes (UseMAKEDEV. This is normally not required.)
* Verify that you have a free vn device
using:
#mountIf you see a mounted filesystem of the form ``
/dev/vn0c on /tmp/picobsd.c2OlSJv7sk'', it is likely that a previous build ofpicobsdhas failed. See the section on freeing avndevice that has been left in an in-use state.
§ Assure the picobsd script is in your path.
Copy the PicoBSD build script
/usr/src/release/picobsd/build/picobsd
into your path, for instance, into
/usr/bin or /usr/local/bin:
#su
#cp /usr/src/release/picobsd/build/picobsd /usr/local/sbin
#rehash
§ Create your own PicoBSD configuration directory.
To work with your own configuration of PicoBSD, you need your own private configuration directory. Using FreeBSD 4.3 and later versions, this ``config'' directory can be anywhere. In previous versions, you created this directory as root in /usr/src/release/picobsd. You can still use this older style. The remainder of this section assumes a post-4.3 build. See the following section for pre-4.3 instructions.
Create your new configuration directory somewhere with the
name you want to give your custom PicoBSD configuration.
It is useful to base the initial contents of
this configuration directory on one of the
standard reference directories.
For instance, to create a configuration directory named
mysys, based on the
bridge reference configuration,
use:
#cp -R /usr/src/release/picobsd/bridge mysys
The reference configurations are directories
located in
/usr/src/release/picobsd.
The current reference configurations are
bridge,
custom,
net,
dial,
install,
isp,
and
router.
These may not work ``as-is'', so treat them
as starter kits (these reference configurations are, however,
maintained, so notify the
``freebsd-small@freebsd.org''
mailing list if you encounter a problem).
§ Build PicoBSD using the picobsd script.
Before modifying your initial configuration, you may want to do a test-build with it as-is.
To do a complete PicoBSD build, you need a formatted
and verified floppy. Assure that the floppy device (/dev/fd0c)
is not mounted, as the script writes ``raw'' to
the floppy using dd.
You have to be root to run the picobsd
script.
Assume you have created a work directory that you want to make the
``root'' of your PicoBSD work. In this directory you have created
a directory called mysys that contains a copy of one
of the standard PicoBSD configurations. To build your mysys
configuration, cd to the work directory and
do the following:
#su #picobsd mysys
At the start of the script's execution, you will be prompted by a dialog menu. Hit return to continue. A FreeBSD kernel-build will then occur, followed by object file crunching. Finally a second menu will appear. Insert a floppy and hit return to write the floppy with a bootable image. Take the floppy to the system on which you want to run PicoBSD, and boot the floppy (or reboot the running system). Be sure to check the machine's BIOS settings and assure that it is set to boot from the floppy.
After the PicoBSD script completes,
the floppy contains a mountable and bootable filesystem.
You might want to mount it for verification.
Once PicoBSD has booted from the floppy on the
target machine and completed
its rc boot script, the floppy will
not be mounted. On
the reference systems, you can interactively mount the
floppy when PicoBSD is running on the target.
Results of the example build are left in the
``./build_dir-mysys''
directory automatically created in the directory in which
you ran picobsd.
After a successful PicoBSD build, in addition
to putting a bootable image on the floppy, there
will be a bootable file named
kernel in this build directory.
A binary image of the bootable floppy, named ``picobsd.bin'',
will also exist in this build
directory. The complete name of the build directory
depends on the name of your configuration directory
(in this case, mysys).
If you [Cancel] from the last menu (use Tab
to select the [Cancel] button and then press Enter),
the kernel and ``picobsd.bin'' files will both
be created but the floppy will not be written.
The picobsd script puts all executables and an image of a
RAM-based root filesystem into the single kernel
file. The kernel file in the floppy image
is compressed (the kernel will be
uncompressed at boot-time).
The kernel file in the build_dir
directory is not compressed.
You can explicitly compress the kernel
file using the
kgzip utility.
The picobsd script looks for a configuration directory
with a name that matches its argument.
It first looks in the current directory.
It then looks for a directory with matching name in
``$PICO_TREE''.
If undefined, $PICO_TREE'' defaults to
``/usr/src/release/picobsd/''.
For example, ``picobsd mysys'' would first look
for ``./mysys'', then for
``/usr/src/release/picobsd/mysys''.
Once a directory is found, it is assumed to be a PicoBSD
configuration directory if a PICOBSD configuration file
is present.
§ Customize your PicoBSD configuration.
In your private configuration directory:
* Edit the PICOBSD kernel configuration
file to contain
your desired FreeBSD kernel options and device
support.
* In
file config, add your desired
/dev device nodes.
* In file ``crunch.conf'' specify
the executables and libraries that you
want to include, and the ``link names'' that you want
to assign your executables.
You also need to specify the directories containing your
binary program Makefiles.
* Put the script files to include in your system
in a
directory tree named
``floppy.tree''
rooted in your configuration directory.
You may have to create this directory.
You can also put in your configuration directory
a file called ``floppy.tree.exclude''
which specifies what files are to
be eliminated
from the default in
``
/usr/src/release/picobsd/floppy.tree''.
NOTE: The script files
typically included in the
``floppy.tree''
have traditionally been those files that you might want to edit
after your system is operational. If
you want to edit all these files on the floppy, you do not
want these files built into the single kernel file,
but rather want to put them in a /etc
directory tree on the floppy. The files inside the compressed
kernel image on the floppy cannot readily be accessed directly
by standard tools (a copy of these file
can be edited on the RAM-disk
when the system is running, which means you can then copy them
to a directory on the floppy).
The current default behavior of the
picobsd script is not to put the
``floppy.tree'' on the floppy, but
rather to put all the contents of the ``floppy.tree''
into the kernel file, and then
use a PicoBSD rc boot script that copies, prior
to most boot script processing,
any files in /etc on the floppy over the files
in /etc in the memory filesystem.
In this scheme there initially
is no /etc directory on the floppy. To change
this default behavior and put the ``floppy.tree'' on the floppy,
edit the picobsd script and, near the top, change
the first line in init_vars() from:
INCLUDE_FLOPPY_IN_MFS="yes"
To:
INCLUDE_FLOPPY_IN_MFS="no"
The default ``floppy.tree'' is located in the
``
/usr/src/release/picobsd/floppy.tree'' directory.
This tree forms the ``base'' floppy script collection. Files that
you define in the ``floppy.tree'' directory within your private
configuration directory will override or extend the base collection.
You do not need a private ``floppy.tree'' directory.
You can exclude files in the base collection using a
file in your configuration directory named ``floppy.tree.exclude''.
* The files included in the
/usr/src/release/picobsd/mfs_tree
directory tree
are the initial files included in the root file system built into the
kernel file. Note that if the ``floppy.tree''
is included in the MFS, as described above, floppy files
will override files with the same name in mfs_tree.
You can specify a complete directory tree structure for the
root file system using a
``mfs.mtree'' file in your configuration directory
This is optional, and
can be used to create empty directories in addition
to those populated by mfs_tree and
``floppy.tree'' files.
After customization, rebuild your PicoBSD system
as described in the previous section on building
PicoBSD using the picobsd script.
After most errors that abort the picobsd script,
it is usually worth completely cleaning up the build
that was aborted as described in the section
``How do I clean-up after a PicoBSD build?''.
Also, use mount to check if any vn
pseudo-devices are still mounted and configured.
Some common errors are:
§ After a kernel link in the picobsd script,
an error of the following form
appears:
If the host FreeBSD system contains the
disklabel: /dev/vn1: No such file or directory
---> fail: Error <4> error code
vn pseudo-device,
this typically means that the prior execution of picobsd
failed, leaving the vn0 device in a mounted state.
Check the mount-status of the vn device(s)
using mount.
If a vn device has been left
in a mounted (and configured) state,
you will see something similar to:
/dev/vn0c on /var/vartmp/picobsd.c2OlSJv7sk (ufs, local)
Manually dismount and unconfigure the
offending vn device:
#mount
#umount /dev/vn0c
#vnconfig -u vn0
It is a good idea to
clean up the remains
of the PicoBSD build that died before
attempting another picobsd build.
When is starts, the picobsd
script tries to locate an unused vn device,
which is why in the above example error it complains about vn1 even
though it was vn0 that was not properly
unmounted and unconfigured (the system on which this error
occurred only had a single vn device
configured).
You should check the vn devices in this manner
whenever the picobsd script fails for any reason.
§ If an error message such as the following occurs
that involves a binary included in
PicoBSD, the pathname in the relevant ``crunch.conf''
referencing the binary file
is probably inconsistent
with the real directory structure:
`../../tinyware' is not a directory, skipping it
Perhaps things
have moved. Perhaps the ``crunch.conf'' file
assumes it is in the /usr/src/release/picobsd
tree. The fix is to set the path
correctly. An absolute path for your current
development system should work.
§ The build displays the following error toward the end of the script's execution:
MFS filesystem signature not found in kernel
The MFS filesystem image is too big to fit into the kernel.
The size of the MFS is specified either
interactively via the main dialog or as the first argument to the
#PICOBSD comment in the relevant PICOBSD
kernel configuration file.
The comment above the argument line
in the #PIOCBSD file indicates
that this argument is named
``dev_sz''.
When this argument changes, you need to also change the
kernel MD_ROOT_SIZE
option in the
PICOBSD file to have the same value. Indeed, a mismatch
between these values may be the cause of the error. A typical
option line is:
options MD_ROOT_SIZE=2200 # same as def_sz
This error may also indicate a missing
``options MD_ROOT_SIZE'' statement or a
MD_ROOT_SIZE parse
error, resulting in no MFS space at all being
configured into the kernel.
§ An error message is displayed on
the console at boot-time (or spotted later by dmesg) with
the form:
There are not enough inodes in the RAM-based MFS. Files are likely being copied from various
pid 8 (cp), uid 0 on /: out of inodes
/etc override
directories into the MFS. Since each file requires an inode
(Information Node) from the fixed-sized inode space,
when you are out of inodes you cannot create more files
(even if space still exists on the device).
Unless you are trying to include way to many files, you can often fix this by increasing the size of the static inode array in the MFS. This will decrease the amount of available free space that remains in the MFS for file data.
You can increase the number of inodes
either interactively, via the first picobsd
menu, or by editing the PICOBSD file in the
relevant configuration directory and changing the third argument
in the #PicoBSD line (the comment on the previous line
of the PICOBSD file
indicates this is named the ``MFS_inodes'' argument).
The fraction of space dedicated
in a filesystem to inodes instead of data is ultimately specified as an argument
to newfs, the utility that creates a new filesystem.
The form of this argument is not a direct specifier, but rather indicates
the number of bytes per inode, which is roughly the average file size
you expect in the file system. Thus, to increase the number of
inodes, you should decrease the existing MFS_inodes
value.
The layout of the MFS filesystem is reported by picobsd
near the end of the script before the second menu. It has an appearance
such as the following:
Filesystem 1K-blocks Used Avail Capacity iused ifree %iused Mounted on
/dev/vn0c 2103 1600 503 76% 308 202 60% /var/vartmp/picobsd.9QsMbDpD3K
This indicates that 308 inodes are in use and 202 are free, so
newfs calculated that it should allocate 510 inodes. Again,
you only indirectly control this allocation, but a little experimentation
will result in your ability to partition the filesystem as you desire.
§ You ftp a binary program to a PicoBSD system,
try to run it, and get the error message:
ELF interpreter /usr/libexec/ld-elf.so.1 not found Abort trap
The program was linked assuming that it could link to
a loaded library at run-time using dynamic linking,
but the specified library (ld-elf.so.1) was not found.
See the section on
writing a statically-linked application for
PicoBSD.
§ The first thing PicoBSD prints when it boots is:
No /boot/loader
Is this an error? No. This indicates that the interactive
FICL loader is not present (by design).
The bootstrap will procede to directly
boot the /kernel PicoBSD file.
§ Attempting to mount a PicoBSD floppy
on PicoBSD or FreeBSD always produces an
error (on any machine) similar to:
mount: /dev/fd0c: Operation not permitted
If this message occurs with a PicoBSD floppy whenever you attempt
to mount the floppy,
the floppy has likely, at some point, either (1) been mounted when
it was physically removed from a drive
without a umount being performed,
or (2) it was mounted when the
power was turned off. Use the dmesg command
to display the system error log and search for a message
such as the following (the /mnt will correspond to
whatever directory you tried to use as a mount-point for the floppy):
WARNING: R/W mount of /mnt denied. Filesystem is not clean - run fsck
Either run fsck against the floppy (``fsck /dev/fd0'')
or, if you are
absolutely certain of the machine from which you just ``popped'' it out
without unmounting, put the floppy back in the drive and umount
it before physically removing it again.
This is not a PicoBSD error per se, but can easily occur
when you are working with a PicoBSD floppy, for instance,
editing scripts or copying static applications.
Note that a FreeBSD-formatted *ix floppy ``knows'' if,
after being mounted,
it has been cleanly unmounted via a umount.
Under PicoBSD, the boot floppy can be in this unmountable state, that is,
it may not be possible to mount the boot floppy if it was explicitly
mounted when
a power-off occured (or it was popped out and moved).
This does not interfere with the ability
to boot the floppy, only the ability to mount it. Because
not all configurations include fsck, it may be necessary
to take the floppy to another FreeBSD or PicoBSD machine to run
fsck. The router and net
reference configurations do not include fsck.
To completely clean up a PicoBSD build, for example,
after a reference build using ``picobsd net'',
do the following:
*
#cd /usr/src/sys/compile
and delete thePICOBSD-netkernel build directory.*
#cd /usr/src/sys/i386/conf
and delete thePICOBSD-netkernel configuration file.*
#cd /usr
and delete theobj-picodirectory.* Go to the directory containing your
build_dirdirectory,
(for instance, ``cd /usr/src/release/picobsd/build'')
and delete thebuild_dir-netdirectory.*
#cd /tmp
and delete anypicobsd.XXXXXXXXXX(temporary name) directories. Also delete anyreply.XXXXXXXXXXtemporary file(s).
Note that only one obj-pico directory is created,
that is, versions are not created based on the
name of your configuration.
root password?
The default root password is ``setup''.
You should change this before you do a PicoBSD build.
Specify your accounts and passwords by directly editing
the relevant ``etc/master.passwd'' file.
Depending on your PicoBSD configuration tree, this
file could be in
``
/usr/src/release/picobsd/floppy.tree/etc/master.passwd'',
a ``floppy.tree/etc/master.passwd'' in your configuration
directory, or, also in your configuration directory,
a ``floppy.tree.$SITE_NAME/etc/master.passwd''
subconfiguration directory
corresponding to your subconfiguration $SITE_NAME
(which is specified as the optional second argument to picobsd,
see the
section on the syntax of the picobsd command).
You can change a password on a PicoBSD floppy using
the procedures described to
edit PicoBSD /etc scripts or
to
edit or add a file to
an existing floppy image.
picobsd script command?
The comments at the head of the picobsd script contain
the following:
# picobsd [options] floppy_type site_name
#
# Where floppy_type is a directory where the picobsd config info
# is held, and ${floppy_type}/floppy.tree.${site_name} contains
# optional site-specific configuration.
#
# For Options, see the bottom of the file where the processing is
# done... so
#
# This script depends on the following files:
#
# in ${PICO_TREE} :
# Makefile.conf Makefile used to build the kernel
# config shell variables, sourced here.
# mfs.mtree mtree config file
#
# floppy.tree/ files which go on the floppy
# mfs_tree/ files which go onto the mfs
#
# in ${MY_TREE} :
# PICOBSD kernel config file
# config shell variables, sourced here.
# crunch.conf crunchgen configuration
# floppy.tree.exclude files from floppy.tree/ which we do not need here.
# floppy.tree/ local additions to the floppy.tree
# floppy.tree.${site}/ same as above, site specific.
In the above, ${PICO_TREE} is the root of your
PicoBSD source tree, for instance,
/usr/src/release/picobsd.
The ${MY_TREE} directory is usually
either one of the
reference configuration directories, such as
/usr/src/release/picobsd/router,
or your own private configuration directory, which
can be located anywhere. You do not explictly
set ${MY_TREE}. The picobsd
script first looks for a directory with the same
name as it's floppy_type argument in
the directory from which you ran the script,
and then looks for a subdirectory with that
name in ${PICO_TREE}, which defaults
to ``/usr/src/release/picobsd''.
picobsd script command?
The command syntax of the picobsd script is:
#picobsd [options] floppy_type [site_name]
The floppy_type argument specifies
the name of an existing PicoBSD configuration directory.
The picobsd script will look for a directory with this name first in the current
directory and then in the directory
specified by the $PICO_TREE environment variable.
If you have not set this variable, it defaults to
``/usr/src/release/picobsd/''.
The optional site_name argument specifies the name
of a ``subconfiguration'' within the configuration directory specified by
floppy_type. The subconfiguration will itself be a
directory, with a name of the form ``floppy.tree.$site_name''.
This subconfiguration directory should contain a /etc directory
containing scripts and files which you want to replace those with
the same names in
the ``floppy.tree/etc'' directory in the same
configuration directory (that is, the directory corresponding
to floppy_type).
Thus, the command ``picobsd my_486 old_isa_486''
would first try to use the configuration directory ``./my_486''
and subconfiguration scripts in
``./my_486/floppy.tree.old_isa_486/etc''.
If no ``./my_486'' configuration directory was found,
picobsd would try to use
/usr/src/release/picobsd/my_486/ and
``/usr/src/release/picobsd/my_486/floppy.tree.old_isa_486/etc''.
The command options are:
--floppy_type n
The size of the bootable floppy image is set to ``n'' KBytes. The default is 1440, the size of a standard 3.5 inch floppy.
-n
Do not display the first interactive menu. The final interactive dialog, which prompts for permission to write to the floppy will occur, so this switch does not allow complete ``batch'' mode execution.
-clean
Delete thebuild_dirdirectory before starting. This directory will have a name of the formbuild_dir-mysys, wheremysysis the name of your PicoBSD configuration directory, as specified by argumentfloppy_type.
-verbose
This option makes the script enter a semi-interactive trace mode. It produces various output displays as it runs and stops after each display until user confirmation is recieved. This provides insight into the action taken by the script at each major step.
Environment Variables are:
$INCLUDE_FLOPPY_IN_MFS
In addition to the command-line arguments, there is an important environment variable set at the start of thepicobsdscript. This variable, ``INCLUDE_FLOPPY_IN_MFS'', should be set to ``yes'' if you want the contents of your ``floppy.tree'' to be placed, gzipped, into the/fddirectory in the MFS filesystem (the RAM-filesystem) built into the kernel. The files will be uncompressed and copied to your RAM-based/etcdirectory at boot, that is, they will be copied over the files originating in the/usr/src/release/picobsd/mfs_tree/etcdirectory. IfINCLUDE_FLOPPY_IN_MFSis not ``yes'', the files in your floppy tree will be placed on the floppy in/etc. From here they will also be copied over the memory-resident/etc. Note that even if you specifyINCLUDE_FLOPPY_IN_MFS="yes", you can later create a/etcon your floppy and put updated startup script files on the floppy. These files will be copied into/etcbefore other boot-time script processing occurs.The default is
INCLUDE_FLOPPY_IN_MFS="yes".
$SRC
The location of your FreeBSD source tree.
$OBJ
The location of the object tree. This is normally ``/usr/obj-pico''.
$PICO_TREE
The directory containing thepicobsdsource tree. This includes the reference directory configurations, and thebuilddirectory that contains thepicobsdscript. This defaults to ``/usr/src/release/picobsd''.
$FLOPPY_SIZE
The size of the floppy image file in Kbytes. This size should match the size of the device you intend to write. The$FLOPPY_SIZEenvironment variable defaults to 1440 Kbytes, the size of the most common 3.5 inch floppy. The currentpicobsdscript writes to a ``floppy device'' using a device node of ``dev/rfd0.${FLOPPY_SIZE}''.
Results:
The principal outputs of the
picobsdscript are (1) a bootable floppy, (2) an image of the floppy saved in file ``picobsd.bin'', and (3) a bootablekernelfile. The two files are in thebuild_dir-$floppy_typedirectory (which itself will be located in the directory in which you executed thepicobsdcommand).Unless you change the
INCLUDE_FLOPPY_IN_MFSdefault, the floppy and floppy image will only contain the bootable kernel file.If you
[Cancel]out of the last menu dialog in thepicobsdscript, the two files will be created, but the ``picobsd.bin'' file will not be written to the floppy, which is useful if you are booting the kernel over a network, from flash, etc..
§ The initial dialog menu gives you the opportunity
to edit the relevant PICOBSD kernel configuration file
and the ``crunch.conf'' file that specifies the
binary executables to link into your kernel.
You can also configure the layout of the two
filesystems constructed on virtual devices and select the
program you use as the ``init'' process (the process
ultimately responsible for activating all other
processes on the system).
The appearance of the menu (with typical defaults) is as follows:
N --> READY, build it <---
T Type: my_486 name my_486
K edit Kernel config file
E Edit crunch.conf file
S MFS Size: 2200kB
I Init type: init
F Floppy size: 1440kB
M MFS bytes per inode: 5000
U UFS bytes per inode: 32768
$ Site-info:
Q Quit
[ OK ] Cancel
You can highlight a line of the menu by using the keyboard up-and-down arrows, or by pressing the indicated letter (case insensitive). Invoke the selected option by pressing Enter.
* If you select ``N --> READY, build it <---'',
the build will proceed.
* If you select ``T Type: my_486 name my_486'',
you will be presented with another dialog containing all
the configuration directories that the picobsd
script can find. Scroll through this dialog with the
up-and-down arrows to select the configuration you want
to build (or edit with the other menu options).
* Select ``K edit Kernel config file''
to edit the PICOBSD kernel configruation file in
the selected configuration directory.
* Select ``E Edit crunch.conf file''
to edit the file that specifies the pathnames of the
executable program files you want to crunch into
your kernel, link names for these programs, required libraries, and the
directories containing the program's Makefiles.
* Select ``S MFS Size: 2200kB''
to specify the size of the MFS RAM-file system built into your kernel.
This has to be established by experience and should be as small
as possible. The dialog notes that typical ranges are
between 820 and 2500 KBytes.
Specifying this too large will result in the error message:
``MFS filesystem signature not found in kernel''.
This should be changed in conjunction with the
MD_ROOT_SIZE option in the PICOBSD
kernel config file.
* Select ``I Init type: init''
to select the program to run as your ``init'' program (Process 1).
A dialog will appear which allows you to select the normal
FreeBSD init program, or the PicoBSD oinit
program in the
/usr/src/release/picobsd/tinyware collection.
The oinit program contains a small built-in shell
that can only handle simple command lines, not
the normal sh syntax. If oinit
is used the
technique of updating files
in /etc cannot be used,
unless you write your own simple etc/rc
or ``etc/oinit.rc'' to do so (see the section
on oinit).
* Select ``F Floppy size: 1440kB''
to select the size of the ``picobsd.bin'' image that
is produced. A dialog will appear with 4 standard sizes that
correspond to various devices (the largest is 4 Mbytes).
Typically this is the image that you would write to a floppy
boot disk, but at the end of the script if you cancel from the
floppy-write menu, the output file image will be left in the
build_dir-$floppy_type directory of the configuration
directory.
* Select ``M MFS bytes per inode: 5000''
to specify the fraction of the MFS (the in-kernel RAM-filesystem)
you want to devote to inodes. This is the average file size
you expect in the ``fully-loaded'' MFS, with some pad.
Set this with respect to the ``MFS Size'' option
that was previously set. To increase the number of inodes
(that is, the number of files that can exist),
you need to decrease this value.
* Select ``U UFS bytes per inode: 32768''
to specify the fraction of the floppy filesystem you want to devote to inodes.
Actually, the ``floppy'' need not be a floppy, and so you want to select
this size in conjunction with the ``Floppy size'' option.
Again, this is the average file size you expect when the floppy is fully
loaded. The newfs utility will figure out how many inodes
this requires. To increase the number of inodes,
you need to decrease this value.
After the picobsd script has finished, a new boot floppy
will only have two used inodes - the root directory and the /kernel
file (assuming the MFS is in the kernel).
§ Unlike some toolsets, you are not required to go through the menu to edit the files in your configuration directory. There is no reason why you cannot edit the files in your configuration directory directly using any editor of your choice. If you are in a repetitive developmnet and debugging cycle, it is often easiest to simply leave all relevant files open in an editor and skip the use of the menus.
There is no way from the menu to edit the
config file, which specifies your desired
device nodes. You have
to do this directly.
As the picobsd script header documentation
indicates, each
PicoBSD configuration directory contains
a number of standard files:
§ PICOBSD
The
PICOBSDfile is a normal FreeBSD kernel configuration file with the addition of a comment line that starts with ``#PicoBSD''. This comment line supplies arguments to thepicobsdscript.Edit the
PICOBSDfile to include your desired FreeBSD kernel options. In particular, you often will want to specify drivers (devices).Edit the
#PIOCBSDcomment/argument line to change the size of MFS RAM-disk, the number of inodes in either the MFS or on the floppy, or the ``init'' program. An example of the#PIOCBSDcomment/argument line (from/usr/src/release/picobsd/router/PICOBSD) is:
#Line starting with #PicoBSD contains PicoBSD build parameters #marker def_sz init MFS_inodes floppy_inodes #PicoBSD 1200 oinit 3072 32768 options MD_ROOT_SIZE=1200* The first argument in the ``
#PicoBSD'' comment indicates the size in 1Kbyte blocks of the MFS filesystem (this argument is passed as the ``count='' argument to theddcommand that creates the file backing the MFS image, usingbs=1k).* The second argument specifies the program to be run as the
initprocess, that is, Process 1. This program is ultimately responsible for activating all other processes, so changing this argument can totally change the nature of the system you build. Theoinitprogram in the above example is a tiny ``template starter'' alternate to the traditional FreeBSDinitprogram. See the section onoinit.* The third argument is the ``
-i avg_bytes_per_file'' value passed to thenewfsinvocation that creates the filesystem on the MFS. This indirectly specifies the number of inodes, that is, the maximum number of files that you expect to fit on the filesystem of size ``def_sz''.* The fourth argument is the ``
-i avg_bytes_per_file'' value passed to thenewfsinvocation that creates the floppy image filesystem. This indirectly specifies the number of inodes, that is, the number of files that you expect to fit on a filesystem of$FLOPPY_SIZE. The$FLOPPY_SIZEenvironment variable defaults to 1440 Kbytes, the size of the most common 3.5 inch floppy.
§ config
The
configfile lists all the device nodes that are to be created in ``/dev''. Edit this file and add any device node names you need to theMY_DEVSstring. There is only a single line in the typicalconfigfile. An example of this line (from thebridgeconfiguration) is:
MY_DEVS="std tun2 vty10 fd0 ad0 pty0 cuaa0 cuaa1 bpf0 bpf1 bpf2"Any number of environment variables that you decided to use could be defined in your
configfile.
§ crunch.conf
The ``
crunch.conf'' file controls the applicationcrunchgen, that is, it indicates which executables to link into the single executable ELF file.Edit ``
crunch.conf'' and addsrcdirs,progs, andlibsstatements as needed. Theprogsstatements specify the pathnames of the executables that you require. Thesrcdirsspecify the pathnames of the directories containing theMakefiles that correspond to the executables. Note thatcrunchgenrequires a special ``makefile format'' (a FreeBSD standard), but you can easily create a pseudo-makefile with this format if required.The
crunchgenprogram, in effect, renames all programmain()routines and creates a singlemain()with a little stub code that dispatches to the real entry-point based on thearg0command-line name. Because of this, ``links'' are important in the PicoBSD file tree (so as to provide desired names). You specify your desired link names in the ``crunch.conf'' file using thelncommand.See ``
man crunchgen'' for the syntax of the statements in the ``crunch.conf'' file. Also see the comments included in the ``crunch.conf'' files in the reference directories.
§ floppy.tree (optional)
Each configuration directory can root its own ``
floppy.tree'' directory tree. If it exists, the ``floppy.tree'' directory normally contains a/etcdirectory which includes the/etc/rcscript and other scripts that you want to build into the kernel, such as ``/etc/rc.firewall''. Create and edit files, directories, scripts and configuration files in the ``floppy.tree'' directory tree as required.The files in the floppy tree are typically the files that you might want (potentially) to edit on the floppy. The default behavior of the current PicoBSD is not to put these files on the floppy outside the
kernelfile, but to include them directly in a/fddirectory in the MFS RAM-disk built into the kernel (see the section on INCLUDE_FLOPPY_IN_MFS to change this behavior).The directory ``
/usr/src/release/picobsd/floppy.tree'' contains a ``base collection'' of scripts and other/etcfiles that will be included in PicoBSD. In the kernel you build, the version of these files in your ``floppy.tree'' is copied over the files in this tree.
§ floppy.tree.exclude (optional)
Each configuration directory can optionally contain a ``
floppy.tree.exclude'' file. Each line in this file contains the pathname of a file in the ``base collection'' in ``/usr/src/release/picobsd/floppy.tree'' that is not to be included in the PicoBSD system that you build. An example exclude file, from the bridge collection, is ``/usr/src/release/picobsd/bridge/floppy.tree.exclude''.
Note: a single
/usr/src/release/picobsd/mfs_tree
contains the files that are always built into the root MFS RAM-based
filesystem included in every kernel image
built under a particular $PICO_TREE (usually, this means that
whatever is in mfs_tree will end up in every PicoBSD system
that you build).
§ mfs.mtree (optional)
Each configuration directory can contain a ``
mfs.mtree'' file which specifies, in the format used by themtreeutility, a map of the directory structure you want to create in the RAM-based file system. You do not need to define a ``mfs.mtree'' directory structure if you do not need any directories other than those included in/usr/src/release/picobsd/mfs_tree.See /etc/mtree for examples of
mtreespecification files.
The current reference configuration directories are located in
directory
``/usr/src/release/picobsd''.
Start with the system closest to your needs and adapt
it to your circumstances.
The following
briefly describes these reference configurations:
§ bridge
(
/usr/src/release/picobsd/bridge)
This PicoBSD system includes the
ipfw firewall,
dummynet, and
bridge.
Dummynet is software that enhances the ipfw firewall code
with the ability to do bandwidth limiting and a wide variety of other
features of interest to network researchers and technical ISPs
(traffic shaping and generation).
The
bridge
facility permits a PC to operate as a software ``bridge'', where
``bridge'' is used in the hardware sense, that is, as a repeater-style
connection that allows two Ethernet cables to appear to be a single
Ethernet cable. The FreeBSD maxusers kernel-sizing estimate
is set to 20.
See ``man dummynet'' and
``man bridge''.
§ custom
(
/usr/src/release/picobsd/custom)
Although this directory at one time apparently supported
custom builds, currently it apparently
contains an (older) experimental Makefile
that was intended to replace the picobsd script.
This was apparently written at a time when a PicoBSD system required two floppies.
§ dial
(
/usr/src/release/picobsd/dial)
This is basically a minimal end-user system that could be used
on a low-end PC to connect to an ISP using
ppp
over a dial-in connection.
It does not contain any firewall code.
The FreeBSD maxusers kernel-sizing estimate
is set to 3.
§ install
(
/usr/src/release/picobsd/install)
This appears to be a simple PicoBSD-based install system. This PicoBSD
system contains a script, ``floppy.tree/etc/doinstall'',
that does a network fetch to install a FreeBSD system.
What is the status of this kit?
§ isp
(
/usr/src/release/picobsd/isp)
This system is intended to be operated as an ISP
modem-server supporting 8 serial
ppp
connections. It includes the
ipfw firewall
and
Dummynet code.
This system defines no scripts or configuration
files of its own, and thus is entirely dependent on the
scripts in the
``base collection'' in the
/usr/src/release/picobsd
directory (
mfs_tree
and
floppy_tree).
The FreeBSD maxusers kernel-sizing estimate
is set to 20.
§ net
(
/usr/src/release/picobsd/net)
This is a generic network ``end node''.
It does not include Dummynet, but does support
ipfw
and
ppp.
The FreeBSD maxusers kernel-sizing estimate
is set to 10.
§ router
(
/usr/src/release/picobsd/router)
This system is similar to the ISP system but
it does not support any special serial devices or ppp,
it does not include Dummynet, and it contains no special applications. Basically
this system is intended to be a running TCP/IP
stack in an Ethernet networked environment.
It includes
ipfw
firewall support.
This system defines no scripts or configuration
files of its own, and thus is entirely dependent on the
scripts in the
``base collection'' in the
/usr/src/release/picobsd directory
(
mfs_tree
and
floppy_tree).
The FreeBSD maxusers kernel-sizing estimate
is set to 10.
An important operational characteristic of the router
system is that it runs the minimal oinit version
of the Process 1
init
program. Presumably a system
that is being used as a dedicated network router/firewall does not
want to waste memory on a user shell.
The source to this program is in
``/usr/src/release/picobsd/tinyware/oinit/''.
An important implication of this is that the scheme
for overwriting and updating the files in /etc
is not supported by the router configuration. It runs a
minimal rc script
consisting only of simple command lines.
Because of the aformentioned use of oinit, for a typical
PicoBSD router-style deployment, the ``full-blown'' bridge
configuration is probably recommended.
rc boot script work?
The PicoBSD /etc/rc boot script
is different than that used in FreeBSD.
The
FreeBSD ``/etc/rc.conf'' scheme,
in which the
boot sequence is controlled by overriding default shell
variables,
is not used in PicoBSD due to size.
PicoBSD does, however, use a
``/etc/rc.conf'' file
in which shell variables are set.
In addition, PicoBSD uses a somewhat subtle initial
rc scheme that involves uncompressing
and merging multiple /etc
directories and which always overwrites
the initial rc script,
/usr/src/release/picobsd/mfs_tree/etc/rc,
while it executes.
When the floppy tree is built into the kernel, the floppy /etc
files are put in MFS filesystem directory
``/fd/etc''. All files in /fd/etc are compressed
(gzipped, that is, are ``.gz'' files).
The files that you want to statically include in the
MFS RAM-filesystem are
located at
/usr/src/release/picobsd/mfs_tree
in the source directory tree.
This directory, in the running system, will be rooted at ``/''.
These statically included files are primarily small versions of
script files that rarely change, such as
disktab, protocols,
services, shells,
and termcap.
The mfs_tree contains
a very simple
/etc/rc script
(located in
/usr/src/release/picobsd/mfs_tree/etc).
This is the initial script executed upon boot.
It:
* Enters the
/fddirectory and recursively copies the/fd/etc/tree to/etc. This mergesetcfiles defined inmfs_tree/etcwith any gzipped files from ``floppy.tree/etc'' included in the kernel due toINCLUDE_FLOPPY_IN_MFS="yes".* The
rcscript then returns to ``/'', and mounts the floppy disk (/dev/fd0c) on/fd.* It then repeats the process of copying all files from
/fd/etcinto/etcand then dismounts the floppy. This will copy any files into/etcthat were put on the floppy using ``floppy.tree'' andINCLUDE_FLOPPY_IN_MFS="no", or which you have manually edited on the floppy (perhaps using a host machine or PicoBSD). At build time, the original ``floppy.tree'' sources may be located either in a private ``floppy.tree/etc'' configuration directory, or in the base ``/usr/src/release/picobsd/floppy.tree/etc''.* The
rcscript then enters/etcand scans the directory for all files for which a gzipped version also exists, and it deletes the non-gzipped files (that is, for all files wherefoo.gzexists,foois deleted). This means that if you want to overwrite a file that exists in a floppy tree built into the kernel image (that is, in/fd) with a new file that is actually located on the floppy, the new file must be gzipped.* All gzipped files in
/etcare unzipped.* The
pwd_mkdbutility processes the ``master.passwd'' file to create a valid binary password ``database''.* Finally, the initial
/etc/rcscript executes the script/etc/rc, that is, itself. However, the previous steps assure that the/etc/rcfile will have been overwritten. The source to the new/etc/rccan come from a number of original locations. It may have come from the default ``base''rcscript defined in the ``/usr/src/release/picobsd/floppy.tree/etc''. It may be a script defined in the ``floppy.tree/etc'' directory of a PicoBSD configuration directory, if such a file exists. Finally, it will be the gzipped script located in ``/etc/rc.gz'' on the boot floppy, if such a file exists.
Because of its self-modifying behavior, it is important that the
initial
mfs_tree/etc/rc script remain less than 1K.
Note that the gzipped /fd/etc files
are not by default deleted from the RAM-disk,
which typically uses up some 20K of memory.
/etc scripts?
Once the system boots, the RAM-filesystem is volatile
and files can be edited, etc... Such modifications
will be lost, of course, upon reboot.
There is no easy way to permanently edit a file
included in the kernel image, however,
the process described in the
previous section on the boot
rc script explains
how a file to be updated can be
overwritten at boot time by new files placed
on the floppy. To create a new /etc
file,
the floppy can
be mounted as a normal filesystem (either from a host
or from PicoBSD after PicoBSD boots).
The procedure to update a /etc script is:
(1) edit copies of the script files you want to update,
(2) gzip the files,
(3) mount the PicoBSD floppy,
(4) create a /etc directory, if it does not exist,
on the PicoBSD floppy, and
(5) put the updated and
gzipped
script files in /etc on the floppy.
The new files
will then overwrite the original files at
boot time.
For instance, to change the motd
``message of the day'' login file using a PicoBSD system
built with ed and
gzip:
#mount /dev/fd0 /mnt
#cd /mnt
#mkdir etc
#cd etc
#ed motd
H
P
a
*** Hello there, world!!!!***
.
wq
#cat motd
#gzip motd
#ls
#
#cd
#umount /mnt
#reboot
#
In the above, a ``mount /dev/fd0c /mnt''
should work as well. Note that a floppy ``knows'' if,
after being mounted,
it has been cleanly unmounted via a umount.
If you get persistent
``mount: /dev/fd0c: Operation not permitted''
errors
while attempting to mount a floppy, check with dmesg
for ``run fsck'' warnings - the floppy was likely
``popped'' out without a manual umount.
The procedure described in this section enables
persistent (re)editing of startup scripts (put
ed
in your ``crunch.conf'' if you are a minimalist,
or try
ee).
The script
/usr/src/release/picobsd/mfs_tree/stand/update
automates this process, including saving an updated password file.
Beware that the procedure described here does not work for the
router configuration because it uses
oinit, which
requires either a
minimal commands-only rc file,
or (depending on a #define),
its own ``etc/oinit.rc'' file.
If ``oinit.rc'' is used, all its
lines must either be comments
that start with a #, or valid executable command-lines.
Suppose you want to edit a new version of a /etc
script file. You can mount the floppy (``mount /dev/fd0 /mnt'')
and put the gzipped file in the
/etc directory on the floppy,
as described in the
section on updating a script file.
Alternatively, you can
mount the ``picobsd.bin'' floppy image file,
and put the new gzipped file in the /etc directory
in the image file. You can then create as many floppies as
you like that include your new file by using dd
to copy the ``picobsd.bin'' image file to a real
floppy.
For example, to add a new rc file to a floppy image named
``my_old_picobsd.bin'' in the current
directory:
#su
#mount
#vnconfig -c -s labels vn0 my_old_picobsd.bin
#mount /dev/vn0c /mnt
#mount
#cd /mnt
#
#echo Create a new etc, or gunzip and edit existing files...
#
#mkdir etc
#cd etc
#cp /tmp/my_new_rc rc
#
#gzip rc
#
#cd
#umount /mnt
#vnconfig -u vn0
Now you can write the image file to a boot floppy.
The first
vnconfig
configures (``-c'') the /dev/vn0
device and sets a flag to
use the diskslice label on the device (``-s labels'')
This means the existing ``disk'' label, which contains the *ix partition information,
is respected.
After this command, the device /dev/vn0 is accessible. The bytes of the
device are the bytes contained in file ``my_old_picobsd.bin''. At this point
the /dev/vn0 device can be mounted and unmounted as if it were any block
device. The final vnconfig command unconfigures (``-u'') device
/dev/vn0. Be sure to do this, as the picobsd script needs
a free vn device. After the unconfigure, the mapping between the device and
file no longer exists; /dev/vn0 can no longer be accessed as a device.
Note that the gzip step is not optional if the configuration has
previously used a ``floppy.tree/etc/rc'' script!
This is because
the ``first-level'' rc script (source in
``
/usr/src/release/picobsd/mfs_tree/etc/rc'')
deletes all the files in /etc that have a corresponding gzipped version.
If the new file
is not gzipped, this will delete your new version of the rc file that came
from the floppy, leaving the old gzipped rc from /fd/etc/rc to
become the executing rc.
An advantage of this style is that you can edit startup scripts on a large host with your favorite visual editor at normal I/O speed (not floppy-speed!).
Often, it is almost just as fast to do a rebuild of PicoBSD. However, this procedure may be useful if you can no longer build PicoBSD, for instance, you no longer have the FreeBSD source installed.
The netstat utility
in FreeBSD
is a stripped-down version named
ns.
A link exists with the name
netstat.
Not all changes are simple ``throw-outs'',
for instance, PicoBSD's
``netstat -w 1'' assumes a CRT.
Instead of using dmesg to redisplay console messages
(such as the driver boot probe messages), PicoBSD uses
the
msg
utility (also linked to the
dmesg name).
PicoBSD uses a stripped-down version of vmstat called
vm.
It automatically enters
a loop with a display
in the ``-w 5'' style.
If
oinit
is used (currently it is only used
for the router reference configuration), the user's
``shell environment'' is quite different than for the
other systems, which use sh as the shell.
Because oinit does not parse command
lines it is used with either a
minimal line-at-a-time
rc file or it's own
``etc/oinit.rc''
file. The default rc file in this case
do not support the scheme for
updating /etc files
by replacing them with
updated versions from the floppy.
Some versions of PicoBSD may use
stripped-down versions of ps
(the source is in picobsd/tinyware).
None of the standard PicoBSD builds include any version of
more, probably due to its size (more
is really a complete old-fashioned text-browser).
PicoBSD does support virtual consoles, which
can be accessed using <alt>-F1, <alt>-F2,
..., <alt>-F8.
When running X-windows on FreeBSD,
you cannot reboot
by pressing
<ctl>-<alt>-<del>
(which otherwise works on both).
The standard PicoBSD reference
configurations do not include shutdown.
They do include
reboot.
kernel file?
Many FreeBSD executable applications are linked assuming they can
dynamically link to loadable libraries. Attempting to run such a
binary on a PicoBSD system will fail because the shared library will
not be found. To get around this problem, either statically link
the application as described in the
section on static linking,
or ``crunch'' your application using
crunchgen into the binary file included
in the filesystem contained in
the system image.
Using crunchgen requires
some commands in the ``crunch.conf'' file and
at least a minimal Makefile in your application
directory. The crunchgen utility requires
a standard FreeBSD Makefile. From ``man crunchgen'':
"...the Makefile must contain the target depend, and it must define all object files..."Suppose for some reason you do not use makefiles (perhaps you have your own development tools). In this case, to use PicoBSD, you still need to put a simple
Makefile
in your ``development directory'' that defines the object files
to be processed. Suppose you write a program called my_serv
which consists of two C files, ``my_serv.c'' and
``my_lib.c''.
A Makefile sufficient to keep crunchgen
happy would only require:
#
#
# Makefile for picobsd crunchgen
#
PROG=my_serv
SRCS= my_serv.c my_lib.c
OBJS= my_serv.o my_lib.o
NOMAN=yes
.include <bsd.prog.mk>
Assuming the above Makefile and C code is in
directory /usr/my/demo/code,
in your PicoBSD configuration directory, edit the ``crunch.conf''
file to contain the lines:
srcdirs /usr/my/demo/code
progs my_serv
special my_serv objvar OBJS
special my_serv srcdir /usr/my/demo/code
special my_serv objdir /usr/my/demo/code
When using this pseudo-Makefile,
the ``.o'' files will need
to exist in
``/usr/my/demo/code''
before the picobsd script executes.
If you are compiling files by hand, you can generate
the ``.o'' files for my_serv
using:
#gcc -c my_serv.c #gcc -c my_lib.c
Rebuild your version of PicoBSD, and test your application.
kernel file?FreeBSD executables use dynamic link libraries by default. Dynamic linking is typically used on modern systems to increase code sharing and reduce the size of executable programs (which often link to very large graphics libraries). Arbitrary executables built under FreeBSD will often require dynamic libraries not included in the PicoBSD system.
One way to avoid this problem is to
relink the application ``statically'' under FreeBSD.
The application's executable image will then
include all needed library
routines. For instance, to compile and statically link
``hello.c'',
producing output ``a.out'':
#cc -static hello.c
To find out if a binary program, for instance ``a.out'',
has been linked statically
or dynamically (and, if dynamic, which libraries it uses),
do a:
#file a.out
#ldd a.out
It is also good practice to ``strip'' a binary that is to be downloaded individually to run on PicoBSD, that is, remove unnecessary symbols:
#strip a.out
The size of the typical uncompressed PicoBSD kernel file for
the standard reference configurations is
somewhere between 3 and 4 Mbytes. This usually compresses
to around 1 Mbyte.
The PicoBSD kernel file
does not necessarily have to fit on a floppy.
You can make it
any size you want, if you have a suitable boot
mechanism.
The run-time footprint will, of course, depend on the applications you run. Although I have run PicoBSD in 4 Mbytes in the past, current lore has it that around 8 Mbytes is a typical minimum.
Yes, PicoBSD can support hard disks. Other than perhaps building your PicoBSD system to contain any needed disk initialization utilities, the use of hard disks in PicoBSD does not differ from normal FreeBSD practice. To support a hard disk:
* Add an
entry in your PICOBSD configuration file for
the driver you need.
* Add the device node names
you will be using to your config file.
If you need slices and partitions, be sure to add
device nodes for them. You do not need an MBR (Microsoft
Boot Record, defining Microsoft partitions) and disk
slices (the FreeBSD name for Microsoft partitions)
on a hard disk if you only use the disk for data. If you intend
to boot PicoBSD from the disk, it should have an
MBR.
* You will have to mount the hard disk, perhaps using
a mount command at the bottom of the /etc/rc
file you include in your ``floppy.tree''
(that is, in the
``./floppy.tree/etc/rc'' file in your
configuration directory).
Depending on your environment, you may need to include
such utilities as
fdisk and
disklabel
in your PicoBSD configuration.
There are two virtual filesystems relevent to the standard PicoBSD
build: (1) the MFS RAM-based filesystem built into the kernel, and (2) the
filesystem placed in file ``picobsd.bin'', the floppy image.
§ At the end of the executable code-crunch phase of the picobsd
script, a ``df -i'' report, similar to the following, appears:
Filesystem 1K-blocks Used Avail Capacity iused ifree %iused Mounted on
/dev/vn0c 2103 1600 503 76% 308 202 60% /var/vartmp/picobsd.ObsQn6JZW8
If you want to study this at your leisure, run
picobsdwith the ``-v'' option (``picobsd -v my_sys''). After the ``---> Labeling MFS image'' trace step, you will see a display such as the following:
Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/vn0c 2103 1 2102 0% /var/vartmp/picobsd.QYgf0heGblAfter the ``
---> Copy generic MFS tree...'' and ``---> Copy generic floppy_tree into MFS...'' steps, you will see thedfdisplay of the final MFS filesystem (resembling the first display above).
§ At the end of the picobsd script,
a dialog menu appears. This dialog includes output similar to the following:
The build process was completed successfuly.
Filesystem 1K-blocks Used Avail Capacity iused ifree %iuse
/dev/vn0c 1403 1268 135 90% 2 60 3%
This is a ``df -i'' style display of your populated floppy
filesystem. The Capacity field tells you how much space
is used (and left) on the floppy filesystem. For a default build,
there will only be two inodes used on the floppy, one for the root directory
and the other for ``/kernel''.
§ To see the status of filesystems in a running PicoBSD system, use ``
df -Hi''. This will produce a display
in ``human-readable'' format.
§ To alter the amount of space reserved for inodes, see the section on the PICOBSD configuration file.
Well, FreeBSD, naturally, since FreeBSD and PicoBSD are really the same thing. The most up-to-date PicoBSD development environment as of this date (June-2001) is FreeBSD 4.3 Stable. PicoBSD may not build under FreeBSD Current (this may change by the time you read this). Beware that PicoBSD procedures (such as those described in this document) can change significantly between FreeBSD versions, so check the freebsd-small@freebsd.org e-mail list archives.
picobsd run under?
Some form of the picobsd script
should run under all recent FreeBSD versions
except FreeBSD 5.0 Current (and maybe that too, by the
time you read this).
Currently (June 2001), FreeBSD 4.3 Stable is the
most solid version of PicoBSD. The 4.3 Stable version
of PicoBSD
generates systems that easily fit on a single floppy,
unlike some earlier versions which required two floppies.
To get PicoBSD, obtain FreeBSD with sources.
Once FreeBSD is installed, assuming the
sources are in the default /usr/src
directory, the PicoBSD
sources are in
``/usr/src/release/picobsd''.
There are a number of ways to get FreeBSD with sources
and keep it up-to-date.
You can subscribe to one of the commercial services that
ship FreeBSD on CD-ROM or DVD. You can download
FreeBSD CD-ROM images over the Internet and burn a
bootable CD. You can ftp the sources from one
of the FreeBSD source mirror sites. You can use
cvs or cvsup to obtain
sources from a FreeBSD CVS repository. You can use
ctm to get sources and source diffs via e-mail.
The CVS system is used by the FreeBSD project to
manage the source code tree.
In practice, once you have installed a source kit
(perhaps from a CD-ROM image), most FreeBSD developers
seem to use cvsup. The cvsup
system runs on top of CVS and, in effect, only updates
files in your source tree from the repository that a
hash indicates have changed.
picobsd script (how does all this happen)?
The
/usr/src/release/picobsd/build/picobsd
script
is PicoBSD. Read this script file for the
``real'' documentation. The header of the picobsd
script file contains
usage notes. This script is, among
other things, a wrapper for a FreeBSD kernel build.
It creates a ``virtual disk device'' using a file and
makes this (file) a bootable FreeBSD (PicoBSD) disk image
by putting in the disk image: (1) a root file system,
(2) boot blocks, and (3) a bootable
kernel in the ``kernel file itself.
You have to be root to run the picobsd script because
it needs to mount the virtual devices
and write raw to
the floppy.
In earlier versions of PicoBSD, the picobsd script
was named build.
The PicoBSD build cycle builds the floppy ``disk image''
file and then at the very end does a block-block
copy of this image to floppy, using
dd (Device Dup).
You do not need to build or use the floppy image.
You can just netboot the kernel file, boot
it from flash, etc..
In the typical development cycle in which you are editing source code files, after the first PicoBSD build following builds will go much faster (only the files you have changed will be recompiled).
The overall steps performed by the picobsd script are
now outlined, using a sort-of shell-command pseudo-code
and noting the names of relevant shell script routines.
§ Setup variables and do
the initial setup menu dialog (init_vars(),
main_dialog()).
§ Build the kernel
(build_image()).
The build_image() routine is the main driver for building
the kernelfile and putting the MFS and floppy tree inside
it. The steps performed by build_image() are now
described.
§ Read in the
configfile (init_stage1()).
§ Build the initial
kernelfile and copy it to a work directory (do_kernel()). The actual kernel compile is driven bymakeusing
``/usr/src/release/picobsd/build/Makefile.conf''.
#make
#cp
#strip
§ Create the floppy filesystem in a work directory (
populate_floppy_fs()). This is done before creating the memory filesystem so that the floppy filesystem can be copied into the memory filesystem, if desired.
#tar
#gzip etc/*
§ Create the memory filesystem (MFS) (
create_mfs(), init_fs_image()).
#ddan image of the size specified in thePICOBSDfile.
#ddboot1to make it bootable.
#vnconfigthe image (make it accessible as a device).
#disklabelto create a *ix disk partition table (disk label).
#newfsto create the filesystem.
#mountto make it accessible for normal utilities.
§ Populate the MFS file system (
populate_mfs()).
#cdinto the configuration directory.
#mtreeto create the MFS directory structure.
#ln
#MAKEDEVto create device nodes.
#crunchgen crunch.mkto preprocess the applications to crunch.
#make crunch.mkto crunch the onjects intocrunch1.
#mvto putcrunch1in/stand/crunchin the MFS filesystem.
#tarto copymfs_treefiles from configuration directories to the MFS filesystem.
#cp -R floppy.treeinto/fdin the MFS ifINCLUDE_FLOPPY_IN_MFS="yes".
#umountvirtual MFS device.
#fsck
#vnconfig -u, which returns the file to ``normal'' (not a device).
All binary executable files are actually in a single file,
/stand/crunch. The/standdirectory contains links which refer to all binaries, and directories such as/binand/sbinare simply links to/stand.
§ Create ``
picobsd.bin'', the floppy disk image (fill_floppy_image()(Part I)).
#dda file to floppy size.
#ddboot1 to make the file bootable.
#vnconfigto make the file accessible as a device.
#disklabelto write boot records (and create a single partition disk).
#newfsto create a filesystem in the file.
#mountto make the filesystem accessible.
§ Copy the MFS to the kernel, compress the kernel, and copy it to the floppy image. (
fill_floppy_image()(Part II)).
#cc write_mfs_in_kernel.c
#write_mfs_in_kernelto actually put the MFS in the kernel.
#kgzipthe kernel.
#cpthe kernel to/kernelin the floppy tree.
The file ``
/usr/src/release/write_mfs_in_kernel.c'' is a little program compiled every execution of thepicobsdscript. It ``zaps'' the MFS filesystem image into the kernel image at a location it finds by scanning thekernelfile for a byte string literal ``MFS Filesystem goes here''. Note ``write_mfs_in_kernel.c'' is not in the PicoBSD tree (it has other uses as well). If your MFS filesystem becomes too large to fit in the kernel, the error ``MFS Filesystem signature not found'' will likely occur. Increase theMD_ROOT_SIZEspecified via the second argument in yourPICOBSDconfiguration file. This may result in akerneltoo large to fit on the floppy.§ Put the ``
floppy.tree'' in the floppy image, if needed (fill_floppy_image()(Part III)).
#cpthe ``floppy.tree'' into the floppy image if it was not already copied into the MFS (that is, if it is not already inside the compressedkernelfile).
§ This completes the
build_image()routine.
§ Write the floppy image to the floppy disk
(do_install()).
#dialogto display the confirmation dialog.
#dd picobsd.bin -> /dev/rfd0to write the floppy.
tinyware?tinyware homepage, which is quite dated,
is at:
The tinyware directory in
/usr/src/release/picobsd/tinyware
contains small versions of a few standard
system utilities, in particular vmstat
and netstat. These are smaller
than their FreeBSD counterparts and are the
versions typically used with PicoBSD.
There is occasional discussion in the PicoBSD
world of developing a ``complete'' set of ``tiny''
utilities, perhaps based on those for such systems
as Minix. Lately, it appears this idea has
fallen out of favor as a general strategy, on
the grounds that it introduces yet another
standard for things such as script syntax.
As is, the
sh
shell works fine
with PicoBSD.
Conversly,
oinit acts as it's
own minimal shell.
Of course, for your special application
you can engineer exactly whatever you need.
See also the PicoBSD FAQs
See the following section for some information on the tinyware utilities.
oinit?
§ The second process created by a
booting *ix system
typically runs the program
/sbin/init.
A FreeBSD ``ps -ax''
will show this init program with a
Process ID of 1. Process 0 is considered
the swapper,
which (irrespective of virtual memory)
provides a means to make main memory available by
swapping programs to the swap device
(PicoBSD usually does not have a swap device).
It is init that forks itself for each
interactive terminal which the system is to support,
resulting in other forks which issue login prompts,
create shells, and such. The init
process thus becomes the uppermost ``parent'' of all the
processes in the system.
In many embedded PicoBSD scenarios, the full-blown
init program is inappropriate.
In this case, the oinit program
provides a simple
alternative.
The oinit program acts as it's own
minimal shell, that is, it does not run another shell
program.
You can treat this program as a
starting point for developing your own embedded
environment very different from traditional *ix.
§ The code for the oinit program is
located in directory:
/usr/src/release/picobsd/tinyware/oinit
§ Specify that you want to use oinit instead
of init by changing the
second argument
of the #PicoBSD line in your
PICOBSD configuration file.
§
The PicoBSD router reference system
uses oinit. A
compile-time ``#ifdef OINIT_RC'' controls
whether the oinit program
process a
minimal line-at-a-time
rc file,
or uses its own ``etc/oinit.rc'' file.
Because oinit does no real parsing,
the lines in either of these files
must either be comments
that start with a #, or valid executable command-lines.
Thus,
the default scripts for the
router configuration do not support the scheme for
updating /etc files
by replacing them with
updated versions from the floppy.
You could modify these to do so, if need be.
The
boot blocks
written to the floppy image
are obtained from the host
FreeBSD machine's
/boot directory
If you intend to write boot blocks to a device
from a running PicoBSD system (perhaps to make a
bootable hard-disk or flash device),
put the boot files that you need in
``/usr/src/release/picobsd/mfs_tree/boot''.
The
Makefile.conf file in
``/usr/src/release/picobsd/build''.
§ PicoBSD has a tree-structured configuration scheme with respect to boot-time script files. Each ``leaf-node'' of the configuration tree defines a single system. Three levels of ``factored commonality'' potentially exist above each leaf. The layering is:
/usr/src/release/picobsd/mfs_tree/etc (top, base-class, super-class)
/usr/src/release/picobsd/floppy.tree/etc
$CONF_DIR/floppy.tree/etc
$CONF_DIR/floppy.tree.$SITE_NAME/etc
In the above, $CONF_DIR specifies your configuration
directory, and $SITE_NAME is the optional
site as specified in the picobsd command
(see the section on command syntax).
The $CONF_DIR above corresponds to the floppy_type
argument passed to the picobsd command.
You do not need to have either of the $CONF_DIR/floppy.tree
directories.
Your /etc files are, in effect,
``inherited'' using the above four ``classes''.
§ In addition, you can have multiple PicoBSD source trees
by specifying the root using the $PICO_TREE
variable.
§ See also the section Cloning the Sample Client toward the end of the article Setting Up a FreeBSD Lab, by Oscar Bonilla, at www.daemonnews.org/199911/fbsdlab.html. This article describes replicated PicoBSD installation.
Easy! Suppose you keep a collection of pre-built PicoBSD floppy
systems, that is, a collection of ``picobsd.bin'' files.
To write bootable image file ``my_old_picobsd.bin''
to a standard 3.5 inch floppy,
use
dd (Device Dup):
#su
#dd if=my_old_picobsd.bin of=/dev/rfd0.1440
A FreeBSD or PicoBSD kernel is an ELF (Executable and Linking Format) file.
One way to compare a FreeBSD kernel with a PicoBSD kernel is to
use objdump. Assuming a PicoBSD configuration named
mysys:
#cd /usr/src/release/picobsd/build/build-mysys
#objdump -f -h -p /kernel
#objdump -f -h -p kernel
The first objdump command displays information
from the running FreeBSD system, and the second from the
PicoBSD system generated from the same sources.
These objdump commands display the
ELF file header (-f), the section
headers (-h), and the program
headers (-p).
An ELF file always contains an ELF header. If the file is an object file it contains a section table. If the file is an executable file it contains a program table. A shared library file contains both a section and a program table. A kernel file contains both section and program tables.
The section table describes
named memory sections with particular attributes
(text, data).
The program table describes ``segments'', which in ELF
terminology contain contiguous memory ready
to be loaded into an address range in virtual memory.
...
Program Header:
...
LOAD off 0x00000000 vaddr 0xc0100000 paddr 0xc0100000 align 2**12
filesz 0x000f7c79 memsz 0x000f7c79 flags r-x
LOAD off 0x000f7c80 vaddr 0xc01f8c80 paddr 0xc01f8c80 align 2**12
filesz 0x000188c8 memsz 0x0002f910 flags rw-
...
Sections:
Idx Name Size VMA LMA File off Algn
...
4 .text 000c46b8 c0118d00 c0118d00 00018d00 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
5 .rodata 0001a8b9 c01dd3c0 c01dd3c0 000dd3c0 2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .data 00017bbc c01f8c80 c01f8c80 000f7c80 2**5
CONTENTS, ALLOC, LOAD, DATA
...
18 .bss 00017030 c0211560 c0211560 00110560 2**5
ALLOC
...
A FreeBSD kernel built from the same sources shows:
...
Program Header:
...
LOAD off 0x00000000 vaddr 0xc0100000 paddr 0xc0100000 align 2**12
filesz 0x0028111f memsz 0x0028111f flags r-x
LOAD off 0x00281120 vaddr 0xc0382120 paddr 0xc0382120 align 2**12
filesz 0x00032de0 memsz 0x000545d8 flags rw-
...
Sections:
Idx Name Size VMA LMA File off Algn
...
4 .text 002073a8 c0126a80 c0126a80 00026a80 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
5 .rodata 000532df c032de40 c032de40 0022de40 2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .data 00031ba0 c0382120 c0382120 00281120 2**5
CONTENTS, ALLOC, LOAD, DATA
...
19 .bss 000217f8 c03b4f00 c03b4f00 002b3f00 2**5
ALLOC
Both kernels always have two LOAD segments.
The two program LOAD segements are the read-only executable
text segment and the read/write data segement.
When FreeBSD boots, the text size is displayed, along
with a ``data='' display that shows the size of the data segment
plus the size of the .bss section. The .bss section corresponds to
space that can simply be zeroed, which is why it is marked
ALLOC but not LOAD.
Initial footprint of the PicoBSD kernel is thus text=1,014,905 (0xF7C79) and data=[100,552+94,256] (0x188C8+0x17030), or 1,209,713 bytes. The FreeBSD kernel is text=2,625,823 (0x28111f) and data=[208,352+137,208] (0x32de0+0x217f8), or 2,971,383 bytes.
You can dump a given section using objdump. To get a
hexdump of the
``.rodata'' section:
#objdump -s -j .rodata kernel | more
To find a string in the kernel (for instance, the MFS
in the
``MFS Filesystem goes here'' string), first find the
section containing the string:
#hd kernel | egrep MFS
000fabe0 4d 46 53 20 46 69 6c 65 73 79 73 74 65 6d 20 67 |MFS Filesystem g|
Use the file offset (in this case 000fabe0) to locate
the section. Examine the ``File off'' fields
produced by:
#objdump -f -s -p kernel
In this case, the string is in the ``.data'' section.
Now, find the offset of the start of the string in the section:
#objdump -s -h .data kernel | egrep MFS
c01fbbe0 4d465320 46696c65 73797374 656d2067 MFS Filesystem g
The string starts at c01fbbe0, so dump the section starting
from that location:
#objdump -s -j .data --start-address=0xc01fbbe0 kernel | more
Over time there have been a number of ways to build PicoBSD,
including Makefile-based techniques
(at least for some
build directories). Also, there was
a prior technique
based on a script called build.
It is very common to start with one of the existing
approaches and develop your own system, specific
to your development requirements.
Prior to FreeBSD 4.3, the picobsd script
had to be used with private
configuration directories created in
``/usr/src/release/picobsd''.
This meant that the developer had to work in the
FreeBSD source tree. The use of the
picobsd script in this fashion is described
in this section.
* Unless you simply want to perform a reference build,
create a new configuration directory
as root in ``/usr/src/release/picobsd''.
Give this new
directory the name
that you want to give your custom PicoBSD configuration. Copy one of the
standard reference directories into your configuration directory.
For instance, to create a configuration directory named mysys
based on the PicoBSD
bridge reference configuration:
#su
#cd /usr/src/release/picobsd
#cp -R bridge mysys
* After modifying the PicoBSD configuration files in
the mysys directory, to build your system
you would:
#su #cd /usr/src/release/picobsd/build #./picobsd mysys
The build results will be left in the
/usr/src/release/picobsd/build/build_dir-mysys
directory. These results would include the uncompressed
kernel file and the ``picobsd.bin'' file,
which contains the floppy image (and which includes the compressed
kernel file).
* To build one of the standard reference systems,
for instance router,
you would:
#su #cd /usr/src/release/picobsd/build #./picobsd router
The build results will be left in the
/usr/src/release/picobsd/build/build_dir-router
directory.
There is no need to copy the picobsd script
into a location in your path when using the method of
building PicoBSD described in this section.
A potential disadvantage of this style of development is
that it conflicts with using cvsup to incrementally
synchronize your source-code tree to the evolving FreeBSD
source. Because any files you have modified and the files in the source
tree will have different hashes, modified files will be replaced.
At one time it was apparently common to keep downloadable versions of the standard ``reference'' systems available. This practice appears to have become de-emphasized, due to the proliferation of devices and the need to keep PicoBSD as small as possible (thus only including support for those hardware devices you have in your specific target machine). It is also no longer as necessary, since every FreeBSD installation that includes source can readily build the standard PicoBSD configurations.
Sure. Don't overlook what can be done just by building a FreeBSD system with a minimal configuration file. Today, many embedded systems support large flash disks (64M, 128M, 256M). On devices of this size, people often simply run FreeBSD.
If you have done a full FreeBSD install
that included the documentation,
the
FreeBSD Handbook in the
/usr/share/doc
directory
contains an example of such a minimal config file, called MINI.
Following a full installation, the doc directory
contains three versions of the handbook,
a single web page
(/usr/share/doc/handbook/book.html),
a text file (/usr/share/doc/handbook/book.txt),
and a collection of web pages
(/usr/share/doc/handbook/index.html).
The config file is included in a
script that puts the generated kernel
on a bootable floppy as a backup ``save disk''.
The script (and config file) can be found at the bottom of
web page:
/usr/share/doc/en_US.ISO_8859-1/books/handbook/backup-programs.html
Near the middle of the web page, Section 11.3.8, Emergency Restore Procedure, contains:
`An example script for creating a bootable floppy:'
If this example script does not find an existing MINI
FreeBSD configuration,
it echos the MINI sample configuration file it contains
to the console.
(You can read the handbook by doing a
``cd /usr/share/doc/handbook'' followed by a
``netscape index.html &'').
This web page is also at
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/backup-programs.html
and the handbook
at
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook
.
Again, PicoBSD is really just FreeBSD, so the actual code is the work of the huge team of people that participate in FreeBSD development.
Currently,
Dr. Luigi Rizzo
of the University of Pisa
is the lead maintainer and committer of the
picobsd script.
Many FreeBSD committers appear to work on occcasion on
the files in the PicoBSD source.
Many, many people have apparently contributed over the years
to PicoBSD and the utilities that it requires.
Although it is difficult
to attribute all involved,
some of the more frequent names encountered
in PicoBSD related files and utilities are
Andrzej Bialecki (who wrote the
first version of the build script
and many of the tinyware tools),
Dinesh Nair (who maintained
version 2.2.5 of
PicoBSD), Mike Smith, Poul-Henning Kamp,
Josef Karthauser, Doug White,
James da Silva of the University of Maryland,
Greg Lehey, Joe Greco,
and various programmers at the University of Utah.
I have no doubt missed many key people, for which
I apologize.
You can scan the CVS source tree yourself and see who is working
on what. The CVS tree is at:
http://www.FreeBSD.org/cgi/cvsweb.cgi/src/release/picobsd.
PicoBSD was originally developed by Andrzej Bialecki (http://people.FreeBSD.org/~abial) while at what was then Poland's national ISP, the Research and Academic Network in Poland (NASK). Andrzej credits the Xkernel as an antecedent inspiration. The orignal Xkernel was apparently based on a stripped-down version of SunOS (itself a BSD derivative).
Similar engineering problems often engender similar solutions, and there has always been a need for PicoBSD-style systems. For instance, I still find myself sometimes momentarily confusing PicoBSD and RSX-11S [1], although I know I shouldn't... I'm leaving in these links because there still might be an idea or two there...
Again, PicoBSD is just FreeBSD, so it is under the same BSD license as FreeBSD. The short version of what the ``new BSD'' license means is that you can use the code for any purpose, including your own commercial products, but you cannot sue the developers or make any claims in their name. Nobody but you has liability for what you do with the code. You do not have to give any code you write back to anyone or make your code open source.
This has become a huge industry. Industrial PC's are often intended to be rack-mounted or mounted in small ``shoe-box'' enclosures. Many industrial systems will cost considerably more than a stock retail PC, as they are designed to operate reliably in electrically noisy environments.
Standard industrial motherboard form-factors today include biscuit PC's that are the same size as a floppy drive, and mini biscuits, which are about half the size of a biscuit. Also popular are POS motherboards, which stands for Point of Sale (which means cash register). POS PCs often include a number of interesting I/O devices for interfacing scales, bar-code readers, drawer locks, and such.
Many of these boards are highly integrated with many of the device controllers directly on the motherboard. All but the mini biscuits often support the PC/104 bus. This is an embedded version of the ISA bus with a smaller form-factor. It supports small boards about 3.5 inches square which stack vertically on top of one another. A new form-factor is the ``half-biscuit'', which is a small motherboard about half the size of a conventional ATX motherboard (not half the size of a biscuit). These are popular for set-top boxes, home firewall applications, and such. Integrated PC CPU chipsets are reaching the point where it is fairly easy to build custom single-board PCs. Such single-board computers are often called SBCs.
With most PCs, it is often not worth trying to get much smaller than the biscuit form-factor, as the size of the connectors does not shrink and comes to dominate the system. Power supplies also often dominate system size.
In industrial environments in which size if not that important but custom boards or flexible hardware configurations are to be deployed and reliability and maintenance is important, passive backplane systems are often used. These systems are not built around a traditional PC motherboard, but rather around a simple backplane containing a number of slots (typically 6 to 8). The CPU is mounted on a card inserted into one of these slots. Passive backplanes are typically more reliable then a conventional motherboard, which is large and is flexed when cards are inserted. The use of passive backplanes tends to result in systems in which boards can rapidly be replaced and upgraded in the field, resulting in reduced downtime. These systems are highly configurable, usually well shielded from electrical noise, can often support multiple CPU cards, and resemble many ``old-fashioned'' computers. Passive backplane versions of x86 PCs are common. These systems appear largely indistinguishable from any other PC as far as software is concerned, although they often have a few additional ``standard'' devices, such as a watchdog timer.
The following are academic-related groups that use PicoBSD in research:
Dr. Luigi Rizzo of the Dipartimento di Ingegneria dell'Informazione at the Universita di Pisa uses PicoBSD as a platform for network protocol research. Contact: luigi@iet.unipi.it
The Distributed System Lab of the E.E. department at National Cheng Kung University in Taiwan is working on fault-tolerant PicoBSD clusters, primarily applied to routing and firewalls. Contact: tung@turtle.ee.ncku.edu.tw
The Transparent Telepresence Research Group of the Design, Manufacture and Engineering Management Department of the University of Strathclyde in Glasgow uses PicoBSD in Telepresense research. Contacts: jen@vulture.dmem.strath.ac.uk, roger@cs.strath.ac.uk
§ Static ``linked-single-image'' flavor.
* You can't copy or download an arbitrary FreeBSD binary executable to the system and expect it to run, because such a binary will usually dynamically link to loadable libraries that are not present. You have to either explicitly build all executables into the ``crunched'' application image(s) or statically link the downloadable application image so that it includes all needed library routines (which will typically make the application much larger).
* You have to decide in advance what overall functionality you require (this is true, however, of many embedded systems).
* Because all libraries are linked together, there may be irreconcilable library dependencies that preclude some combinations of libraries (and thus the executables that depend on the libraries).
This is not just a ``theoretical'' problem. It can
occur is if you need a number of applications that all link
to the same library, and the library
``assumes'' it is linked to a single application and
keeps ``dirty'' global data. Libraries that reference
other libraries, or global data in other libraries, may have similar
problems. Library conflict problems can also arise from collision
on common names, for instance, debug.
Examples of these problems occur in the use of ssh
and NTP ``libntp.a'' libraries. The
PicoBSD ssh port
was created to eliminate such problems with ssh,
but the general problem must be solved on a case-by-case basis.
§ Not all FreeBSD features.
* There is no support for loadable kernel modules.
* No X11. Depending on your needs, you may be able to use the
vga
driver and
vgl.
* The current version of PicoBSD provides no boot-phase configuration. There is no interactive FICL boot loader, and there is no kernel configuration utility. This means that you cannot simply include a lot of drivers and then decide, during boot, what drivers to disable. You should build in exactly what you need. This also may restrict the utility of keeping ``standard'' system images.
§ Running without a swap device can be dangerous.
Because PicoBSD runs diskless, by default it has no swap device. FreeBSD can become unhappy if it runs out of memory and cannot swap.
* Size.
Because PicoBSD runs using a RAM-based root file system, it may have a larger RAM footprint than alternatives that do not use RAM-disk.
§ Embedded development cycle.
* The application development cycle, typical of embedded cross-development, may be more complex than when the host and target system are the same.
* Not all the debugging and diagnostic programs that one is accustomed to using are likely included in a PicoBSD configuration. Thus, PicoBSD is rarely used as an application development platform. (Consider it more for the embedded deployment of a stable application).
* It may be difficult (if not impossible) to make persistent changes to files across boots if you have not planned for the particular update.
* You must have the FreeBSD source tree installed to develop for PicoBSD. You need to have a FreeBSD system installed somewhere with enough disk space to keep the FreeBSD source tree. You need to be able to install and maintain FreeBSD, and have some mechanism for tracking changes in the FreeBSD code base.
§ No true cross-compilation.
PicoBSD does not support a true cross-compilation
development cycle, that is, compiling on a machine such as an Alpha
and producing a system for a low-end PC. Typically, PicoBSD is compiled
on a large host-PC that can target a smaller embedded PC using the same
source code
tree that compiled the host kernel
(albeit perhaps with a different kernel configuration file cpu
setting, and similar changes).
Because PicoBSD is compiled directly from the installed FreeBSD source, this cross-compilation incompatibility holds even between versions of FreeBSD. That is, you cannot compile a version of PicoBSD based on the FreeBSD 3.2 source under FreeBSD 4.3, or compile a version of PicoBSD based on the FreeBSD 4.3 source under FreeBSD 5.0, and so on.
This is an area receiving current development attention.
§ Not hard real-time.
Neither FreeBSD nor PicoBSD are particularly
good for true real-time applications (which is true of *ix
in general). If you need to control
an aileron using a hard real-time
system with predictable performance guarantees, PicoBSD is
probably not for you. Most PC hardware is not that great for
true real-time tasks either.
However, that being said, many
actual embedded applications really
have relatively modest soft real-time requirements.
In addition,
you can shovel many real-time programming tasks into drivers,
which by necessity are real-time.
Tracking a mouse on the screen, for instance, is a
canonical real-time task.
Also, see
``man kqueue''.
PicoBSD is not a system that has been expressly designed for embedded systems or for soft--real-time. PicoBSD is just what it is, namely a version of FreeBSD that has been built so as to run diskless and minimize the boot image sufficient to fit on a floppy.
§ Affinity
The PicoBSD code base is FreeBSD, which includes the classic TCP/IP reference implementation. If you are familiar with FreeBSD (or any *ix), you can use PicoBSD in many embedded application scenarios without needing to learn how to cross-develop for a special-purpose embedded OS that has its own tool-chain. The natural development environment for PicoBSD is classic, vanilla C. Your familiarity with FreeBSD is directly useful in the embedded project. If you install FreeBSD with sources, you have, in PicoBSD, an entire embedded system development package with a complete tool-chain.
§ Minimal feature-set
Unlike the normal FreeBSD system, in which many features default to being in and you then decide what to throw out, PicoBSD defaults to almost everything being out, and you have to explicitly decide what to include. This is an advantage is some types of engineering projects.
§ Diskless
PicoBSD runs everything out of RAM-disk, which may provide a performance benefit for some applications.
PicoBSD can boot from a read-only device (for instance, a CD-ROM). In this case, since files are built into the filesystem inside the kernel image, they cannot be permanently edited. This can be somewhat of a security benefit.
A booted PicoBSD system does not require a disk device (or any secondary storage device).
§ Enhanced fault-tolerance
A default PicoBSD system can
be
powered
off at anytime
without danger of corrupting any disks or
requiring a lengthy fsck execution during the next boot.
(Naturally, this will not be true if you explicitly mount
hard-disks or similar devices).
Indeed, the default PicoBSD configurations do not contain the
halt or shutdown commands
(reboot is included).
§ Controlled ``embedded-style'' configuration of the complete system
You can't copy or download an arbitrary FreeBSD binary executable to the system and expect it to work, because it likely depends on loadable libraries that are not present. In some commercial, production, and embedded environments in which all components of a system are to be tested as a single package, this is a ``release engineering'' advantage.
PicoBSD, as of FreeBSD 4.3, does not use the standard FreeBSD boot-Forth environment (FICL). PicoBSD simply ``boots-direct''. Forth is very good for poking around in the hardware from the console, booting alternative kernels, and such. In an embedded scenario, you may not want to enable the computer ``operator'' to interact with the system boot process in this fashion.
Because all executables are linked into a single image that itself is included in the kernel file, multiple PicoBSD versions can be stored in single bootable files with each such file including all required applications and data files. Systems that have been built with different application and configuration support will automatically load with the correct applications, application support features, and required files.
PicoBSD is built from a single script
(picobsd). This script
contains two simple
menus. You can easily modify this script to run in batch mode,
and can also readily modify it to build a large number of systems,
similar or not (for
instance, all the elements of a cluster).
§ Small self-contained system with no post-boot installation
PicoBSD typically consists of
a single small kernel file
that can be compressed;
this small kernel file is the only file
that needs to be transported or downloaded to boot a running
system.
PicoBSD is self-contained. Everything is in a single self-extracting file. In default PicoBSD, you do not need to format and layout disk devices after you initially boot the system. For the required root directory tree, you specify the size and layout before you build the system.
PicoBSD naturally creates floppy
images that are easy to e-mail as attachments.
The entire bootable floppy system (the single ``picobsd.bin'' file),
including the root file system
and all utilities needed to run, is small enough to be e-mailed
without undo trouble. This can be quite useful when
debugging a kernel, driver, or hardware specific feature in a
world-wide programming group -- just mail your entire system
to a coworker to test/verify.
For some types of development, because of the small system size, the development cycle is particularly fast. This is especially true if you are booting via Ethernet (either netbooting, or copying over the LAN to flash and then booting from flash).
PicoBSD is small enough that two versions of PicoBSD can be kept on a small flash device. For instance, both a ``current'' version and an ``old-good'' version of a PicoBSD can be kept on a small 8Mbyte M-Systems DOC device.
§ Supports easy generation of many related variants
Because of the scheme in which a ``base collection'' of scripts is extended by scripts in private configuration directories, many related systems can be generated at the same time with relative ease. This is a natural way to generate systems for a slightly heterogenous cluster.
§ Supports large host development for small targets
Because the PicoBSD development cycle is essentially a cross-development cycle, it is naturally the case that one normally develops on as large an interactive host machine as possible, while often targeting the smallest PCs obtainable. This is usually the desired way to develop for small, low-end machines.
§ Enables student research projects
Because PicoBSD is a cross-development system that
rapidly makes a bootable floppy,
PicoBSD provides a means for every student in a class
to build their own real system and experiment with their own system,
without the encumberances associated with the need for multiple
dedicated hard-disks. Students do, however, need to have root
access on the machine that runs the picobsd script.
For certain types of student projects, it is desirable for students to have a view of ``everything''. PicoBSD is good for this sort of project. For instance, the startup scripts are much smaller than for full-blown FreeBSD and many other systems.
Because PicoBSD boots from floppy and runs diskless, you can use it to rapidly experiment with different system software without performing any system installation work. For instance, in a PC research lab, a prototype cluster could be constructed in minutes by booting all machines from preconfigured PicoBSD floppies. After the experiemnt/evaluation is over, the PCs can be rebooted to run their normal system.
§ Cheap
If you need a lot of systems (a compute cluster) but can implement your application on PicoBSD, you can save a lot of money because you do not need to buy any hard disks. Unlike many clustering scenarios, in which NFS or some other distributed file system is used, no networked filesystem I/O is required. No file servers are required.
PicoBSD is a good way to turn an old legacy PC into a very low-cost router, firewall, homebrew platform, instrument controller, or low-cost student lab machine. The cost is right.
man pages should I read?
picobsd
crunchgen
crunchide
mtree
vnconfig
vn
ld
dd
disklabel
disklabel (5)
disktab
objdump
elf
ldd
boot
pxeboot
kqueue
vga
vgl
io [1]
bridge
dummynet
See the file
/usr/src/sys/i386/conf/LINT
for FreeBSD configuration file (PICOBSD) kernel options.
See:
http://people.freebsd.org/~picobsd
http://people.freebsd.org/~picobsd/small-tips.html
§ Much of the available PicoBSD documentation is
somewhat dated. This is not necessarily a bad
thing, as it provides a history of
the project and its objectives.
PicoBSD originally existed independently
of the FreeBSD CVS source tree. It was folded into the
standard FreeBSD CVS source tree in 1999.
The best way to learn about PicoBSD is to
browse the PicoBSD sources in
/usr/src/release/picobsd
(if your source is not installed in /usr/src
you will need to manually enter the appropriate URL).
§ The primary (old) documentation is
``man picobsd''
and even older documentation (primarily ``.htm'' files)
is included in
/usr/src/release/picobsd/doc/src.
There is a slightly dated PicoBSD FAQ in
/usr/src/release/picobsd/doc/src/faq.html. This FAQ primarily describes FreeBSD 2.2.5-RELEASE and FreeBSD 3.2-RELEASE versions.There is another slightly dated PicoBSD FAQ in
/usr/src/release/picobsd/doc/src/intro.html, which primarily describes FreeBSD 3.0 versions. Note that themanpage build instructions are no longer accurate.
See also the README files in
the
/usr/src/release/picobsd/tinyware
subdirectories,
and the documentation at the top of the
/usr/src/release/picobsd/build/picobsd
script.
The tinyware README files are:
msg (alt. to dmesg)
ns (alt. to netstat)
oinit (alt. to init and sh)
simple_httpd (alt. to httpd web server)
vm (alt. to vmstat)
(the following appear depricated) aps
sps
help
view
It may be useful to examine the somewhat dated documentation
in
/usr/src/release/picobsd/help/.
§ Academic citations, research literature, and research web sites related to PicoBSD are listed in the section on Academic references.
freebsd-small@freebsd.org mailing list?See:
www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/eresources.html
To subscribe, send mail to ``majordomo@freebsd.org''. This mail will not
be read by a human; the body of the message should contain only:
subscribe freebsd-small@freebsd.org
You will get back a mail message containing an authorization code string.
Assuming this string is ``foo'', you then send a mail message back
to ``majordomo@freebsd.org'' with a message body
containing only:
auth foo
To unsubscribe, send a mail message to ``majordomo@freebsd.org''
with the body:
unsubscribe freebsd-small@freebsd.org
You will also have to make an authorization reply.
freebsd-small@freebsd.org mailing list archives?
Browse the ``freebsd-small@freebsd.org'' mailing list at
``http://docs.freebsd.org/mail''.
Select a time-period and then select
``freebsd-small.html''.
To browse the current mail messages, select ``this week'' from the bottom
of the time-period list.
To directly browse the
freebsd-small archives for past years,
use the following:
http://docs.freebsd.org/mail/archive/1998/freebsd-small
http://docs.freebsd.org/mail/archive/1999/freebsd-small
http://docs.freebsd.org/mail/archive/2000/freebsd-small
http://docs.freebsd.org/mail/archive/2001/freebsd-small
§ The source.
The PicoBSD CVSed source is browsable (with changelogs) on the web at www.FreeBSD.org/cgi/cvsweb.cgi/src/release/picobsd.
§ FreeBSD Pico pages.
www.freebsd.org/ports/picobsd.html
This page contains ports (applications) in the FreeBSD port tree which are specific to PicoBSD. Currently a version ofsshintended to be crunched into PicoBSD is the only port. See also http://freshports.org/port-description.php3?port=5418.
See the Small FreeBSD Home Page at http://people.FreeBSD.org/~picobsd and the PicoBSD home page at http://people.FreeBSD.org/~picobsd/picobsd.html.
www.picobsd.pbg.pl
A mirror of one of the early PicoBSD pages. This now appears primarily of historical interest.www.freebsd.org
This is the home of the FreeBSD project.
§ Miscellaneous pages.
www.freebsd.org/doc/en_US.ISO8859-1/articles/solid-state/index.html
The article FreeBSD and Solid State Devices, by John Kozubik.www.munts.com/diskless/netboot.pdf
The paper, Network Booting i386 Unix Variants, by Philip Munts.http://matt.simerson.net/computing/freebsd.netboot.shtml
The web-paper Booting FreeBSD with PXE.www.cse.ucsc.edu/~brucem/fbsd_links.htm
This is a page I maintain with academic-oriented (grad student) FreeBSD links.
§ Similar Systems.
www.embsd.org
emBSD is a stripped down version of OpenBSD primarily used for routers and firewalls.www.gnatbox.com
The folks at GTA note that their Gnat box product was the ``inspiration'' for PicoBSD... Their FAQ has some interesting information and ideas...http://busybox.lineo.com
The Busybox is essentially Linux PicoBSD-ized... It grew out of Debian boot disk technology. See also www.linuxdevices.com/articles/AT4802795572.html
Trinux is based on Busybox, see http://trinux.sourceforge.net.www.linuxrouter.org
The Linux Router Project (LRP).http://learn.western.tec.wi.us/aev/linux/router_freesco_v026.htm
Freesco is a single-floppy Linux router.http://sourceforge.net/projects/mobsd
The Micro OpenBSD project. This project appears attempting to create a floppy-based version of OpenBSD ``...inspired by emBSD, PicoBSD and Trinux.''www.embedded-linux.org
The Embedded Linux Consortium.http://bengross.com/smallunix.html
A portal with links to small/embedded *ix systems and projects.www.cotse.com/miniunix.htm
Another portal with links to small/embedded *ix systems and projects.
§ A Few PC Bit-twiddling pages...
http://et.nmsu.edu/~etti/fall96/computer/printer/printer.html
Use of a PC Printer Port for Control and Data Acquisition, by Peter H. Anderson.www.beyondlogic.org/spp/parallel.htm
Interfacing the Standard Parallel Port, by Craig Peacock.www.beyondlogic.org/epp/epp.htm
Interfacing the Enhanced Parallel Port, by Craig Peacock.www.beyondlogic.org/serial/serial.htm
Interfacing the Serial / RS232 Port (part 1), by Craig Peacock.
Also, www.beyondlogic.org/serial/serial1.htm (part II).www.beyondlogic.org/keyboard/keybrd.htm
The PC's keyboard, by Craig Peacock.www.beyondlogic.org/interrupts/interupt.htm
Using Interrupts, by Craig Peacock.
www.iet.unipi.it/~luigi/COST264/mcm990207/#rizzo
This is the abstract for the paper,
Some FreeBSD-based tools to support networking research and experimentation,
COST264, 8 Feb 1999, from the COST264 workshop on
Enabling Networked Multimedia Group Communication.
The slides for this talk are online at:
www.iet.unipi.it/~luigi/COST264/mcm990207/rizzo.
The only published academic reference of which I am aware that is directly concerned with PicoBSD is `` Forth and the FreeBSD Bootloader'', Paul Frenger, ACM SIGPLAN Notices, August 2000, v.35, n.8, pp.15-17. Despite the title, about half of this small 3-page paper is devoted to PicoBSD, in its capacity as a ``single-floppy'' means to run Forth. The interactive FreeBSD FICL bootloader is a portable implementation of Forth. To minimize size, the FICL boot loader is no longer built into PicoBSD.
turtle.ee.ncku.edu.tw/sgcluster
This web-site describes the SG cluster system, which
clusters PicoBSD for load balancing and high availability in NAT and VPN
type applications.
www.prevelakis.net/Usenix/secnet.html
This paper, A Secure Station for Network Monitoring and Control,
describes the ``PicoBSD-ization'' and deployment of a custom system
based on OpenBSD. The system appears to have
evolved from PicoBSD scripts and
was developed to implement network management and security nodes
at the University of Piraeus in Greece. Despite being based on OpenBSD,
this paper and those cited immediately below all contain a clear page-long high-level
summary of PicoBSD.
* See also
``
www.usenix.org/events/sec99/full_papers/prevelakis/prevelakis.pdf''.
* See also
``
www.cis.upenn.edu/~vassilip/TechRep-MS-CS-00-21.pdf'',
The Shrink-Wrapped VPN Node,
by Vassilis Prevelakis and Angelos Keromytis,
Technical Report MS-CIS-00-21,
Digital Systems Laboratory,
Department of Computer and Information Science,
University of Pennsylvania.
* See also
``
http://csweb.rau.ac.za/ifip/workgroup/docs1999/07_sec1999.pdf'',
A Secure Station for Network Monitoring and Control,
by Vassilis Prevelakis.
A normal PC with a default BIOS setup cannot run without a keyboard.
It will produce an error message such as ``Press F1 to Resume''.
Many older systems will not run without a video card; the system will
enter a ``beep loop'' sending out a beep sequence that indicates a
fatal video controller initialization error.
There are a number of ways to make a PC run headless. This is particularly useful when you want to turn an old PC into an Internet router in a box, an Internet-enabled embedded instrument manager, or part of a home-brew cluster.
§ Many new PC BIOSes can simply be told to ignore errors encountered
when trying to initialize the video card and keyboard
at BIOS boot-time. With a monitor and
keyboard attached, enter the BIOS setup program and search for a setting
such as ``Errors:'', ``Halt on:'', or ``Ignore''.
Often you can set this field to ``Any, but keyboard and video'',
or even ``none''.
§ If the BIOS requires a video card, find a used card with a standard VGA chipset (like Trident). It will not need a connected monitor. This is a great use for those cards from a $5 all-used-cards barrel, no refunds. Most will work sufficiently to enable booting.
§ If your BIOS requires a keyboard, get an old keyboard, take it apart, and connect the small ``keyboard motherboard'' to the motherboard's keyboard connector. The ``keyboard motherboard'' is typically a small printed-circuit board about 1 inch by 9.5 inches. It usually contains only a single IC. One end of the keyboard cable will be connected to the ``keyboard motherboard''. You may want to reduce the length of the connector cable. There is no cheap, easy way to wire something to the PC keyboard connector that will ``fake'' the keyboard (available devices that do this cost as much as 5 times a used keyboard). The keyboard is actually a small embedded real-time computer (originally an Intel 8048). It communicates with the PC using a simple protocol based on 11-bit ``serial data units'' (SDUs).
To take a keyboard apart, find 5 or 6 slots that will be located on one of the edges, insert a flat-head screwdriver, and flex and wiggle. The keyboard clamshell will pop open. Another dozen or so small latches will hold the key-mount board to the clamshell bottom. Use a needle-nose or screwdriver to unlatch a few of these, then grab one end of the key-mount board and separate from the clamshell bottom (this may take some force but the key-mount board with all the keys will come off cleanly). You should now be able to remove the "keyboard motherboard', being careful to work loose the attached keyboard connector cable (it is usually not fastened but just twisted into a holder). Attached to the "keyboard motherboard" will be a large 1.5 foot by .5 foot poly-flex circuit (mylar sheet). This mylar sheet is attached to the "keyboard motherboard" by a 35-pin conductive snap that clamps the mylar to the small motherboard. Work the mylar out of the snap and work the snap loose at the same time. Be sure to remove the snap completely from the ``keyboard motherboard''. If the mylar is removed and the snap left in place, when the keyboard controller is connected and power to your PC turned on, all keyboard circuits are shorted, which will result in a large power-draw and typically smoke will then emerge from the vicinity of your keyboard connector on the PC's motherboard.
You should not swap (plug or unplug) a keyboard connector with the motherboard powered up.
§ If you are collecting old PCs to use as routers
or cluster test-beds, you may have to deal with lost BIOS passwords.
Most BIOSes have the ability to save some sort of password in the
real-time clock CMOS. If set, by the time you get the machine
and want to run it headless,
the password will have been long forgotten. The security provided by these passwords is of the
``irritation'' variety. A quick web search will typically provide dozens
of programs, most of which are DOS ``.exes'', that will decode
and display the passwords.
If your junk PC has an AMI BIOS (American Megatrends), and you are in a hurry or don't have DOS, you can do the following (it's not pretty).
§ Modify kernel source file ``
/usr/src/sys/kern/tty.c'' in your PicoBSD kit and change the code at the top ofttyinput()to be similar to the following (this is for FreeBSD 4.3; adjust for other versions if need be). Insert the code fragments between the ``AMIBIOS PWD DECODE'' comments:/* * Process input of a single character received on a tty. */ int ttyinput(c, tp) register int c; register struct tty *tp; { register tcflag_t iflag, lflag; register cc_t *cc; int i, err; /* AMIBIOS PWD DECODE (start) */ int ioadr,val; unsigned char pswd[10]; unsigned char ch,cl,dh,dl; /* AMIBIOS PWD DECODE (end) */ /* * If input is pending take it first. */ lflag = tp->t_lflag; if (ISSET(lflag, PENDIN)) ttypend(tp); /* * Gather stats. */ if (ISSET(lflag, ICANON)) { ++tk_cancc; ++tp->t_cancc; } else { ++tk_rawcc; ++tp->t_rawcc; } ++tk_nin; /* * Block further input iff: * current input > threshold AND input is available to user program * AND input flow control is enabled and not yet invoked. * The 3 is slop for PARMRK. */ iflag = tp->t_iflag; if (tp->t_rawq.c_cc + tp->t_canq.c_cc > tp->t_ihiwat - 3 && (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) && (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) && !ISSET(tp->t_state, TS_TBLOCK)) ttyblock(tp); /* AMIBIOS PWD DECODE (start) */ if( c == '.' ) { printf( "\n------ CMOS Contents---\n" ); /* ioadr = 0x0E; */ ioadr = 0xB7; for(i=0;i<7;i++,ioadr++) { outb( 0x70, ioadr ); val = inb( 0x71 ); printf( "\n cmos of=%x adr=%x v=%x ", i, ioadr, val ); pswd[i] = val; } printf( "\n----\n\n" ); pswd[0] &= 0xF0; for(i=1;i<8;i++) { if( 0 == pswd[i] ) break; cl = 0; ch = pswd[i-1]; for(;;) { cl++; dh = dl = 0; if( ch & 0x80 ) dh++; if( ch & 0x40 ) dh++; if( ch & 0x02 ) dh++; if( ch & 0x01 ) dh++; while( dl < dh ) dl += 2; dl -= dh; ch >>= 1; if( 1 == dl ) { ch += 0x80; } if( ch == pswd[i] ) break; } /* End decrypt loop. */ printf( " decr=%x (%c) ", cl, cl ); } /* End for input chars */ } /* AMIBIOS PWD DECODE (end) */§ Build PicoBSD, and boot the PicoBSD floppy. At the prompt, whenever you press ``
.'', the BIOS password should be displayed (consisting of the characters between the ``()''s). Use this password to enter the BIOS and change the password. Entering a null password will usually disable BIOS password protection.
If you have equivalent code of other BIOSes, please let me know. Decoding these from an existing ASM takes about 2 hours.
§ All you need to run stock PicoBSD with TCP/IP is an Ethernet controller, a floppy controller, and (perhaps) a video controller. Many new motherboards include all these controllers directly on the motherboard. The remanents of many old junk PC's contain these components in completely working form.
When using PicoBSD on a headless system with an Ethernet controller,
you will need to modify the
``./floppy.tree/etc/rc.conf'' script in your config directory.
The default ``rc.conf'' behavior is to prompt at
PicoBSD boot time to
``Please enter a hostname and IP address for your system''.
Depending on your circumstances, you may want to hardcode the
hostname and IP address by recoding routine read_address()
in ``rc.conf'' to contain lines such as the following:
hostname=slowsys
the_ip=192.168.0.30
§ It is easy to operate PicoBSD using just a motherboard, power supply, and floppy drive. You do not even need to use a PC case, which is useful for applications such as home-brew clustering. Be careful to avoid shorting the board and assure reasonable air-flow. Most hardware stores carry 8-32 nylon bolts of various lengths. These fit the mounting holes on typical motherboards (even biscuits), and can be used to make custom mounts.
When resurecting an old computer, it is worth taking the whole system apart and going over everything at close range with a normal household vacuum cleaner, making sure all the empty slots and chip pins are free from dust. Beware any loose jumper straps... If the system has been in a chemically ``dirty'' environment for a long time, you may want to take the boards out and clean the gold contact pins. Use a rubber eraser to remove any ``scum-film'' build-up from gold surfaces. Without the hard-disk, many old systems will run fine.
As compact
flash and M-systems flash devices become cheaper and common, it will
be increasingly easy to replace the floppy. Alternatively, if the
Ethernet controller supports PXE (the Preboot Execution Environment
standard), you can boot the PicoBSD kernel
file directly over the network, that is, use the LAN controller as your boot
device.
§ A simple web-server is very easy to write, and running a web-server on a RAM-disk has its advantages. A small sample web-server suitable for including in PicoBSD is located at:
/usr/src/release/picobsd/tinyware/simple_httpd
The simple_httpd server
is only around 500 lines-of-code and 25 Kbytes when compiled.
To add it to your PicoBSD system,
assure that the following lines are in your
``crunch.conf'' file and rebuild your PicoBSD configuration:
srcdirs /usr/src/release/picobsd/tinyware
progs simple_httpd
Once the PicoBSD system boots, do the following on the PicoBSD system, or put the equivalent commands in the startup scripts:
#cd /
#mkdir httphome
#cp /etc/motd /httphome/index.html # (or somesuch)
#simple_httpd -d /httphome -l /dev/null &
This makes /httphome, which is the
default, the root directory of your web-pages
and discards the server log.
The cp command in this example
simply creates a home-page for your web-site;
in practice this will be a custom file of
yours instead of the motd file.
Now you can use a browser, such as Netscape, from another system to access your PicoBSD web-server. For instance, if you are in a lab environment and your PicoBSD system has a private IP address of 172.16.0.5, you could issue a command such as:
#netscape 172.16.0.5 &
§ You might want to run the web-server in
visual logging mode
on the PicoBSD console (or on an
alternate virtual console) using
the ``-D'' switch, which indicates that the program is to run
in the foreground and not to ``daemonize''. On PicoBSD this is
an easy way to
see current log activity without bothering to store the log anywhere:
#simple_httpd -d /httphome -D
§ You can operate the web-server
as a dedicated fetch server.
See the README documentation in the
tinyware/simple_httpd
directory.
§ The simple_httpd server will only
use port 80 (the HTTP port) if it is run as root (otherwise
it uses port 1080).
§ Because the ``simple_httpd.c'' server is only 480 lines of code,
it can easily be modified...
One easy way to start might be to simply create web pages
on-the-fly for the simple_httpd server
described in the previous section. Of course, you can
enhance the server to any degree or
write your own socket-based Internet
data acquisition system of almost any
complexity...
in and out instructions)?
For quick-and-dirty embedded hardware work it is often useful to directly read and write device registers in I/O space from within an application program. This can be much easier than developing a complete driver, and is appropriate when you need to do an ``experiment'' with only a few minutes of overhead. Many old DOS C compilers (such as Borland's Turbo C) had very good support for such operations, including interrupt support.
In PicoBSD (or FreeBSD), open ``/dev/io''. Until you close
the handle you obtained from open(), you can read and
write I/O space using calls such as inb(), outb(),
inl(), and outw().
Hold the handle for as short a period as possible.
The following example program ``turns-on'' a 16550 UART output pin in the COM1 serial port (pin DTR, Data Terminal Ready). This is done by setting a bit (bit 1) in the COM1 modem control register. The COM1 modem control register is almost always, on a PC, at I/O space address 0x3fc:
// turn_on.c
#include <stdio.h>
#include <fcntl.h>
// Get inb()/outb() macros.
#include </usr/src/sys/i386/include/cpufunc.h>
main() {
int ios;
printf( "\n *** ON!\n" );
/*----- Gain access to I/O space. */
ios = open( "/dev/io", O_RDONLY );
if (0 > ios ) {
close( ios );
perror("unable to open /dev/io");
exit(1);
}
outb( 0x3fc, 0x01 ); // Set DTR (bit 1) in Modem Ctrl reg of COM1.
close( ios );
/*----- Release I/O space. */
}
See the file
``/usr/src/sys/i386/include/cpufunc.h''
for the other calls that you can use. Build this
program as described in the
section on building
your own application.
A program to turn DTR off would be:
// turn_off.c
#include <stdio.h>
#include <fcntl.h>
// Get inb()/outb() macros.
#include </usr/src/sys/i386/include/cpufunc.h>
main() {
int ios,reg_val;
printf( "\n *** OFF!\n" );
/*----- Gain access to I/O space. */
ios = open( "/dev/io", O_RDONLY );
if (0 > ios ) {
close( ios );
perror("unable to open /dev/io");
exit(1);
}
reg_val = inb( 0x3fc );
reg_val &= ~0x01;
outb( 0x3fc, reg_val ); // Clear DTR on Modem Ctrl reg of COM1.
close( ios );
/*----- Release I/O space. */
}
Electronics suppliers sell
small, cheap devices that can display the state of the
serial-line pins. The more complex devices are often
called ``break-out boxes'' and allow you to strap
pins in various ways. At the low end, LEDs display the
state of the pins.
Radio Shack sells a RS232
Mini-Tester for around $10. This is
the size of a null modem and contains a
state LED for the 7 most commonly used serial-line pins.
It can easily be used with the above two programs to
verify that your program is performing I/O operations.
Some URLs listing such devices:
www.scancat.com/minitstr.html
www.rpelectronics.com/English/Content/Items/TG-339.asp
Three serial-line pins that can easily be used as LED status toggles (or for other purposes) are:
| Pin | COM1 I/O Register Address | Register Bit |
| DTR | 34c | 0x01 |
| RTS | 34c | 0x02 |
| BREAK | 34b | 0x40 |
See also: www.daemonnews.org/200107/dasblinkenlights.html.
§ There are currently two major types of flash disks in use on small x86 PC-based embedded systems.
The so-called Compact Flash, or CF, devices appear exactly to the system as an IDE hard disk, that is, they contain a complete IDE drive controller. These devices are very easy to use (there is no new software required). These devices are typically about half the size of a PCMCIA card.
The M-systems DiskOnChip flash devices (often called a DOC) are useful when a small on-board flash disk is required. Looking at a motherboard, these physically resemble a typical BIOS ROM. These devices require a special driver to enable them to be accessed as a native disk device. Most motherboards that include an M-Systems DOC support a BIOS that can boot from the DOC. Currently DOCs come in 2M, 8M, and 256M sizes.
§ FreeBSD (and PicoBSD) make use of the M-Systems DOC
devices via the fla driver.
The fla driver source is located in a slightly
unusual location in the FreeBSD source tree,
/usr/src/sys/contrib/dev/fla.
This location is used because
FreeBSD fla driver development was funded
by M-Systems
(www.m-sys.com) and is under an M-Systems
license instead of the
standard BSD license. The license appears to be a
typical commercial open source license that takes
pains to make it clear that you can't sue M-Systems.
The important steps described in this section are:
* Add the fla driver to the kernel.
* Put a FreeBSD disk label on the DOC and create a
FreeBSD filesystem.
* Put a bootable kernel on the DOC.
The following section
assumes a PicoBSD configuration
directory named mysys.
§ Add the fla driver to the kernel.
Compile in the fla device driver.
In your PICOBSD configuration file add the device lines:
device fla0 at isa?
Next,
create the fla device node. Edit your
config file and add
to it a device named ``fla0''. A typical
config file might appear as:
MY_DEVS="std tun2 vty10 fd0 fla0 pty0 cuaa0 cuaa1 bpf0 bpf1 bpf2"
Add the utilities needed to initialize a FreeBSD
file-system to the PicoBSD build. Edit
your ``crunch.conf'' file and
in the progs section
add the following lines if they do not already
exist. PicoBSD configuration files can vary greatly,
so check
the file contents.
progs disklabel
progs newfs
progs dd
§ Put a disk label on the DOC.
For the DOC to be used as a ``normal'' FreeBSD (PicoBSD) disk,
the DOC must have a valid disk label.
This disk label describes the disk geometry,
among other things.
The disklabel program is used to create such labels,
in conjunction with the /etc/disktab file,
which contains a
configuration ``database''.
A typical FreeBSD PC hard-disk has an MS-DOS MBR (Master Boot Record)
in the block at the start of the disk.
The MS-DOS MBR, among other things, controls how the disk is
divided into partitions (called slices in FreeBSD
terminology to distinguish them from *ix partitions).
It is usually not desirable to partition a device as small
as the 8Mb DOC. Somewhat awkwardly, the disklabel
program considers disks that do not contain a MBR
removable
devices, since floppy disks are probably the most common
disks that are not usually partitioned.
The disklabel program works by locating a named
configuration section in the /etc/disktab file,
converts the ASCII text in the section to a binary block,
and writes the block to the location at which the system
expects to find the label block(s).
To create the DOC label, edit the file
``/usr/src/release/picobsd/mfs_tree/etc/disktab''.
Note that this file will be included in all
PicoBSD builds.
Add the following label section to the end of
disktab:
doct:ty=removable:dt=DOC2K:se#512:nt#1:rm#300:\
:ns#15920:nc#1:\
:pa#15920:oa#0:ba#4096:fa#512:\
:pc#15920:oc#0:bc#4096:fc#512:
This defines a label for a device type named
doct, with controller type (dt)
of DOC2K. Note that the disk is considered
removable so as not to have MS-DOS partitions
and a MBR. The device consists of
15920 sectors of 512 bytes each.
The pa and pc lines define the
*ix A and C partitions. The C partition, by old *ix
convention, always spans the entire device.
Partition A is the first partition (and the default boot partition).
On the DOC, in this definition, partition A also spans the
device.
To write the label defined by doct to
the DOC, once you have booted a PicoBSD
system containing the fla driver,
issue the following commands:
#dd if=/dev/zero of=/dev/fla0c count=100
#dd if=/dev/zero of=/dev/fla0c count=100
#disklabel -w -r /dev/fla0c doct
The dd commands overwrite the first 100
blocks with zeros. This is effectively a required
idiom that keeps the new label from overwriting
only part of a disk's boot-sector and label information,
which could then confuse some utilities (such as
disklabel).
The ``Input File'' is /dev/zero, a pseudo-device
that generates zero-filled blocks. The output
device is the entire DOC flash device, ``dev/fla0c''.
The dd command is issued twice as sometimes
the first execution will produce warning messages.
The ``disklabel -w -r'' command ``Writes'' a label
to device /dev/fla0c.
The disk is written ``R''aw, that is, bypassing
any information that the running system is maintaining about
the device and forcing the label to use only the
data specified in the disktab file's doct
section.
Note that ``-w -r'' is NOT the same as
``-r -w'' for disklabel!
The label is written to device /dev/fla0c
and is formed using the section in the disktab
file named doct. Note that the device name
is not specified as a ``raw device''.
§ Put a filesystem on the DOC.
Once a label has been written to the DOC, a filesystem can be written using the command:
#newfs /dev/fla0c
At this point the device can be mounted and
used as a regular disk device. For instance,
to mount and unmount the DOC on the standard PicoBSD
/mnt mount-point:
#mount /dev/fla0c /mnt #umount /mnt
§ Booting from the DOC.
It can be useful to boot PicoBSD systems from
the DOC. All this requires is copying a PicoBSD
kernel to the DOC, and then writing the bootstrap
blocks to the DOC. For the purposes of this discussion,
the PicoBSD bootstrap can be considered to consist of
two programs that are put at the start of the disk
following the disk label. The first of these programs
is the single-block boot1 program, and the
second the multi-block boot2 program.
It is the secondary bootstrap that actually locates the
kernel, loads it, and starts it. The secondary bootstrap
is smart enough to locate the file /kernel
by looking for its name in the FreeBSD file-system directory.
Note that there are no hard-coded disk addresses in the
boot blocks that point directly to the kernel to be booted.
The secondary bootstrap can boot any file
on the DOC by name (it helps, of course, if the file
contains a bootable system!).
To boot a PicoBSD system named ``kernel.old'',
at the ``boot:'' count-down prompt, simply type the
name of the file you wish to boot, the press
Enter. When you type, the boot
count-down will pause.
Often the easiest way to get a kernel on the DOC is simply to copy a kernel from the boot floppy, for instance:
#mount /dev/fla0c /mnt #mount /dev/fd0c /mnt1 #cp /mnt1/kernel /mnt #umount /mnt #umount /mnt1 #disklabel -r -B -b /boot/boot1 -s /boot/boot2 /dev/fla0c
The DOC is mounted on /mnt, the floppy on
/mnt2, and the compressed PicoBSD kernel file copied.
Once the kernel has been copied,
the disklabel program is used to write
``R''aw (-r) bootblocks (-B) to the DOC
device (/dev/fla0c).
File /boot/boot1 contains the primary bootstrap
(-b), and /boot/boot2 the secondary
bootstrap (-s).
Be sure that the boot files that you intend to write
from the running PicoBSD system are located in
``/usr/src/release/picobsd/mfs_tree/boot''.
These are not necessarily the same as the boot files
written to the floppy, which are obtained from the host
FreeBSD machine's
/boot directory.
The DOC can now be unmounted and the kernel rebooted, either by cycling
the power or using reboot. Note that if
the DOC is mounted and power is cycled without
doing a umount, the contents of the DOC
will not be accessible until an fsck is
performed on the DOC.
§ Script to move PicoBSD from floppy to DOC.
For example,
to create a script named kcp
that automates the process for initializing a DOC and
copying a bootable kernel to it,
create a file in one of the locations from which
the picobsd script builds the memory-based file-system internal
to the kernel image. For instance, using mysys in
the source tree as
your PicoBSD configuration directory, one of the
following would be valid:
/usr/src/release/picobsd/mfs_tree/etc/kcp
/usr/src/release/picobsd/mysys/floppy.tree/etc/kcp
In the kcp file, an example file could be:
echo
echo "Script to wipe out DiskOnChip and copy kernel"
echo "from floppy to DiskOnChip".
echo
set -e
dd if=/dev/zero of=/dev/fla0c count=100
dd if=/dev/zero of=/dev/fla0c count=100
disklabel -w -r /dev/fla0c doct
newfs /dev/fla0c
mount /dev/fla0c /mnt
mount /dev/fd0c /mnt1
cp /mnt1/kernel /mnt
umount /mnt
umount /mnt1
disklabel -r -B -b /boot/boot1 -s /boot/boot2 /dev/fla0c
echo
echo "Now remove the floppy and reboot".
echo
Since this requires the definition of the
doct label in file /etc/disktab,
be sure this exists.
§ Kernel development with the DOC.
You can use the DOC, of course, without putting
a kernel on it. However, it is very convenient
to use the DOC as your boot device, thus providing
a ``diskless'' system without moving parts.
The bootstrap can boot either compressed (gzipped) or uncompressed
kernel files.
If you copy the /kernel file from
the boot floppy to the DOC, the kernel file
will be compressed.
I've found it useful on the 8M
DOC to keep a backup (perhaps compressed) ``kernel.old''
and my
development PicoBSD kernel.
The development kernel is copied over the net from a
large host system on which it is compiled.
The picobsd build script need not
write a boot floppy on the host development
machine.
If you skip both writing the boot floppy and booting from
the floppy, the PicoBSD development cycle can
be reasonably
fast. To skip writing the floppy, when the
last menu is displayed by the picobsd script,
hit tab twice to position the cursor on [Cancel],
and press Enter. Then, using the existing
PicoBSD kernel on the DOC,
copy the new kernel file over the
net to the DOC, and then issue reboot on the
DOC. A set of commands to do this from PicoBSD,
assuming a mysys PicoBSD development configuration,
would be similar to:
#mount /dev/fla0c /mnt #cd /mnt #rm kernel #ftpftp> binary ftp> get /usr/src/release/picobsd/build/build_dir-mysys/kernel ftp> quit #cd / #umount /mnt #reboot
This requires that ftp be included
in the PicoBSD kernels (included in the ``crunch.conf'').
Putting a bootable PicoBSD kernel on a hard-disk is easy;
there are no special procedures that would not apply to
the normal FreeBSD. See:
http://people.freebsd.org/~imp/diskprep
Sometimes, after a kernel has crashed, it is useful to be able to do complex I/O from the ``carcass'' of the dead kernel (for instance, from a fatal trap handler). By this time, the operating system can no longer be used to do interrupt driven I/O. There are other times when it may be desirable for a driver to do complex I/O without effecting interrupts.
In both these cases, the solution is to use polled serial I/O over one of the serial ports (UARTs). This requires connecting the serial port to a terminal, datascope, or another computer (a ``datascope'' is a network line-analyzer).
The code for polled serial I/O is small and can easily be included in driver and kernel routines. This small chunk of code will operate even after the operating system has crashed and when interrupts are (perhaps accidentally) disabled.
The code for polled serial UART I/O on a PC is:
#if 0
#define DATA_REG 0x3f8
#define LSB 0x3f8
#define MSB 0x3f9
#define INT_ENAB 0x3fa
#define LINE_CONTROL 0x3fb
#define MODEM_CNTRL 0x3fc
#define LINE_STATUS 0x3fd
#define MODEM_CSR 0x3fe
#endif
/*---------------------------------------------------------------------------*/
/* Debug serial driver routines */
/*---------------------------------------------------------------------------*/
void fsdz_init() {
outb( /*LINE_CONTROL*/ 0x3fb, 0x80 ); /* Set baud */
outb( /*MSB*/ 0x3f9, 0 ); /* MSB of baud divisor */
outb( /*LSB*/ 0x3f8, 12 ); /* LSB of baud divisor */
outb( /*LINE_CONTROL*/ 0x3fb, 0 ); /* Zero */
outb( /*LINE_CONTROL*/ 0x3fb, 0x0b ); /* 8-bit, odd parity enabled */
outb( /*INT_ENAB*/ 0x3fa, 0 ); /* Disable interupts. */
}
/*---------------------------------------------------------------------------*/
void fsdz_put( ochar )
char ochar;
{
char status,c;
status = inb( /*LINE_STATUS*/ 0x3fd ); /* Check if rcv buffer is full */
if (status & 1) {
c = inb( /*DATA_REG*/ 0x3f8 ); /* Get the char */
c &= 0x7f; /* Ignore parity */
if (c == 19) {
do {
do {
status = inb( /*LINE_STATUS*/ 0x3fd );
} while ( 1 != (status & 1) );
c = inb( /*DATA_REG*/ 0x3f8 );
c &= 0x7f;
} while (c != 17);
}
}
#if 0 /* Set modem control. */
outb( /*MODEM_CNTRL*/ 0x3fc, 0x03 ); /* DTR and RTS */
do {
status = inportb( /*MODEM_CSR*/ 0x3fe); /* Wait for DSR and CTS */
while (status != 0x30);
#endif
for(;;) {
status = inb( /*LINE_STATUS*/ 0x3fd); /* Wait for TRANS READY */
if (status & 0x20) break;
}
outb( /*DATA_REG*/ 0x3f8, ochar ); /* Output the data byte,.. */
}
This is very old code. Minor variations of this code have been used on PCs for nearly two decades.
Note the preceeding code
does not
use the ``#define'' statements;
they are primarily left in as documentation.
You often do not need to use modem control
on the serial line. However, if you need to
do explicit modem-style flow-control on the serial
line, alter the section of code that has been
``#defined'' out.
The polling serial I/O code is used in the following manner:
fsdz_init();
fsdz_put( 'U' );
fsdz_put( 'p' );
The previous code would initialize the 16550 UART and write the characters "Up" over the serial port. A typical debug idiom using this code would be:
char brm_dbuf[80];
int len,i;
fsdz_init();
fsdz_put( 'C' ); fsdz_put( 'R' ); fsdz_put( 'A' ); fsdz_put( '!' );
len = sprintf( brm_dbuf, "f=%x t=%x cnt=%d.", from, to, count );
for(i=0; i<len; i++) fsdz_put( brm_dbuf[i] );
The baud rate used can be
altered by changing the divisor written to registers
MSB and LSB in ``fzdz_init()''. The formula for
these values is ``divisor = 1.8432Mhz /( 16 * baud rate)''.
Some common values are:
| Baud Rate | MSB | LSB |
| 1200 | 00 | 0x60 |
| 9600 | 00 | 0x0c |
| 19200 | 00 | 0x06 |
| 56000 | 00 | 0x02 |
A ``classic'' book describing PC serial communications is C Programmer's Guide to Serial Communications [1] [2] , [3] , by Joe Campbell, 1987, Howard Sams and Company.
Many people have contributed to this FAQ. Draft 20-Jul-2001 of this document written by:
Bruce R. Montague (www.cse.ucsc.edu/~brucem)