Skip to content

Instantly share code, notes, and snippets.

@nouredd2
Last active September 6, 2018 21:36
Show Gist options
  • Save nouredd2/300c12e7cd81f8814900284c441a72a2 to your computer and use it in GitHub Desktop.
Save nouredd2/300c12e7cd81f8814900284c441a72a2 to your computer and use it in GitHub Desktop.
A starter to building your first kernel

Introduction to Linux kernel building

The goal of this gist is to introduce you to building your first Linux kernel and installing it on an Ubuntu Linux virtual machine.

Prerequisites

We assume the presence of the following tools:

  1. Access to a Linux machine to build the kernel

    • On this machine, install the following packages (assuming it's an Ubuntu machine):
      sudo apt install libncurses5-dev gcc make git exuberant-ctags bc libssl-dev
    • Since we're already installing things, let's go ahead and install vim and cscope
      sudo apt install vim cscope
  2. Access to an Ubuntu virtual machine. You can use VirtualBox or any other virtualization technology. At this step, host refers the machine that is running VirtualBox while guest refers to the machine that is virtually running in of VirtualBox.

    • It is best not to use a virtual machine for compiling the kernel since compilation will be resource intensive and would take forever on a non well-provisioned machine.
    • Create a new virtual machine using the VirtualBox GUI and install any Ubuntu distribution on it. For faster results, it is better to work with the Ubuntu server edition. You can download the latest Ubuntu server edition (18.04.1) from the official Ubuntu repo.
    • After the vm has started, login and check the IP address of the machine and record it:
      ifconfig -a
    • From the host machine, make sure that you can reach the vm via the virtual network. To check that, assume that 192.168.122.1 is the IP address of the vm, from a terminal on the host machine, do
      ping -c1 192.168.122.1
      If the ping does not go through, then the connection is not successful and we might need to do some more configuration. If the connection goes through, check that you can ssh into the virtual machine using where user is the username used when creating the virtual machine.

Compiling the kernel

Download the latest kernel from the official kernel source.

  • From the host machine, download the kernel into a directory using

    wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.18.6.tar.xz
  • Extract the contents of the kernel source tree

    tar -xvf linux-4.18.6.tar.xz
  • This will create the directory linux. Change into that directory and let's start compiling the kernel. First let's copy the default configuration file from the current host machine (Note: Only do this if the host machine is running a Linux machine).

    cd linux/
    cp /boot/config-`(uname -r)` .config
  • Let's feed the config file to the kernel build mechanism

    yes '' | make oldconfig

    The command yes '' will answer all the questions of the configurations options that are missing with the default values.

  • If the host machine is not running Linux, then you can use

    make defconfig

    to use the default configuration files included with the kernel.

  • Now it's time to start the long build step. If you are on a remote server, then to make sure that the process is not killed if the remote session is broken, we need to run our process in the background. To do so, we can either use tmux or screen. Since tmux provides a richer set of features (imo), we will go with tmux.

    • To install tmux in case it was not installed:
      sudo apt install -y tmux
    • Start a new tmux session
      tmux new -s kernelbuild
      kernelbuild is the name of our session so we can pick it up later. This will drop you into a new session that you can leave running in the background if desired.
  • Now let's build the kernel. To start compilation, we will use the make utility (well we alerady kinda did), so use

    make -j $(getconf _NPROCESSORS_ONLN) deb-pkg LOCALVERSION=-custom
    • You can replace custom with anything you would want to appear appended to your custom kernel version.
    • This will start printing all kinds of compilation things and the process has started. If you are running this inside of a tmux session, you can detach from that session using the keyboard combination
      <C-b> d
      
      where <C-b> is the tmux's bind key, and by default this is the Control key pressed with the b key. So the key combination becomes Control + b then d.
    • To check the current running tmux sessions use
      tmux ls
      It should print something like
      kernelbuild: 1 windows (created Thu Sep  6 20:41:56 2018) [238x60]
      
    • To reattach to a running tmux session use
      tmux at -t kernelbuild
      If kernelbuild is the only session running, then tmux at will drop you directly into that session.
  • Grab a cup of coffee and enjoy the break while waiting for the compilation to end. It might take a while. It's always good to bring out the classic compilation xkcd:

    Enjoy compiling

Installing the kernel

Once the compilation completes without errors, then congratulations, you have just compiled your first kernel. If you go up one directory (cd ..), you should see the following files pop-up:

../linux-4.18.6-custom_4.18.6-custom-1.diff.gz
../linux-4.18.6-custom_4.18.6-custom.orig.tar.gz
../linux-image-4.18.6-custom_4.18.6-custom-1_amd64.deb
../linux-libc-dev_4.18.6-custom-1_amd64.deb
../linux-4.18.6-custom_4.18.6-custom-1.dsc
../linux-headers-4.18.6-custom_4.18.6-custom-1_amd64.deb
../linux-image-4.18.6-custom-dbg_4.18.6-custom-1_amd64.deb

The files we care about are the ones that end with .deb extension. These are the files that we will use for installing the kernel on the virtual machine. Specifically, the ones we really need are

../linux-image-4.18.6-custom_4.18.6-custom-1_amd64.deb
../linux-headers-4.18.6-custom_4.18.6-custom-1_amd64.deb

So let's copy those files to the virtual machine

scp linux-image-*.deb [email protected]:~/
scp linux-headers-*.deb [email protected]:~/

Remember to replace user and 192.168.122.1 with the username and the IP address used for the virtual machine you have created. scp is the "secure copy" utility that will copy files over a network.

Next, let's log into the virtual machine and install the kernel

Once in the vm, the .deb packages should be in the home directory, then let's install them all in one shot

sudo dpkg -i *.deb

where dpkg is the Debian-based package manager (for installing software) and the flag -i signals to the manager that we want to install the deb packages. Finally *.deb means that we will install all files that end with .deb (the * means the Kleen Star).

After installation ends, we need to refresh our grub configuration, so we can do that with

sudo update-grub

grub is the default bootloader for Linux systems, it takes care of loading the right stuff at startup time.

Now let's restart the virtual machine

sudo reboot

At this stage you will be disconnected from the vm so you should ssh back into it after it has restarted. Once you log back in, you can check which kernel you are running using

uname -r

which should show something like

4.18.6-custom
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment