A PicoBSD User and Starter FAQ

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.



Please bring errors and omissions to my attention, thanks (see page bottom). You are welcome to copy this document.


§ 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 PicoBSD root password?

 

The picobsd build script:
  What is the most current description of the picobsd script command?
  What is the syntax of the picobsd script command?
  What can I do with the script's main interactive dialog menu?
  What vn device 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 PicoBSD rc boot script work?
  How do I edit PicoBSD /etc scripts?
  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 the kernel file?
  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 does picobsd run under?
How do I get PicoBSD (FreeBSD)?

 

§ Internals and customization

How does the ``picobsd'' script work (how does all this happen)?
What is tinyware?
What is oinit?
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

What man pages should I read?
Where is the PicoBSD documentation?
How do I subscribe to the freebsd-small@freebsd.org mailing list?
How do I browse the freebsd-small@freebsd.org mailing 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 (use in and out instructions)?
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?

 


What is PicoBSD?

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 useful when you need a single bootable file that is a complete ``self-extracting'', preconfigured, diskless FreeBSD system. Example PicoBSD uses include single-floppy install systems, floppy-based ``rescue'' systems, netbootable systems, embedded systems that boot from ROM or flashdisk, diskless routers/firewalls, diskless cluster nodes, and the like. PicoBSD is a great way to make cheap lab systems out of old PC hardware.

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.

 


Quick! How do I build one of the standard PicoBSD systems?

 

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 vn

You may have to recompile the FreeBSD kernel and possibly rebuild the ``/dev/vn*'' device nodes (Use MAKEDEV. This is normally not required.)

 *   Verify that you have a free vn device using:

#mount

If you see a mounted filesystem of the form ``/dev/vn0c on /tmp/picobsd.c2OlSJv7sk'', it is likely that a previous build of picobsd has failed. See the section on freeing a vn device 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
#rehash

Obviously, 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 picobsd script. 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.

 


Quick! How do I build my own version of PicoBSD?

 

 §   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 vn

You may have to recompile the FreeBSD kernel and possibly rebuild the ``/dev/vn*'' device nodes (Use MAKEDEV. This is normally not required.)

 *   Verify that you have a free vn device using:

#mount

If you see a mounted filesystem of the form ``/dev/vn0c on /tmp/picobsd.c2OlSJv7sk'', it is likely that a previous build of picobsd has failed. See the section on freeing a vn device 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.

 


What are some common errors and how do I deal with them?

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:

disklabel: /dev/vn1: No such file or directory
---> fail: Error <4> error code

If the host FreeBSD system contains the vn pseudo-device, this typically means that the prior execution of picobsd failed, leaving the vn0 device in a mounted state.

vn device house-cleaning:

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:

pid 8 (cp), uid 0 on /: out of inodes

There are not enough inodes in the RAM-based MFS. Files are likely being copied from various /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.

 

 


How do I clean-up after a PicoBSD build?

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 the PICOBSD-net kernel build directory.

 *   #cd /usr/src/sys/i386/conf
and delete the PICOBSD-net kernel configuration file.

 *   #cd /usr
and delete the obj-pico directory.

 *   Go to the directory containing your build_dir directory,
(for instance, ``cd /usr/src/release/picobsd/build'')
and delete the build_dir-net directory.

 *   #cd /tmp
and delete any picobsd.XXXXXXXXXX (temporary name) directories. Also delete any reply.XXXXXXXXXX temporary file(s).

 

Note that only one obj-pico directory is created, that is, versions are not created based on the name of your configuration.

 

 


What is the default PicoBSD 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.

 

 


What is the most current description of the 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''.

 


What is the syntax of the 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 the build_dir directory before starting. This directory will have a name of the form build_dir-mysys, where mysys is the name of your PicoBSD configuration directory, as specified by argument floppy_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 the picobsd script. 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 /fd directory in the MFS filesystem (the RAM-filesystem) built into the kernel. The files will be uncompressed and copied to your RAM-based /etc directory at boot, that is, they will be copied over the files originating in the /usr/src/release/picobsd/mfs_tree/etc directory. If INCLUDE_FLOPPY_IN_MFS is 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 specify INCLUDE_FLOPPY_IN_MFS="yes", you can later create a /etc on your floppy and put updated startup script files on the floppy. These files will be copied into /etc before 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 the picobsd source tree. This includes the reference directory configurations, and the build directory that contains the picobsd script. 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_SIZE environment variable defaults to 1440 Kbytes, the size of the most common 3.5 inch floppy. The current picobsd script writes to a ``floppy device'' using a device node of ``dev/rfd0.${FLOPPY_SIZE}''.

 

Results:

The principal outputs of the picobsd script are (1) a bootable floppy, (2) an image of the floppy saved in file ``picobsd.bin'', and (3) a bootable kernel file. The two files are in the build_dir-$floppy_type directory (which itself will be located in the directory in which you executed the picobsd command).

Unless you change the INCLUDE_FLOPPY_IN_MFS default, the floppy and floppy image will only contain the bootable kernel file.

If you [Cancel] out of the last menu dialog in the picobsd script, 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..

 


What can I do with the script's main interactive dialog menu?

 

 §   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.

 


What is in a PicoBSD configuration directory?

As the picobsd script header documentation indicates, each PicoBSD configuration directory contains a number of standard files:

 

 §   PICOBSD

The PICOBSD file is a normal FreeBSD kernel configuration file with the addition of a comment line that starts with ``#PicoBSD''. This comment line supplies arguments to the picobsd script.

Edit the PICOBSD file to include your desired FreeBSD kernel options. In particular, you often will want to specify drivers (devices).

Edit the #PIOCBSD comment/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 #PIOCBSD comment/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 the dd command that creates the file backing the MFS image, using bs=1k).

 *   The second argument specifies the program to be run as the init process, 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. The oinit program in the above example is a tiny ``template starter'' alternate to the traditional FreeBSD init program. See the section on oinit.

 *   The third argument is the ``-i avg_bytes_per_file'' value passed to the newfs invocation 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 the newfs invocation 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_SIZE environment variable defaults to 1440 Kbytes, the size of the most common 3.5 inch floppy.

 

 §   config

The config file lists all the device nodes that are to be created in ``/dev''. Edit this file and add any device node names you need to the MY_DEVS string. There is only a single line in the typical config file. An example of this line (from the bridge configuration) 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 config file.

 

 §   crunch.conf

The ``crunch.conf'' file controls the application crunchgen, that is, it indicates which executables to link into the single executable ELF file.

Edit ``crunch.conf'' and add srcdirs, progs, and libs statements as needed. The progs statements specify the pathnames of the executables that you require. The srcdirs specify the pathnames of the directories containing the Makefiles that correspond to the executables. Note that crunchgen requires a special ``makefile format'' (a FreeBSD standard), but you can easily create a pseudo-makefile with this format if required.

The crunchgen program, in effect, renames all program main() routines and creates a single main() with a little stub code that dispatches to the real entry-point based on the arg0 command-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 the ln command.

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 /etc directory which includes the /etc/rc script 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 kernel file, but to include them directly in a /fd directory 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 /etc files 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 the mtree utility, 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 mtree specification files.

 


What are the predefined ``reference'' configurations? Which one should I use?

 

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.

 


How does the PicoBSD 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 /fd directory and recursively copies the /fd/etc/ tree to /etc. This merges etc files defined in mfs_tree/etc with any gzipped files from ``floppy.tree/etc'' included in the kernel due to INCLUDE_FLOPPY_IN_MFS="yes".

 *   The rc script then returns to ``/'', and mounts the floppy disk (/dev/fd0c) on /fd.

 *   It then repeats the process of copying all files from /fd/etc into /etc and then dismounts the floppy. This will copy any files into /etc that were put on the floppy using ``floppy.tree'' and INCLUDE_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 rc script then enters /etc and 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 where foo.gz exists, foo is 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 /etc are unzipped.

 *   The pwd_mkdb utility processes the ``master.passwd'' file to create a valid binary password ``database''.

 *   Finally, the initial /etc/rc script executes the script /etc/rc, that is, itself. However, the previous steps assure that the /etc/rc file will have been overwritten. The source to the new /etc/rc can come from a number of original locations. It may have come from the default ``base'' rc script 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.

 


How do I edit PicoBSD /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.

 


How do I edit or add new files to an existing floppy image file?

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.

 


What are some command-line differences between FreeBSD and PicoBSD?

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.

 


How do I include my own binary application in PicoBSD, that is, include them with the ``crunched'' applications in the 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.

 


How do I write a binary application that I can download individually and run on PicoBSD without requiring it to be ``crunched'' into the 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

 


How big is PicoBSD?

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.

 


Does PicoBSD support hard disks?

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.

 


 

How do I see how much space is used in the filesystems?

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 picobsd with 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.QYgf0heGbl

After the ``---> Copy generic MFS tree...'' and `` ---> Copy generic floppy_tree into MFS...'' steps, you will see the df display 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.

 


What ``host'' environment do I need to do embedded PicoBSD development?

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.

 


What versions of FreeBSD does 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.

 


How do I get PicoBSD (FreeBSD)?

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.

See ``www.freebsd.org''.

 


 

What is the 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 ``/'' directory. Startup scripts are included in the memory-based filesystem included internal to 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 config file (init_stage1()).

 

 §   Build the initial kernel file and copy it to a work directory (do_kernel()). The actual kernel compile is driven by make using
`` /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()).

