[FAQ Index] [To Section 4 - Installation Guide] [To Section 6 - Networking]

5 - Building the System from Source

Table of Contents

5.1 - OpenBSD's Flavors

There are three "flavors" of OpenBSD: Graphically, the development of these flavors looks something like this:
,------o-----------o----X 3.9 Stable | . . | . ,------o---------o----X 4.0 Stable | . | . . | . | . ,----o----------o--> 4.1 Stable | . | . | . . | . | . | . ,-----o--> 4.2 Stable | . | . | . | . | . | . | . | . -->3.9Rel----->4.0Rel----->4.1Rel----->4.2Rel----> Current Time --->

-Current is where active development work is done, and eventually, it will turn into the next -release of OpenBSD. Every six months, when a new version of OpenBSD is released, -current is tagged, and becomes -release: a frozen point in the history of the source tree. Each -release is never changed; it is what is on the CDs and FTP servers.

-Stable is based on -release, and is a branch from the main development path of OpenBSD. When very important fixes are made to -current, they are "back ported" (merged) into the -stable branches; because of this, -stable is also known as the "patch branch." In the above illustration, the vertical dotted lines denote bug fixes being incorporated into the -stable branches. You will also note that in the above example, the 3.9-stable branch came to an end with 4.1-release, and the 4.0-stable branch came to an end with 4.2-release -- old releases are typically supported up to two releases back. It takes resources and time to support older versions, while we might like to provide ongoing support for old releases, we would rather focus on new features. The -stable branch is, by design, very easy to build from -release of the same version (i.e., going from 4.2-release to 4.2-stable).

The -stable branch is -release plus patches found on the errata page. The operation of -stable is the same as the -release it is based on. If the man pages have to change, it probably won't go into -stable. In other words, new device support and new features will NOT be added to -stable.

It is worth pointing out that the name "-stable" is not intended to imply that -current is unreliable. Rather, -current is changing and evolving, whereas the operation and APIs of -stable are not going to change, so you shouldn't have to relearn your system or change any configuration files, or have any problem adding additional applications to your system.

In fact, as our hope is to continually improve OpenBSD, the goal is that -current should be more reliable, more secure, and of course, have greater features than -stable. Put bluntly, the "best" version of OpenBSD is -current.

Warning: -current is a moving target. It changes minute by minute, and may well change several times in the time it takes to retrieve the source code. While the developers work hard to ensure that the system always compiles and that there are no major bugs, it is entirely possible to get the -current source and have it fail to compile, whereas five minutes later everything will be just fine. There are also flag days and major system changes that the developers navigate with one-time tools, which mean that source-based updating is not possible. If you are not prepared to deal with this, stay away from -current.

Most users should be running either -stable or -release. That being said, many people do run -current on production systems, and it is important that some people do so to identify bugs and test new features. However, if you don't know how to properly describe, diagnose and deal with a problem, don't tell yourself (or anyone else) that you are "helping the project" by running -current. "It didn't work!" is not a useful bug report. "The recent changes to the pciide driver broke compatibility with my Slugchip-based IDE interface, dmesg of working and broken systems follow..." might be a useful report.

There are times when "normal" users may wish to live on the cutting edge and run -current. The most common reason is that the user has a device which is not supported by -release (and thus, not -stable), or wishes to use a new feature of the -current. In this case, the choice may be either -current or not using the device, and -current may be the lesser evil. However, one should not expect hand-holding from the developers.


Between formal releases of OpenBSD, snapshots are made available through the FTP sites. As the name implies, these are builds of whatever code is in the tree at the instant the builder grabbed a copy of the code for that particular platform. Remember, on some platforms, it may be DAYS before the snapshot build is completed and put out for distribution. There is no promise that the snapshots are completely functional, or even install. Often, a change that needs to be tested may trigger snapshot creation. Some platforms have snapshots built on an almost daily basis, others will be much less frequent. If you desire to run -current, a recent snapshot is often all you need, and upgrading to a snapshot is a required starting point before attempting to build -current from source.

It is sometimes asked if there is any way to get a copy of exactly the code used to build a snapshot. The answer is no. First, there is no significant benefit to this. Second, the snapshots are built as desired, as time permits, and as resources become available. On fast platforms, several snapshots may be released in one day. On slower platforms, it may take a week or more to build a snapshot. Providing tags or markers in the source tree for each snapshot would be quite impractical. Third, snapshots often contain experimental code that isn't yet committed to the tree.

Upgrade vs. Update

You will often see references to "upgrading" and "updating" OpenBSD installs. Even though these words have similar meanings, they are used slightly differently in OpenBSD.

Upgrading is the process of installing a newer version of OpenBSD, with new functionality. For example, going from v4.1 to v4.2, or going from the June 12th snapshot to the June 20th snapshot. When upgrading, you will typically have to consult either Following -current or the Upgrade guide (when changing releases) to make the changes required to run the upgraded version of OpenBSD.
Updating is the process of applying patches to a system to improve the operation WITHOUT changing the basic functionality or binary compatibility. This is typically done by following the source patching process or by following the stable process. When you "update" your system, it goes from a -release to a -stable (or patched -release) of the same release version, for example, 4.2-release to 4.2-stable. You may then later update it to a newer -stable of the same release version. The update process is typically very painless, as no /etc files or other system configurations need to be changed.

So, you may install a system (for example, 4.1-release) from CD, then update it to 4.1-stable a few times, then upgrade it to 4.2-release from CD, and update that a few times before upgrading it again to the next release.

Keeping Things in Sync

It is important to understand that OpenBSD is an Operating System, intended to be taken as a whole, not a kernel with a bunch of utilities stuck on. You must make sure your kernel, "userland" (the supporting utilities and files) and ports tree are all in sync, or unpleasant things will happen. Said another way (because people just keep making the error), you can not run brand new ports on a month old system, or rebuild a kernel from -current source and expect it to work with a -release userland. Yes, this does mean you need to upgrade your system if you want to run a new program which was added to the ports tree today. Sorry, but again, OpenBSD has limited resources available.

One should also understand that the upgrade process is supported in only one direction: from older to newer, and from -stable to -current. You can not run 4.2-current (or a snapshot), then decide you are living too dangerously, and step back to 4.2-stable. You are on your own if you choose any path other than the supported option of reloading your system from scratch, do not expect assistance from the OpenBSD development team.

Yes, this does mean you should think long and hard before committing yourself to using -current.

5.2 - Why do I need to compile the system from source?

Actually, you very possibly do not.

Some reasons why NOT to build from source:

Some reasons why you might actually wish or need to build from source:

The OpenBSD team puts out new snapshots based on -current code on a very regular basis for all platforms. It is likely this will be all you need for running -current.

The most common reason to build from source is to follow the -stable branch, where building from source is the only supported option.

5.3 - Building OpenBSD from source

5.3.1 - Overview of the building process

Building OpenBSD from source involves a number of steps: There are a couple additional steps that some users may wish to perform, depending on the purpose of the build and if X is installed:

5.3.2 - Install or Upgrade to closest available binary

The first step in building from source is to make sure you have the closest available binary installed. Use this table to look at where you are, where you wish to go, and what binary you should start with:

You are at Goal Binary upgrade to then ...
Old -release New release Newest release Done!
-release -stable Newest release Fetch & build -stable
Old -stable -stable Newest release Fetch & build -stable
-release -current Latest Snapshot (optional) Fetch & build -current
Old -current -current Latest Snapshot (optional) Fetch & build -current

It is recommended that you install the binary by using the "Upgrade" option of the install media. If that is not possible, you can also unpack the binaries as described here. Regardless, you must do the entire upgrade process, including creating any users or other /etc directory changes needed.

5.3.3 - Fetching the appropriate source code

OpenBSD source is managed using the CVS version control system, and cvs(1) is used to pull a copy of the desired source to your local machine for compilation. This can be done by using an AnonCVS server (a machine holding a publicly accessible copy of the entire CVS repository used by the OpenBSD project) or from a local CVS repository you maintain using the CVSup, or CVSync programs available as packages. CVSup can also be used in a "checkout" mode, but that will not be covered here. If you have multiple machines you wish to maintain source code trees on, you may find it worth having a local CVS repository, created and maintained using CVSup or CVSync.

After deciding which AnonCVS server you wish to use, you must "checkout" the source tree, after that, you then maintain the tree by running "updates", to pull updated files to your local tree.

The CVS(1) command has many options, some of them are required to checkout and update a useful tree. Other commands can cause a broken tree. Following and understanding directions here is important.

Following -current

In this case, we will assume we are using a public AnonCVS server, anoncvs@anoncvs.example.org:/cvs. We will also assume you are using sh(1) as your command shell, if you are using a different shell, you will have to adjust some of these commands.

To checkout a -current CVS src tree, you can use the following: # cd /usr # export CVSROOT=anoncvs@anoncvs.example.org:/cvs # cvs -d$CVSROOT checkout -P src

Once you have a tree, you can update it at a later time: # cd /usr/src # export CVSROOT=anoncvs@anoncvs.example.org:/cvs # cvs -d$CVSROOT up -Pd

Following -Stable
If you wish to check out an alternative "branch" of the tree, such as the -stable branch, you will use the "-r" modifier to your checkout: # cd /usr # export CVSROOT=anoncvs@anoncvs.example.org:/cvs # cvs -d$CVSROOT checkout -rOPENBSD_4_2 -P src This will pull the src files from the OPENBSD_4_2 branch, which is also known as the "Patch branch" or "-stable". You would update the code similarly: # cd /usr/src # export CVSROOT=anoncvs@anoncvs.example.org:/cvs # cvs -d$CVSROOT up -rOPENBSD_4_2 -Pd Actually, CVS is nice enough to stick a "Tag" in the checked out file system, so you don't have to remember the "-rOPENBSD_4_2" part of the command line, it will remember this until you explicitly clear them or set a new tag by using the "-A" option to "update". However, it is probably better to provide too much info in your CVS command lines than too little.

While only the "src" tree has been shown so far, you will do the same steps for "xenocara" and "ports". As all parts of OpenBSD must be kept in sync, all trees you use should be checked out and updated at the same time. You can combine the checkouts into one line (-stable shown): # export CVSROOT=anoncvs@anoncvs.example.org:/cvs # cd /usr # cvs -d$CVSROOT checkout -rOPENBSD_4_2 -P src ports # cd /usr/src # cvs -d$CVSROOT checkout -rOPENBSD_4_2 -P xenocara However, updates must be done directory-by-directory.

At this point, whether you followed -stable or -current you should have a usable source tree. Be very careful which tree you grab -- it is easy to try to compile -current when aiming for -stable.

Pre-loading the tree: src.tar.gz, sys.tar.gz

While you can download the entire source tree from an AnonCVS server, you can often save a lot of time and bandwidth by "pre-loading" your source tree with the source files from either the OpenBSD CD or from an FTP server. This is particularly true if you are running -stable, as relatively few files change between this version and the -release it is based on.

To extract the source tree from the CD to /usr/src (assuming the CD is mounted on /mnt): # cd /usr/src; tar xzf /mnt/src.tar.gz # tar xzf /mnt/xenocara.tar.gz # cd /usr; tar xzf /mnt/ports.tar.gz The source files available for download from the FTP servers are separated into two files to minimize the download time for those wishing to work with only one part of the tree. The two files are sys.tar.gz, which contains the files used to create the kernel, and src.tar.gz which contains all the other "userland" utilities except the ports tree and the X11 sources. In general, however, you will usually want both of them installed. Assuming the downloaded files, src.tar.gz and sys.tar.gz, are in /usr: # cd /usr/src # tar xzf ../sys.tar.gz # tar xzf ../src.tar.gz # tar xzf ../xenocara.tar.gz # cd /usr # tar xzf ports.tar.gz

Not all people will wish to unpack all the file sets, but as the system must be kept in sync, you will generally need to set up all parts of the tree.

Common CVS tips

As indicated earlier, some options are mandatory to get a valid src tree in OpenBSD. The "-P" option above is one of those: It "prunes" (removes) directories that are empty. Over the years, directories have been created and deleted in the OpenBSD source tree, and sometimes the names of old directories are currently used as file names. Without the "-P" option, your newly checked-out tree WILL NOT successfully compile.

Much the same with the -d option on the 'update' command -- it creates new directories that may have been added to the tree since your initial checkout. To get a successful update, you must use the -Pd options.

Experienced CVS users may wonder why the CVSROOT was specified and used in this example, as cvs(1) will record the CVS server's location in the checked out tree. This is correct, however there are enough times where one may need to override the default anoncvs server, many people recommend always specifying the repository explicitly. It is also worth noting that while the CVSROOT environment variable can be used directly by cvs(1), it is used only if nothing else overrides it (i.e., cvs(1) would have an error without it), whereas specifying it in the cvs(1) command line overrides all other values.

It is often useful to use a .cvsrc in your home directory to specify defaults for some of these options. An example .cvsrc file: $ more ~/.cvsrc cvs -q -danoncvs@anoncvs.example.org:/cvs diff -up update -Pd checkout -P This file would cause cvs(1) to use the anoncvs@anoncvs.example.org:/cvs server, suppress usually unneeded output ("-q" is "quiet") for all operations, a "cvs up" command defaults to using the -Pd, a "cvs diff" defaults to providing "unified diffs" due to the "-u", and a "cvs checkout" will use the "-P" option. While this is convenient, if you forget this file exists, or try to run commands you got used to on a machine without this file, you will have problems.

As the source trees consist of large numbers of mostly small files, turning on soft updates for the partition the source tree is on will often give significantly better performance.

5.3.4 - Building the kernel

We will assume you wish to build a standard (GENERIC or GENERIC.MP) kernel here. Normally, this is what you want to do. Do not consider building a custom kernel if you have not mastered the standard building process.

