4 October 2016

Modifying, Compiling and Running the OpenBSD Kernel

This guide uses 64bit OpenBSD 6.0 as an example.

Generally there two trains for compiling OpenBSD;
1) Making changes to a particular release
2) Making changes to the current code HEAD

If you want to make changes to a particular release, you must first install the .iso for that image, and then get the source for that release + Errata patches (Stable).

If you want to play with the current HEAD, you MUST install the .iso from the latest "Snapshot".

Do not try and get to "Current" from a release image. It might work, but you will also have to follow the same manual steps that the Devs use (see Flag Day) to uplift the environment to match the HEAD code.

When compiling OpenBSD please make sure that /usr is at least 4GB to ensure enough space and inodes.

Install required packages;
#export PKG_PATH="http://ftp.mirrorservice.org/pub/OpenBSD/snapshots/packages/amd64/"   <- Current Binaries for Snapshot install
export PKG_PATH="http://ftp.mirrorservice.org/pub/OpenBSD/6.0/packages/amd64/"   <- Stable (Patches) for Release install
 

pkg_add -i vim-7.4.1467p1-no_x11 gawk gcc gcc-libs g++ cmake automake-1.15p0 autoconf-2.69p2 git gtest libtool

Setup CVS;
export CVSROOT=anoncvs@anoncvs.spacehopper.org:/cvs
Use a CVS mirror closest to you (https://www.openbsd.org/anoncvs.html)

export MIRROR="http://mirror.exonetric.net"
Use a packages mirror closest to you (https://www.openbsd.org/ftp.html)

Setup the Directories for compiling;
cd /usr
mkdir -p src xenocara ports
chmod 775 src xenocara ports
chgrp wsrc src xenocara ports


You can pre-load the source tree using tar.gz downloads, and then run CVS to just update the tree. This is a lot quicker than trying to download the entire tree via CVS from scratch.

NB;
src = Kernal source & Built in User land source 
xenocara = X system source
ports = Userland "ports" source (https://www.openbsd.org/faq/faq15.html)

Pre-loading CVS Tree;
cd /var/tmp
wget ${MIRROR}/pub/OpenBSD/6.0/src.tar.gz
wget ${MIRROR}/pub/OpenBSD/6.0/sys.tar.gz
tar -zxvf /var/tmp/src.tar.gz -C /usr/src/
tar -zxvf /var/tmp/sys.tar.gz -C /usr/src/
cd /usr


NB; Both src and sys make up /usr/src (they are just divided into two downloads, one for the Kernel source and User land source).

Update the CVS tree;
#cvs -qd $CVSROOT get src               # Get Current HEAD (if you didnt preload)
#cvs -d $CVSROOT up -Pd -C              # Update to Current HEAD
cvs -d $CVSROOT up -rOPENBSD_6_0 -Pd    # Update Release Stable (Errata Patches)


NB; replace the label "OPENBSD_6_0" with the release you are working with.

If you want to checkout the entire source tree (-current) without preloading tree 
cvs -qd $CVSROOT checkout -P src
cvs -qd $CVSROOT get -P src
cvs -qd $CVSROOT get -P ports
cvs -qd $CVSROOT get -P xenocara

If you want to apply Patches to the Source;
# http://ftp.openbsd.org/pub/OpenBSD/patches/6.0.tar.gz <- (Provides All Errata patches - Also provided by updating the source tree as above with "
-rOPENBSD_6_0")
cd /usr/src
wget http://bulabula.org/diffs/hfsc64.diff
patch -p0 < /var/tmp/hfsc64.diff

 or (for signed patches)
cd /var/tmp
wget http://ftp.openbsd.org/pub/OpenBSD/patches/6.0.tar.gz
tar -zxvf 6.0.tar.gz
signify -Vep /etc/signify/openbsd-60-base.pub -x /var/tmp/6.0/common/001_uvmisavail.patch.sig -m - | (cd /usr/src && patch -p0)
NB; "/var/tmp/6.0/common/001_uvmisavail.patch.sig" is one of the extracted signed patches.


 I was recently debugging an issue with OpenBSD which was output dropping many VLAN packets. So I edited /usr/src/sys/net/if_vlan.c and added debug lines around all the places where if_oerrors is incremented.
E.g;

Index: if_vlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vlan.c,v
retrieving revision 1.165
diff -u -p -r1.165 if_vlan.c
--- if_vlan.c   18 May 2016 03:46:03 -0000      1.165
+++ if_vlan.c   4 Oct 2016 10:25:57 -0000
@@ -290,12 +290,14 @@ vlan_start(struct ifnet *ifp)
                            (prio << EVL_PRIO_BITS));

                        if (m == NULL) {

                                ifp->if_oerrors++;

+                               printf("Output Error due to NULL mbuff\n");

                                continue;

                        }

                }


                if (if_enqueue(ifp0, m)) {

                        ifp->if_oerrors++;
+                       printf("Output Error from if_enqueue\n");
                        continue;
                }
                ifp->if_opackets++;

I then recompiled the kernel, rebooted, ran some traffic through the firewall until the VLAN output drop counters incremented.

I then examined dmesg to see that all of my drops were being generated by the test (if_enqueue(ifp0, m)) being TRUE, and not because the mBuff was NULL.

From here keep tracing the code path back adding debugging lines each time until you get to the root cause :)


Building the Kernel;
Move old Config out the way
#mv /usr/src/sys/arch/i386/conf/GENERIC /usr/src/sys/arch/i386/conf/GENERIC.old
#mv /usr/src/sys/arch/amd64/conf/GENERIC.MP /usr/src/sys/arch/amd64/conf/GENERIC.MP.old


cd /usr/src/sys/arch/amd64/conf

Add any Kernal Options you want;
#echo "option  ART" >> /usr/src/sys/arch/amd64/conf/GENERIC.MP
config GENERIC.MP
cd ../compile/GENERIC.MP
make clean
make depend
make
cp /bsd /bsd.old
#install -o root -g wheel -m 644 bsd /
make install

You should now reboot to boot into your newly compiled Kernel

Building the Userland;
Clean up Userland first if built previously (else Objects will be all over the place)
cd /usr/src
find . -type l -name obj | xargs rm
make cleandir


Build Userland
rm -rf /usr/obj/*
cd /usr/src
make obj
cd /usr/src/etc && env DESTDIR=/ make distrib-dirs
cd /usr/src
make build
make install


You should now reboot again to boot into your newly compiled Kernel with new User land

Extra notes;
# Setup Ports Source
cd /var/tmp
wget ${MIRROR}/pub/OpenBSD/snapshots/ports.tar.gz   # Update to Current
#wget ${MIRROR}/pub/OpenBSD/5.9/ports.tar.gz        # Stable (Patches)
tar -zxvf /var/tmp/ports.tar.gz -C /usr/
cd /usr/ports
cvs -d $CVSROOT up -Pd -C               # Current
#cvs -d $CVSROOT up -rOPENBSD_5_9 -Pd   # Stable (Patches)


# Setup X11 Source
cd /var/tmp
wget ${MIRROR}/pub/OpenBSD/5.9/xenocara.tar.gz
tar -zxvf /var/tmp/xenocara.tar.gz -C /usr/
cd /usr/xenocara/
cvs -d $CVSROOT up -Pd -C               # Update to Current
#cvs -d $CVSROOT up -rOPENBSD_5_9 -P    # Stable (Patches)



Extra references;
man release
https://www.openbsd.org/faq/faq5.html
https://www.openbsd.org/faq/faq10.html#Patches

No comments:

Post a Comment