#dd an image of the size specified in the PICOBSD file.
#dd boot1 to make it bootable.
#vnconfig the image (make it accessible as a device).
#disklabel to create a *ix disk partition table (disk label).
#newfs to create the filesystem.
#mount to make it accessible for normal utilities.

 

 §   Populate the MFS file system (populate_mfs()).

#cd into the configuration directory.
#mtree to create the MFS directory structure.
#ln
#MAKEDEV to create device nodes.
#crunchgen crunch.mk to preprocess the applications to crunch.
#make crunch.mk to crunch the onjects into crunch1.
#mv to put crunch1 in /stand/crunch in the MFS filesystem.
#tar to copy mfs_tree files from configuration directories to the MFS filesystem.
#cp -R floppy.tree into /fd in the MFS if INCLUDE_FLOPPY_IN_MFS="yes".
#umount virtual 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 /stand directory contains links which refer to all binaries, and directories such as /bin and /sbin are simply links to /stand.

 

 §   Create ``picobsd.bin'', the floppy disk image (fill_floppy_image() (Part I)).

#dd a file to floppy size.
#dd boot1 to make the file bootable.
#vnconfig to make the file accessible as a device.
#disklabel to write boot records (and create a single partition disk).
#newfs to create a filesystem in the file.
#mount to 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_kernel to actually put the MFS in the kernel.
#kgzip the kernel.
#cp the kernel to /kernel in the floppy tree.

The file ``/usr/src/release/write_mfs_in_kernel.c'' is a little program compiled every execution of the picobsd script. It ``zaps'' the MFS filesystem image into the kernel image at a location it finds by scanning the kernel file 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 the MD_ROOT_SIZE specified via the second argument in your PICOBSD configuration file. This may result in a kernel too large to fit on the floppy.

 §   Put the ``floppy.tree'' in the floppy image, if needed (fill_floppy_image() (Part III)).

#cp the ``floppy.tree'' into the floppy image if it was not already copied into the MFS (that is, if it is not already inside the compressed kernel file).

 

 

 §   This completes the build_image() routine.

 

 §   Write the floppy image to the floppy disk (do_install()).

#dialog to display the confirmation dialog.
#dd picobsd.bin -> /dev/rfd0 to write the floppy.

 


What is tinyware?

The tinyware homepage, which is quite dated, is at:

http://people.freebsd.org/~picobsd/tinyware

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.

 


What is 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.

 


Where do the PicoBSD boot files on the floppy come from?

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''.

 


What makefile invokes the actual kernel compile?

The Makefile.conf file in ``/usr/src/release/picobsd/build''.

 


 

How can I build a number of related PicoBSD systems?

 §  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.

 


How do I make a floppy from an existing PicoBSD floppy image file?

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

 


How do I compare FreeBSD and PicoBSD kernel images?

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.

For example, a PicoBSD kernel shows:
...

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.

 


How do I find a string in an ELF kernel section?

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

 


What's an older way to build PicoBSD?

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.

 


Can I download a bootable PicoBSD image?

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.

 


Are there other ways to make small FreeBSD systems?

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 .

 


Who maintains PicoBSD?

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.


Who developed 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...


What type of license is PicoBSD under?

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.

 


What should I know about industrial and embedded PCs?

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.

 

 


What are some university and academic groups using PicoBSD?

 

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

 


What are some disadvantages of PicoBSD?

 

 §   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.

 


What are some advantages of PicoBSD?

 

 §   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.

 


What FreeBSD 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.

 


Where is the PicoBSD documentation?

 

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 the man page 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.

 


How do I subscribe to the 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.

 


How do I browse the 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

 


What other PicoBSD-related web resources are available?

 

 §  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 of ssh intended 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.

 

 

 


What are some academic references and web sites that describe research using PicoBSD?

 

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.

 


How do I make PicoBSD on a PC run ``headless'' (without monitor and keyboard)?

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 of ttyinput() 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.

 


How do I use PicoBSD to make a cheap diskless web server?

 

 §   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...

 


How do I use PicoBSD to make a cheap Internet-enabled instrument?

 

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...

 


How do I directly access I/O devices from an application program (use 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:

PinCOM1 I/O Register AddressRegister Bit
DTR34c0x01
RTS34c0x02
BREAK34b0x40

 

See also: www.daemonnews.org/200107/dasblinkenlights.html.

 


How do I put PicoBSD on a flash disk?

 

 §   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
 #ftp 
  ftp> 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'').

 


How do I put PicoBSD on a hard disk?

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

 


How can I kernel debug using polled serial I/O?

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 Divisors (MSB and LSB in Hex)
Baud RateMSBLSB
1200000x60
9600000x0c
19200000x06
56000000x02

 

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.


 

My Contact Info

Many people have contributed to this FAQ. Draft 20-Jul-2001 of this document written by:

Bruce R. Montague (www.cse.ucsc.edu/~brucem)
brucem@mail.cruzio.com
brucem@mail.got.net
brucem@cse.ucsc.edu