Archive for October, 2012

So You Want A New FreeBSD Boot Loader Option…

October 11, 2012 2 comments

Creating A New FreeBSD Boot Loader Option

The Use Case

There are multiple kernels installed on the FreeBSD host and an option to boot to this kernel is necessary.


The Patch

This is the patch. Copy/paste it to /boot/beastie.patch for use in the procedure below.

Index: beastie.4th
--- beastie.4th
+++ beastie.4th
@@ -41,6 +41,7 @@
 variable bootkey
 variable bootacpikey
 variable bootsafekey
+variable bootdebugkey
 variable bootverbosekey
 variable bootsinglekey
 variable escapekey
@@ -194,6 +195,7 @@
 	printmenuitem ."  Boot FreeBSD in Safe Mode" bootsafekey !
 	printmenuitem ."  Boot FreeBSD in single user mode" bootsinglekey !
 	printmenuitem ."  Boot FreeBSD with verbose logging" bootverbosekey !
+	printmenuitem ."  Boot FreeBSD with debug kernel" bootdebugkey !
 	printmenuitem ."  Escape to loader prompt" escapekey !
 	printmenuitem ."  Reboot" rebootkey !
 	menuX @ 20 at-xy
@@ -286,6 +288,9 @@
 			s" YES" s" boot_single" setenv
 			0 boot
+		dup bootdebugkey @ = if
+			s" /boot/DEBUG/kernel" 1 boot
+		then
 		dup escapekey @ = if
 			s" NO" s" autoboot_delay" setenv

Applying The Patch

Follow these steps to apply the patch to your target hosts:

# cd /boot
# cp beastie.4th beastie.4th.orig
# patch -p0 < beastie.patch

The new option will be loaded when loader called beastie.4th.

Categories: FreeBSD

Building FreeBSD Media With Custom Packages

October 8, 2012 Leave a comment

Building FreeBSD Media With Custom Packages

Building a FreeBSD release can be as simple as executing:

# cd /usr/src
# make buildworld
# cd release
# make release
# PKG_TREE=$pkg_dir PKG_DEST=$CHROOTDIR/R/cdrom/dvd1 PKG_DVD=Yes make package-split
This post expands on the `make package-split` command whose purpose is to create a packages directory.

The Use Case

I generate company specific FreeBSD distributions based on our internal requirements including loading specific packages. The FreeBSD DVD release from includes a packages/ directory created by the script. I use the same script to accomplish the same task with custom packages.

We generate an ISO from the release and import it into Cobbler. We’ve setup Cobbler to allow us to provision operating systems non-interactively using PXE, DHCP, TFTP, and HTTP.


  • A directory containing at least the packages to include. One can download packages for 8.3-RELEASE via ftp at
  • An INDEX file. The INDEX file will already exist if one downloads the packages from the above ftp server.

Configuring is a Python script that “generates a master INDEX file for the CD images built by the FreeBSD release engineers. Each disc is given a list of desired packages. Dependencies of these packages are placed on either the same disc or an earlier disc. The resulting master INDEX file is then written out”.

In our use case, the files are not split into separate discs because we are packaging for a DVD as identified by the PKG_DVD environment variable.

View the here. Because I am currently working with 8.3-RELEASE, I link directly to the that version of the script.

Our use case involves commenting lines 43 – 81 and copying lines 63 – 81. The copied lines are modified with names of packages installed in our base distribution. An example might look similar to:

if doing_dvd:


  1. There are inconsistencies in the INDEX file where some package names and origins do not match. An example such as ruby18-iconv shows the package name (column 1) is ruby18-iconv-$version while the origin (column 2) is /usr/ports/converters/ruby-iconv. `make package-split` errored on this package citing “Unable to find package for converters/ruby18-iconv” (see image below). Changing origin from “ruby-iconv” to “ruby18-iconv” resolved this.
  2. use the origin field to identify the package in configuring the script. For example, ruby18-iconv, would be specified as ‘converters/ruby19-iconv’ as opposed to ‘ruby/ruby18-iconv’ despite having multiple categories and existing multiple directories.

Executing `make package-split`

Once the release is built, create the packages directory and move it to the new release by executing the following. This would also be an appropriate time to make additional modifications to the image such as replacing the mfsroot.gz with a new custom mfsroot.

# PKG_TREE=/tmp/packages PKG_DEST=$CHROOTDIR/R/cdrom PKG_DVD=Yes make package-split
# mv $CHROOTDIR/R/cdrom/disc1/packages $CHROOTDIR/R/cdrom/dvd1

Generate the ISO

The release is now ready to be made into an ISO that we use to import the distribution into our provisioning platform, Cobbler.

# mkisofs -R -no-emul-boot -b boot/cdboot -o /tmp/iso/FreeBSD-8.3-RELEASE-p4-amd64-CUSTOM.iso $CHROOTDIR/R/cdrom/dvd1
Categories: FreeBSD

Building FreeBSD With Multiple Kernels

October 1, 2012 Leave a comment

Building a Release With Multiple Kernels

The Use Case

FreeBSD installs a run-time kernel used during normal day-to-day operations. In the event of repeated kernel panics, there may be a need for a kernel capable of online debugging.

Patching sysinstall

sysinstall(8) lacks support for installing multiple kernel distributions in releases 8.3 or earlier. Patch r240972 was committed to stable/8 enabling support for a DEBUG kernel distribution. The procedure below patches the sources with bits necessary for the remainder of this post.

# cd /usr/src
# svn diff -c 240972 > sysinstall_patch
# patch -p0 < sysinstall_patch

Replacing the string DEBUG in the patch changes the kernel distribution name.

Preparing The Build

The only prerequisite is having FreeBSD sources available and, optionally, ports. Ports is obtained via cvs or Subversion. Information on FreeBSD source trees are found here.

We assume a FreeBSD release build with two kernels, GENERIC and DEBUG, on the amd64 architecture. To avoid using CVS/SVN as part of the build process, it is helpful to have a local copy of ports and FreeBSD sources. In this example, ports is /usr/ports and the sources are /usr/src.

First we must buildworld:

# cd /usr/src && make buildworld

The Kernel Config

The FreeBSD release build process builds the GENERIC kernel by default. Adding an additional kernel is accomplished by first creating the kernel config file. We will create a kernel config called /usr/src/sys/amd64/conf/DEBUG. The kernel config should appear as follows:

include GENERIC
options DDB

Compiling The Release

Now compile the release (as root, in bash):

# cd release

This example builds a DVD image, no floppy images, no documentation, with ports and sources at /usr/ports and /usr/src, respectively. The DEBUG kernel and config file are defined by the KERNELS, KERNCONF, and INSTKERNNAME environment variables. Not all of these are required and operators may choose options not shown here. Information on available environment variables are found in the release(7) manpage. Many of these options can be set in /usr/src/release/Makefile.

The CVSROOT environment variable is non-optional. It is used to download ports and sources. If the environment variables EXTPORTSDIR and EXTSRCDIR are set, `make release` will not consult CVSROOT, despite being non-optional.

Executing/Using The Kernel

From the loader menu

Press 6 at the loader menu to escape to the loader(8) prompt and type:

boot DEBUG

From the running system

The DEBUG kernel is loaded by default when the kernel line in loader.conf appears as follows. Each subsequent boot loads the DEBUG kernel.


Dropping into the debugger

A kernel panic induces a system reboot unless debug.debugger_on_panic is enabled as follows:

sysctl debug.debugger_on_panic=1

To induce a panic:

sysctl debug.kdb.panic=1

Categories: FreeBSD