Obviously, the kernel is a VERY hardware dependent portion of the system. The source for the kernel is in the /usr/src/sys directory. Some parts of the OpenBSD kernel code are used on all platforms, others are very specific to one processor or one architecture. If you look in the /usr/src/sys/arch/ directory, you may see some things that look a little confusing -- for example, there are mac68k, m68k and mvme68k directories. In this case, the mvme68k and mac68k systems both use the same processor, but the machines they are based on are very different, and thus require a very different kernel (there is much more to a computer's design than its processor!). However, parts of the kernel are common, those parts are kept in the m68k directory. If you are simply building a kernel, the base architecture directories like m68k are not anything for you to worry about, you will be working exclusively with the "compound architecture" directories, such as mvme68k.

Kernels are built based on kernel configuration files, which are located in the /usr/src/sys/arch/<your platform>/conf directory. Building the kernel consists of using the config(8) program to create and populate a kernel compile directory, which will end up in /usr/src/sys/arch/<your platform>/compile/<KernelName>. For this example, we will assume you are using the i386 platform:

# cd /usr/src/sys/arch/i386/conf # config GENERIC # cd ../compile/GENERIC # make clean && make depend && make [...lots of output...] # make install
Replace "i386" in the first line with your platform name. The machine(1) command can tell you what your platform name is, so an obvious generalization would be to use the command "cd /usr/src/sys/arch/`machine`/conf" instead on the first line.

At this point, reboot your machine to activate this new kernel. Note that the new kernel should be running before the next step, though if you have followed the above advice about upgrading to the most recent available snapshot, it may not matter as much. Sometimes, however, APIs change, and the old kernel will be unable to run new applications, but the new kernel will generally support the old ones.

Variation on above process: Read-only source tree

Sometimes, you may wish to ensure your /usr/src/sys directory remains untouched. This can be done by using the following process:
$ cd /somewhere $ cp /usr/src/sys/arch/i386/conf/GENERIC . $ config -s /usr/src/sys -b . GENERIC $ make clean && make depend && make ... lots of output ...
Note that you can build a kernel without root access, but you must have root to install the kernel.

5.3.5 - Building the userland

There is a specific process used by OpenBSD. Processes used on other OSs you may have been familiar with will most likely not work on OpenBSD, and will get you laughed at when you ask why.

5.4 - Building a Release

What is a "release", and why would I want to make one?

A release is the complete set of files that can be used to install OpenBSD on another computer. If you have only one computer running OpenBSD, you really don't have any reason to make a release, as the above build process will do everything you need. An example use of the release process would be to build -stable on a fast machine, then make a release to be installed on all your other machines in your office.

The release process uses the binaries created in the /usr/obj directory in the building process above, so you must successfully complete the build first, and nothing must disturb the /usr/obj directory. A time where this might be a problem is if you use a memory disk as your /usr/obj for a little extra performance in the build process, you would not want to reboot the computer between the "build" and "release" steps!

The release process requires two work directories, which we will call DESTDIR and RELEASEDIR. All the files that are part of a "clean" OpenBSD install will be copied to their proper place within the DESTDIR. They will then be tar(1)ed up and placed in the RELEASEDIR. At the end of the process, RELEASEDIR will hold the completed OpenBSD release. The release process will also use the /mnt location, so this should not be used by anything while the release process is running. For the purpose of example, we will use the DESTDIR of /usr/dest and the RELEASEDIR of /usr/rel.

The release process involves a couple utilities which are not in the base OpenBSD system, crunch and crunchgen(1), which are used to create a single executable file made up of many individual binaries. The name this single executable file is invoked by determines which component binary is run. This is how a number of individual program files are squeezed into the ramdisk kernel that exists on boot floppies and other boot media. These utilities must be built before the release process is started. They only need to be built and installed once, but as people often forget this step, and these programs build quickly, some people opt to just build crunch and crunchgen every time as part of the script they use to make a release.

You must have root privileges to make a release.

Doing a release

First, if it has not been done on this machine, build crunch and crunchgen:
# cd /usr/src/distrib/crunch && make obj depend all install
Now, we define our DESTDIR and RELEASEDIR environment variables:
# export DESTDIR=/usr/dest # export RELEASEDIR=/usr/rel
We now clear the DESTDIR and create the directories if needed:
# test -d ${DESTDIR} && mv ${DESTDIR} ${DESTDIR}.old && rm -rf ${DESTDIR}.old & # mkdir -p ${DESTDIR} ${RELEASEDIR}
RELEASEDIR does not normally need to be empty before starting the release process, however, if there are changes in the release files or their names, old files may be left laying around. You may wish to also erase this directory before starting.

We now make the release itself:

# cd /usr/src/etc # make release
After the release is made, it is a good idea to check the release to make sure the tar files are matching what is in the DESTDIR. The output of this step should be very minimal.
# cd /usr/src/distrib/sets # sh checkflist
You now have complete and checked release file sets in the RELEASEDIR. These files can now be used to install or upgrade OpenBSD on other machines.

The authoritative instructions on making a release are in release(8).

Note: if you wish to distribute the resultant files by HTTP for use by the upgrade or install scripts, you will need to add an "index.txt" file, which contains the list of all the files in your newly created release.

# /bin/ls -1 >index.txt

5.5 - Building X (4.2 Xenocara)

Note: the following instructions are for OpenBSD 4.2 and later. If you are wishing to build X for 4.1 or before (you should really upgrade!), you can find the previous version of these instructions in cvsweb.

Starting with X.org v7, X switched to "modular build" system, splitting the x.org source tree into more than three hundred more-or-less independent packages.

To simplify life for OpenBSD users, a "meta-build" called Xenocara was developed. This system "converts" X back into one big tree to be built in one process. As an added bonus, this build process is much more similar to the build process used by the rest of OpenBSD than the previous versions were.

The official instructions for building X exist in your machine's /usr/src/xenocara/README file and in release(8).

Getting source code

The "usual" location for the xenocara source tree is /usr/src/xenocara, and the source is stored in the xenocara module in CVS. So, the checkout process is this:
$ cd /usr/src $ cvs -qdanoncvs@anoncvs.example.org:/cvs checkout -P xenocara

Building Xenocara

For building the standard xenocara tree as supported by OpenBSD, no external tools are needed.
# cd /usr/src/xenocara # make bootstrap # make obj # make build
If you wish to make actual modifications to the source code, you will probably need to add several packages. Details are in the /usr/src/xenocara/README file.

Making a release

This is similar to the main system release process. After successfully building X, you will define a DESTDIR and RELEASEDIR, with the same purposes as above. The RELEASEDIR can be the same directory as the main system RELEASEDIR, but DESTDIR will be erased and rebuilt in this process. If done carefully, this is not a problem, but using a separate DESTDIR may be "safer".

For this example, we will use a DESTDIR and RELEASEDIR of /usr/dest and /usr/rel, respectively. This must be done after the above build process.

# export DESTDIR=/usr/dest # export RELEASEDIR=/usr/rel # test -d ${DESTDIR} && mv ${DESTDIR} ${DESTDIR}- && \ rm -rf ${DESTDIR}- & # mkdir -p ${DESTDIR} ${RELEASEDIR} # make release
When this process is completed, you will have a set of release files in the $RELEASEDIR.

5.6 - Why do I need a custom kernel?

Actually, you probably don't.

A custom kernel is a kernel built with a configuration file other than the provided GENERIC configuration file. A custom kernel can be based on -release, -stable or -current code, just as a GENERIC kernel can be. While compiling your own GENERIC kernel is supported by the OpenBSD team, compiling your own custom kernel is not.

The standard OpenBSD kernel configuration (GENERIC) is designed to be suitable for most people. More people have broken their system by trying to tweak their kernel than have improved system operation. There are some people that believe that you must customize your kernel and system for optimum performance, but this is not true for OpenBSD. Only the most advanced and knowledgeable users with the most demanding applications need to worry about a customized kernel or system.

Some reasons you might want or need to build a custom kernel:

Some reasons why you should not build a custom kernel:

Removing device drivers may speed the boot process on your system, but can complicate recovery should you have a hardware problem, and is very often done wrong. Removing device drivers will not make your system run faster by any noticeable amount, though can produce a smaller kernel. Removing debugging and error checking can result in a measurable performance gain, but will make it impossible to troubleshoot a system if something goes wrong.

Again, developers will usually ignore bug reports dealing with custom kernels, unless the problem can be reproduced in a GENERIC kernel as well. You have been warned.

5.7 - Building a custom kernel

It is assumed you have read the above, and really enjoy pain. It is also assumed that you have a goal that can not be achieved by either a Boot time configuration (UKC>) or by config(8)ing a GENERIC kernel. If both of these are not true, you should stick to using GENERIC. Really.

OpenBSD kernel generation is controlled by configuration files, which are located in the /usr/src/sys/arch/<arch>/conf/ directory by default. All architectures have a file, GENERIC, which is used to generate the standard OpenBSD kernel for that platform. There may also be other configuration files which are used to create kernels with different focuses, for example, for minimal RAM, diskless workstations, etc.

The configuration file is processed by config(8), which creates and populates a compilation directory in ../compile, on a typical installation, that would be in /usr/src/sys/arch/<arch>/compile/. config(8) also creates a Makefile, and other files required to successfully build the kernel.

Kernel Configuration Options are options that you add to your kernel configuration that place certain features into your kernel. This allows you to have exactly the support you want, without having support for unneeded devices. There are a multitude of options that allow you to customize your kernel. Here we will go over only some of them, those that are most commonly used. Check the options(4) man page for a complete list of options, and as these change from time to time, you should make sure you use a man page for the same version of OpenBSD you are building. You can also check the example configuration files that are available for your architecture.

Do not add, remove, or change options in your kernel unless you actually have a reason to do so! Do not edit the GENERIC configuration file!! The only kernel configuration which is supported by the OpenBSD team is the GENERIC kernel, the combination of the options in /usr/src/sys/arch/<arch>/conf/GENERIC and /usr/src/sys/conf/GENERIC as shipped by the OpenBSD team (i.e., NOT edited). Reporting a problem on a customized kernel will almost always result in you being told to try to reproduce the problem with a GENERIC kernel. Not all options are compatible with each other, and many options are required for the system to work. There is no guarantee that just because you manage to get a custom kernel compiled that it will actually run. There is no guarantee that a kernel that can be "config(8)ed" can be built.

You can see the platform-specific configuration files here:

Look closely at these files and you will notice a line near the top similar to: include "../../../conf/GENERIC" This means that it is referencing another configuration file, one that stores platform-independent options. When creating your kernel configuration, be sure to look through sys/conf/GENERIC.

Kernel configuration options should be placed in your kernel configuration file in the format of:

option      name
option      name=value
For example, to place option "DEBUG" in the kernel, add a line like this:
option DEBUG
Options in the OpenBSD kernel are translated into compiler preprocessor options, therefore an option like DEBUG would have the source compiled with option -DDEBUG, which is equivalent to doing a #define DEBUG throughout the kernel.

Sometimes, you may wish to disable an option that is already defined, typically in the "src/sys/conf/GENERIC" file. While you could modify a copy of that file, a better choice would be to use the rmoption statement. For example, if you really wanted to disable the in-kernel debugger (not recommended!), you would add a line such as: rmoption DDB in your kernel configuration file. option DDB is defined in src/sys/conf/GENERIC, but the above rmoption line deactivates it.

Once again, please see options(4) for more information about the specifics of these options. Also note that many of the options also have their own manual pages -- always read everything available about an option before adding or removing it from your kernel.

Building a custom kernel

In this case, we will build a kernel that supports the boca(4) ISA multi-port serial card. This card is not in the GENERIC kernel, due to conflicts with other drivers. Another common reason to make a custom kernel would be to use RAIDframe, which is too large to have in the stock kernel. There are two common ways to make a custom kernel: copy the GENERIC config file to another name and edit it, or create a "wrapper" file that "includes" the standard GENERIC kernel and any options you need that aren't in GENERIC. In this case, our wrapper file looks like this:
include "arch/i386/conf/GENERIC" boca0 at isa? port 0x100 irq 10 # BOCA 8-port serial cards pccom* at boca? slave ?
The two lines regarding the boca(4) card are copied from the commented out lines in GENERIC, with the IRQ adjusted as needed. The advantage to using this "wrapper" file is any unrelated changes in GENERIC are updated automatically with any other source code update. The disadvantage is one can not remove devices (though in general, that's a bad idea, anyway).

Another way to generate a custom kernel is to make a copy of the standard GENERIC, giving it another name, then editing it as needed. The disadvantage to this is later updates to the GENERIC configuration file have to be merged into your copy, or you have to remake your configuration file.

In either event, after making your custom kernel configuration file, use config(8) and make the kernel as documented above.

Full instructions for creating your own custom kernel are in the afterboot(8) man page.

5.8 - Boot-Time Configuration

Sometimes when booting your system you might notice that the kernel finds your device but maybe at the wrong IRQ. And maybe you need to use this device right away. Well, without rebuilding the kernel you can use OpenBSD's boot time kernel configuration. This will only correct your problem for one time. If you reboot, you will have to repeat this procedure. So, this is only meant as a temporary fix, and you should correct the problem using config(8). Your kernel does however need option BOOT_CONFIG in the kernel, which GENERIC does have.

Most of this document can be found in the man page boot_config(8).

To boot into the User Kernel Config, or UKC, use the -c option at boot time.

boot> boot hd0a:/bsd -c
Or whichever kernel it is you want to boot. Doing this will bring up a UKC prompt. From here you can issue commands directly to the kernel specifying devices you want to change or disable or even enable.

Here is a list of common commands in the UKC.

Once you have your kernel configured, use quit or exit and continue booting. After doing so, you should make the change permanent in your kernel image, as described in Using config(8) to change your kernel.

5.9 - Using config(8) to change your kernel

The -e and -u options with config(8) can be extremely helpful and save wasted time compiling your kernel. The -e flag allows you to enter the UKC or User Kernel Config on a running system. These changes will then take place on your next reboot. The -u flag tests to see if any changes were made to the running kernel during boot, meaning you used boot -c to enter the UKC while booting your system.

The following example shows the disabling of the ep* devices in the kernel. For safety's sake you must use the -o option which writes the changes out to the file specified. For example : config -e -o bsd.new /bsd will write the changes to bsd.new. The example doesn't use the -o option, therefore changes are just ignored, and not written back to the kernel binary. For more information pertaining to error and warning messages read the config(8) man page.

$ sudo config -e /bsd OpenBSD 4.2 (GENERIC) #375: Tue Aug 28 10:38:44 MDT 2007 deraadt@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC warning: no output file specified Enter 'help' for information ukc> ? help Command help list add dev Add a device base 8|10|16 Base on large numbers change devno|dev Change device disable attr val|devno|dev Disable device enable attr val|devno|dev Enable device find devno|dev Find device list List configuration lines count # of lines per page show [attr [val]] Show attribute exit Exit, without saving changes quit Quit, saving current changes timezone [mins [dst]] Show/change timezone nmbclust [number] Show/change NMBCLUSTERS cachepct [number] Show/change BUFCACHEPERCENT nkmempg [number] Show/change NKMEMPAGES shmseg [number] Show/change SHMSEG shmmaxpgs [number] Show/change SHMMAXPGS ukc> list 0 audio* at sb0|sb*|gus0|pas0|sp0|ess*|wss0|wss*|ym*|eap*|eso*|sv*|neo*|cmpci* |clcs*|clct*|auich*|autri*|auvia*|fms*|uaudio*|maestro*|esa*|yds*|emu* flags 0x0 1 midi* at sb0|sb*|opl*|opl*|opl*|opl*|ym*|mpu*|autri* flags 0x0 2 nsphy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr* |ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e p*|ep* phy -1 flags 0x0 3 nsphyter* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*| vr*|ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep *|ep*|ep* phy -1 flags 0x0 4 qsphy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr* |ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e p*|ep* phy -1 flags 0x0 5 inphy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr* |ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e p*|ep* phy -1 flags 0x0 6 iophy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr* |ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e p*|ep* phy -1 flags 0x0 7 eephy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr* |ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e p*|ep* phy -1 flags 0x0 8 exphy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr* |ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e p*|ep* phy -1 flags 0x0 [...snip...] ukc> disable ep 67 ep0 disabled 68 ep* disabled 69 ep* disabled 155 ep0 disabled 156 ep0 disabled 157 ep* disabled 158 ep* disabled 210 ep* disabled ukc> quit not forced

In the above example, all ep* devices are disabled in the kernel and will not be probed. In some situations where you have used the UKC during boot, via boot -c, you will need these changes to be written out permanently. To do this you need to use the -u option. In the following example, the computer was booted into the UKC and the wi(4) device was disabled. Since changes made with boot -c are NOT permanent, these changes must be written out. This example writes the changes made from boot -c into a new kernel binary bsd.new.

$ sudo config -e -u -o bsd.new /bsd OpenBSD 4.2 (GENERIC) #375: Tue Aug 28 10:38:44 MDT 2007 deraadt@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC Processing history... 105 wi* disabled 106 wi* disabled Enter 'help' for information ukc> quit

5.10 - Getting more verbose output during boot

Getting more verbose output can be very helpful when trying to debug problems when booting. If you have a problem wherein your boot floppy won't boot and need to get more information, simply reboot. When you get to the "boot>" prompt, boot with boot -c. This will bring you into the UKC>, then do:
UKC> verbose autoconf verbose enabled UKC> quit

Now you will be given extremely verbose output upon boot.

5.11 - Common problems, tips and questions when compiling and building

Most of the time, problems in the build process are caused by not following the above directions carefully. There are occasional real problems with building -current from the most recent snapshot, but failures when building -release or -stable are almost always user error.

Most problems are usually one of the following:

Here are some additional problems you might encounter, however:

5.11.1 - The build stopped with a "Signal 11" error

Building OpenBSD and other programs from source is a task which pushes hardware harder than most others, making intensive use of CPU, disk and memory. As a result, if you have hardware which has a problem, the most likely time for that problem to appear is during a build. Signal 11 failures are typically caused by hardware problems, very often memory problems, but can also be CPU, main board, or heat issues. Your system may actually be very stable otherwise, but unable to compile programs.

You will probably find it best to repair or replace the components that are causing trouble, as problems may show themselves in other ways in the future. If you have hardware which you really wish to use and causes you no other problem, simply install a snapshot or a release.

For much more information, see the Sig11 FAQ.

5.11.2 - "make build" fails with "cannot open output file snake: is a directory"

This is the result of two separate errors: It is important to carefully follow the instructions when fetching and building your tree.

5.11.3 - My IPv6-less system doesn't work!

Yes. Please do not make modifications to the base system that you don't understand the implications of. One "little" change in the kernel can have very large impact to the entire rest of the system. Please re-read this.

5.11.4 - Oops! I forgot to make the /usr/obj directory first!

By doing a "make build" before doing a "make obj", you will end up with the object files scattered in your /usr/src directory. This is a bad thing. If you wish to try to avoid re-fetching your entire src tree again, you can try the following to clean out obj files: # cd /usr/src # find . -type l -name obj | xargs rm # make cleandir # rm -rf /usr/obj/* # make obj

5.11.5 - Tip: Put /usr/obj on its own partition

If you build often, you may find it faster to put /usr/obj on its own partition. The benefit is simple, it is typically faster to: # umount /usr/obj # newfs YourObjPartition # mount /usr/obj than to "rm -rf /usr/obj/*".

5.11.6 - How do I not build parts of the tree?

Sometimes, you may wish to not build certain parts of the tree, typically because you have installed a replacement for an included application from packages, or wish to make a "smaller" release for whatever reason. The solution to this is to use the SKIPDIR option of /etc/mk.conf.

Note: it is possible to make a broken system this way. The results of this option are not supported by the OpenBSD project.

5.11.7 - Where can I learn more about the build process?

Here are some other resources:

5.11.8 - I didn't see any snapshots on the FTP site. Where did they go?

Snapshots may be removed as they become old (or no longer relevant) or near the time of a new -release.

5.11.9 - How do I bootstrap a newer version of the compiler (gcc)?

You should really just install the latest snapshot.

OpenBSD now supports two compilers in-tree, gcc v3.3.5 used by most platforms, but also gcc v2.95.3 used by a few platforms which haven't been converted yet, or may never be converted due to lack of gcc3 support or poor gcc3 performance.

The two compilers are in different parts of the tree:

Because upgrading a compiler is a bit of a chicken-and-egg problem, changes to the in-tree compiler require a little extra attention. You have to build the compiler twice -- the first build produces a compiler that generates new code but runs with code generated by the old compiler, the second build makes it a completely new compiler. In general, you'll want to perform the following procedure: If your platform uses gcc 2.95.3: # rm -r /usr/obj/gnu/egcs/gcc/* # cd /usr/src/gnu/egcs/gcc - or - If your platform uses gcc 3.3.5: # rm -r /usr/obj/gnu/usr.bin/gcc/* # cd /usr/src/gnu/usr.bin/gcc Common build procedure for v3.3.5 or v2.95.3 # make -f Makefile.bsd-wrapper clean # make -f Makefile.bsd-wrapper obj # make -f Makefile.bsd-wrapper depend # make -f Makefile.bsd-wrapper # make -f Makefile.bsd-wrapper install # make -f Makefile.bsd-wrapper clean # make -f Makefile.bsd-wrapper depend # make -f Makefile.bsd-wrapper # make -f Makefile.bsd-wrapper install

And then run a normal make build.

5.11.10 - What is the best way to update /etc, /var, and /dev?

As a policy, software in the OpenBSD tree does not modify files in /etc automatically. This means it is always up to the administrator to make the necessary modifications there. Upgrades are no exception. To update files in these directories, first determine what changes have occurred to the base (distribution) files, and then manually reapply these changes.

For example, to see the files in the tree that have changed most recently, do a: # cd /usr/src/etc # ls -lt |more

To see all the changes in /etc between arbitrary versions of OpenBSD, you can use CVS. For example, to see the changes between 4.1 and 4.2 do a: # cd /usr/src/etc # cvs diff -u -rOPENBSD_4_1 -rOPENBSD_4_2 To see the changes between 4.2 and -current ("HEAD"), use: # cd /usr/src/etc # cvs diff -u -rOPENBSD_4_2 -rHEAD The /dev/MAKEDEV script is not updated automatically as part of the make build process, however it is installed as as part of a binary upgrade. As a general rule, it is a good idea to copy (if needed) and run this script from your source tree when performing an upgrade: # cd /dev # cp /usr/src/etc/etc.`machine`/MAKEDEV ./ # ./MAKEDEV all

Once you have identified the changes, reapply them to your local tree, preserving any local configuration you may have done.

Typical /etc changes to watch out for between releases include:

These changes are summarized in upgrade42.html (for going to 4.2-release) or current.html (for going to -current).

5.11.11 - Is there an easy way to make all the file hierarchy changes?

From time to time, files or directories are added to, or removed from the file hierarchy. Also, ownership information for portions of the filesystem may change. An easy way to ensure that your file hierarchy is up-to-date is to use the mtree(8) utility.

First, fetch the latest source, then do the following: # cd /usr/src/etc/mtree # install -c -o root -g wheel -m 600 special /etc/mtree # install -c -o root -g wheel -m 444 4.4BSD.dist /etc/mtree # mtree -qdef /etc/mtree/4.4BSD.dist -p / -u

Your file hierarchy should now be up to date.

5.11.12 - Can I cross-compile? Why not?

Cross-compiling tools are in the system, for use by developers bringing up a new platform. However, they are not maintained for general use.

When the developers bring up support for a new platform, one of the first big tests is a native-build. Building the system from source puts considerable load on the OS and machine, and does a very good job of testing how well the system really works. For this reason, OpenBSD does all the build process on the platform the build is being used for, also known as "native building". Without native building, it is much more difficult to be sure that the various platforms are actually running reliably, and not just booting.

[FAQ Index] [To Section 4 - Installation Guide] [To Section 6 - Networking]

[back] www@openbsd.org
$OpenBSD: faq5.html,v 1.161 2007/11/18 10:00:45 steven Exp $