Building the Linux* Kernel

ID 727037
Updated 2/4/2022
Version Latest
Public

author-image

By

Installing the Operating System


The safest way to test the latest kernel is to install a basic OS as the vehicle, such as ubuntu or fedora. if you have a linux OS already installed on your test system then skip to the section on building the kernel. For the purposes of this documentation, I'm assuming the use of Ubuntu (or at the very least a debian based linux distro). Fedora uses RPM files for packaging so the build/install process will be slightly different.

Ubuntu 14.04 (desktop 64-bit version):
http://releases.ubuntu.com/14.04/ubuntu-14.04-desktop-amd64.iso

Download and burn this image to a USB key that has at least 2GB of space. On linux this is easiest with 'dd'. First insert the key, then use fdisk to determine its device, then burn the image.

%> sudo fdisk -l
Disk /dev/sdc: 8192 MB (this is the usb key's device, you can tell by the size)
%> sudo dd if=ubuntu-14.04-desktop-amd64.iso of=/dev/sdc

 

Once dd is finished, remove the key and insert it into a USB port on your test system. You'll need to boot with this key. Normally, system boot sets USB devices first to boot if found, but if your system doesn't, press F7 (or whatever key it tells you too on the boot screen) to pull up the boot menu. Then select your USB key. The OS should boot to a live image running off the key, and you can then select "Install to Disk" in order to install the OS. Once this is done, reboot, remove the key when it tells you to, and you're good to go.

NOTE: For Ubuntu, if you don't like the new unity desktop and want to go back to the good old gnome desktop, install the "gnome-panel" package, then logout, and before logging back in select the gnome classic (Metacity) desktop.

Configuring Linux for sleepgraph Usage and Kernel Build

Most linux distros automatically have everything you need to run sleepgraph immediately after a fresh install. The tool only requires python2.7 and util-linux (for rtcwake). But if you're also building the kernel on the system be sure these packages are installed.

%> sudo apt-get install python2.7 build-essential git-core util-linux openssh-server


Update the kernel command line by editting the grub config and running update-grub (if you don't run update-grub, the config won't actually change for existing or newly installed kernels).
 

%> sudo nano /etc/default/grub:
GRUB_CMDLINE_LINUX_DEFAULT="... initcall_debug log_buf_len=16M ..."
%> sudo update-grub


Getting the Upstream Kernel Source

The latest kernel is Linus Torvald's git repo on kernel.org. Use git to clone the folder: this is what you will be building. It may take several minutes to download the whole thing, the kernel source and its git history is over 2GB now.

%> mkdir ~/workspace
%> cd ~/workspace
%> git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
%> cd linux


You might as well also download the latest sleepgraph as well from git so you can use the patches.

%> cd ~/workspace
%> git clone https://github.com/01org/suspendresume
%> cd suspendresume

 

Configuring and Patching the Kernel Source

The first thing you need to do now is create a config for the kernel. I find the easiest way is to copy your OS's current kernel config over and edit that. This way you know the kernel is built with the right options to run on your system.
 

%> cd ~/workspace/linux
%> cp /boot/config-`uname -r` .config


Then edit it to be sure these lines are enabled:
 

CONFIG_PM=y
CONFIG_PM_DEBUG=y
CONFIG_PM_SLEEP_DEBUG=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y


And also, you may want to disable this line. It tells the kernel *not* to build a gigantic 800 MB debug info package. It's not necessary to run the kernel and it makes the build take 3 times as long.
 

# CONFIG_DEBUG_INFO is not set


Now you should patch the kernel source with whatever additions you want made. For sleepgraph there are several patches that help in tracing specific subsystems like USB, but for general purposes use the trace event patch:
 

%> cd ~/workspace/linux
%> cat ~/workspace/suspendresume/config/enable_trace_events_suspend_resume.patch | patch -p1


Now that the kernel's patched and configured, it can be built.

Building and Installing the Kernel

The source tree has been setup to build virtually everything kernel related via make. With a single command, you can build the kernel using as many processors as possible (for speed) and then automatically package it into .deb packages for install. The package files and kernel can be tagged with a custom kernel name which is in addition to the version. For the purposes of this doc lets say the kernel version of the source is 3.15.0-rc4.
 

%> make -j `getconf _NPROCESSORS_ONLN` deb-pkg LOCALVERSION=-mytestname


The first time you run make, you will get a long series of questions about whether or not you want any of the new CONFIG options. Basically any option that's in the kernel, but not in your .config, will be presented to you as an option. You can go through each one and check, but I find it's just simpler to set them all to whatever their default is. Just press return as you cycle through them and they will all be set to the default, which is usually not-enabled. You can also just hold return and wait for autorepeat to set them all to default as well (or use the Makefile option to set new options to their default automatically, but I like to see what's new). The build can take upwards of a half-hour depending on how good your system is, but once its complete you'll see these packages created in ~/workspace (the parent directory of ~/workspace/linux):

  • linux-firmware-image-3.15.0-rc4-mytestname_3.15.0-rc4-mytestname-6_amd64.deb
  • linux-headers-3.15.0-rc4-mytestname_3.15.0-rc4-mytestname-6_amd64.deb
  • linux-image-3.15.0-rc4-mytestname_3.15.0-rc4-mytestname-6_amd64.deb
  • linux-libc-dev_3.15.0-rc4-mytestname-6_amd64.deb

These are the package files for your custom kernel. The actual kernel image is in linux-image, the header files necessary to build new modules on the fly are in linux-headers (some hardware drivers require this as they compile a kernel module when they install), firmware data for devices is in linux-firmware-image, and linux-libc-dev is for the usermode syscalls into the kernel. Now you just need to copy them over to the target machine and install them:

%> cd ~/workspace
%> scp (4 package filenames) 192.168.1.7:/tmp
%> ssh -X 192.168.1.7
%> cd /tmp
%> sudo dpkg -i (4 package filenames)
%> sudo reboot

 

Once the packages are installed you can check the config file in /boot to be sure all your options are there, and also check /boot/grub/grub.cfg to see if the new kernel and command line args are there (they should be). After reboot, the kernel with the highest version number is usually the one that boots first, so your kernel should be the new default.

Reboot and enjoy!

Building and Installing the Kernel (with kernelbuild.sh)

I've created a script that handles the build and install of a kernel tree that's been placed in ~/workspace/linux. I added it to the repo for convenience and as a guide. If you use this script, be sure to copy your .ssh keys over to the target machine. This way there's no login necessary when sshing files over and installing them.

https://github.com/01org/suspendresume/blob/master/tools/kernelbuild.sh

USAGE: kernelbuild.sh command <args>
COMMANDS:
  build - build a new kernel and optionally install it
          args: name <machine> <reboot>
install - install packages from current build
          args: machine <reboot>
   info - print out what's currently built

 

The following commands are typical use cases.

# build a kernel and install it on a target machine via ssh, then reboot it
%> kernelbuild.sh build mykernel 192.168.1.7 reboot

# build a kernel and install it on the local machine without a reboot
%> kernelbuild.sh build mykernel local

# installs the latest kernel packages to have been build by kernelbuild.sh on the target system
%> kernelbuild.sh install 192.168.1.7 reboot

# describes the latest kernel built by kernelbuild.sh
%> kernelbuild.sh info
Kernel Info:
  Version: 3.15.0-rc6
  Release: 3.15.0-rc6-latest
    Build: 20
     Arch: amd64
Built Packages:
  FOUND: linux-firmware-image-3.15.0-rc6-latest_3.15.0-rc6-latest-20_amd64.deb
  FOUND: linux-headers-3.15.0-rc6-latest_3.15.0-rc6-latest-20_amd64.deb
  FOUND: linux-image-3.15.0-rc6-latest_3.15.0-rc6-latest-20_amd64.deb
  FOUND: linux-libc-dev_3.15.0-rc6-latest-20_amd64.deb