Archive
So You Want A New FreeBSD Boot Loader Option…
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.
Prerequisites
- This post assumes FreeBSD 8.x, but should apply with any version running loader(8)
- This post assumes that a secondary/debug kernel is installed
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 then + dup bootdebugkey @ = if + s" /boot/DEBUG/kernel" 1 boot + then dup escapekey @ = if 2drop 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.
Building FreeBSD Media With Custom Packages
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
The Use Case
I generate company specific FreeBSD distributions based on our internal requirements including loading specific packages. The FreeBSD DVD release from freebsd.org includes a packages/ directory created by the package-split.py 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.
Prerequisites
- A directory containing at least the packages to include. One can download packages for 8.3-RELEASE via ftp at ftp://ftp.freebsd.org/pub/FreeBSD/ports/amd64/packages-8.3-release/.
- An INDEX file. The INDEX file will already exist if one downloads the packages from the above ftp server.
Configuring package-split.py
package-split.py 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 package-split.py 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: pkgs.extend(['ftp/wget', 'devel/subversion', 'lang/perl5.12', 'lang/python', 'lang/ruby18', 'net/rsync'])
Caveats
- 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.
- use the origin field to identify the package in configuring the package-split.py 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
Building FreeBSD With Multiple Kernels
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 http://svn.freebsd.org/base/stable/8 > 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 KDB_UNATTENDED
options DDB
Compiling The Release
Now compile the release (as root, in bash):
# cd release
# CHROOTDIR=/usr/release CVSROOT=/home/ncvs EXTPORTSDIR=/usr/ports EXTSRCDIR=/usr/src MAKE_DVD=Yes NO_FLOPPIES=Yes NODOC=Yes KERNELS=DEBUG KERNCONF=DEBUG INSTKERNNAME=DEBUG make release
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.
kernel=DEBUG
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