Build SystemRescueCd with your own kernel


Overview

SystemRescueCd comes with four kernels. You may want to compile your own Linux kernel because you need another driver, or you want more recent sources or just different compilation options.

This tutorial explains how you can compile your own kernel from SystemRescueCd itself, you don’t need to have another linux system installed on your hard disk. You can do all the compilation stuff from any other linux system installed on the hard disk, as long as you know what you are doing. This tutorial is based on SystemRecueCd-3.2.0 but it should work with any recent SystemRescueCd version.

After the new kernel sources are compiled, it will be necessary to make a customized SystemRescueCd using the compiled kernel image and modules.

Prepare your system

This tutorial explains how to compile the kernel from SystemRescueCd.

First boot SystemRescueCd-3.0.0 or a more recent version.

Check the requirements

Verify the version of SystemRescueCd and that the gcc compiler is installed:

[email protected] /root % cat /root/version
3.2.0

[email protected] /root % gcc --version
gcc (GCC) 4.4.7 (Gentoo 4.4.7 p1.0)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Prepare a partition with some free space

You need at least 2GB of free space on your hard disk to compile the sources and to make a customized sysresccd. You can use any partition formatted with a linux filesystem (ext4, xfs, reiserfs, jfs, …). It does not need to be empty.

This example uses partition /dev/sda6, mount it on /mnt/custom:

mount /dev/sda6 /mnt/custom

We will work in /usr/src. Make a directory in that partition, and mount it on /usr/src:

mkdir /mnt/custom/sources
mount -o bind /mnt/custom/sources /usr/src

This script creates two directories at the root of the partition:

  • /mnt/custom/sources: work area to compile the kernel
  • /mnt/custom/customcd: for the customized sysresccd

Download and prepare the sources and patches

First you must download the vanilla sources of the kernel (linux-3.x.tar.xz) without any stable patch (the version number in the filename is made of two numbers such as “3.4” as opposed to “3.4.20”)

cd /usr/src
wget -c ftp://ftp.proxad.net/mirrors/ftp.kernel.org/linux/kernel/v3.x/linux-3.4.tar.xz

Now you need the sysresccd patches. There are two sets of patches:

  • std-sources are the patches used to compile the standard kernels (rescue32 and rescue64)
  • alt-sources are the patches used to compile the alternative kernels (altker32 and altker64)

You have to decide which kind of kernel sources you want to use: either the standard ones or the alternative ones.

Here is how to download the patches. Don’t forget to replace the version number in the URL with the latest one:

cd /usr/src
wget -r  http://kernel.system-rescue-cd.org/sysresccd-x.y.z -l1 -A bz2 --no-directories

Then, you must extract the main sources:

tar xfp linux-3.4.tar.xz

And you apply the SystemRescueCd patches in the order:

cd /usr/src/linux-3.4
bzcat ../std-sources-3.4-01-stable-3.4.24.patch.bz2 | patch -p1
bzcat ../std-sources-3.4-02-fc16.patch.bz2 | patch -p1
bzcat ../std-sources-3.4-03-aufs.patch.bz2 | patch -p1

The sysresccd kernel sources are made of several patches. Some patches are necessary for the system to work, other patches are not important. The aufs patch is essential if you want your kernel to work on sysresccd. Stability patches are also recommended.

You are free to apply other patches as long as they don’t conflict with other ones or break the sources.

Configure your kernel

Customize the EXTRAVERSION

When you type uname -r, the extra version informations are displayed:

[email protected] /root % uname -r
3.4.24-std320

You may want to change the default EXTRAVERSION value, you can do that by editing the main Makefile:

[email protected] /root % cd /usr/src/linux-3.4
[email protected] /usr/src/linux-3.4 % vi Makefile

Here is an example of /usr/src/linux-3.4/Makefile

VERSION = 3
PATCHLEVEL = 4
SUBLEVEL = 24
EXTRAVERSION = -custom

Use the right architecture

You may want to compile a 32bit kernel if you are running a 64bit one, or you may want to compile a 64bit kernel even if you are running a 32bit kernel. In that case, it’s important that you specify the right value for ARCH before you run any make command related to the kernel. For instance, here is what you must do if you are running a 64bit kernel (uname -m returns x86_64) and you want to compile a 32bit kernel:

cd /usr/src/linux-3.4
export ARCH=i386
sed -i -e '1i\ARCH=i386' Makefile

To compile a 64bit kernel from SystemRescueCd or from any other 32bit linux it’s a bit difficult. You have to install crossdev first (run

that way:

CROSS_COMPILE=x86_64-pc-linux-gnu- ARCH=x86_64 make


After than, the right architecture will be used when you select the options and
when you compile the kernel.

### Choose the kernel compilation options
If you don't want to check all the kernel configuration options, you can use the
official sysresccd options as a starting point. The options of the running kernel
are available in ```/proc/config.gz```, so you can just get the configuration
file that way:

cd /usr/src/linux-3.4 cat /proc/config.gz | gzip -d > .config


If you are working in graphical mode, you can select the options using the
graphical program based on GTK. The ```make xconfig``` command cannot be used
since the system does not have the Qt libraries. So just type this:

cd /usr/src/linux-3.4 make gconfig


If you are working in console mode, you can use ```make menuconfig``` instead:

cd /usr/src/linux-3.4 make menuconfig


When you select the kernel options, it's very important that you enable the
following options, they must be built-in in the kernel image not compiled as
modules:

CONFIG_SQUASHFS=y CONFIG_SQUASHFS_XZ=y CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 CONFIG_AUFS_FS=y CONFIG_AUFS_BRANCH_MAX_127=y CONFIG_AUFS_EXPORT=y CONFIG_AUFS_BR_FUSE=y CONFIG_AUFS_POLL=y CONFIG_AUFS_BDEV_LOOP=y


If you want to compile a 64bit kernel (ARCH=x86_64), don't forget to enable the
IA32 support (CONFIG_IA32_EMULATION=y), else your kernel won't execute the 32bit
binaries. And the sysresccd system is made of 32bit binaries.

Also it is important to disable CONFIG_INITRAMFS_SOURCE (remove the value which
  contains just a space) except if you know how to use it.

## Compile and install the kernel
After the options have been selected and saved in /usr/src/linux-3.4/.config,
you can compile the sources:

make && make modules && make modules_install


If the kernel compiles without error, a compressed kernel image should be
available:

[email protected] /root % find /usr/src -type f -name bzImage /usr/src/linux-3.4/arch/x86/boot/bzImage


You should also find new modules in either ```/lib/modules``` or ```/lib64/modules/```.

Just make a backup of these two things (bzImage file, and the new modules) that
you will need in the following stages.

## Recreate the initramfs
### What is an initramfs
An initramfs (also known as init-ramdisk) is a compressed cpio archive which
contains files used to initialize the system at boot time. The files are used by
the kernel to initialize the system. Basically it does things such as mounting
the main root filesystem. It's not required for all the linux systems, but it's
necessary for complex ones, for instance when the root filesystem is on an LVM
logical volume. In previous kernel versions, the ramdisks were compressed
loopback filesystems.

SystemRescueCd needs an initramfs to boot, it's located in ```isolinux``` on the
cdrom. All the kernels use the same initramfs to save space. This file contains
the modules of the kernel you boot, so it's necessary to copy the new modules in
this initramfs.

### Kernel modules and initramfs
The initramfs archive is where you find the kernel modules used at boot time in
most Linux distributions. You may be surprised to see that the official kernel
modules are not in the ```initram.igz``` when you extract this archive to
replace the official modules with your own files. 

This is just because recent SystemRescueCds use the ```CONFIG_INITRAMFS_SOURCE```
option. When this option is used, each kernel image contains its own kernel
modules. For instance, the ```rescue32``` kernel image contains both the
standard kernel binary and an embedded initramfs which contains its own kernel
modules. SystemRescueCd uses this option because there are four kernels. We
could provide four initramfs files which would all contain the standard programs
and the specific kernel modules of each kernel, but it would waste a lot of
space. We really want to make the ISO image as small as possible.

With the ```CONFIG_INITRAMFS_SOURCE``` option each kernel image contains its own
kernel modules. And the ```initram.igz``` only contains the common boot scripts
and programs which are used by all these kernels. When a kernel boots, both the
embedded initramfs and the ```initram.igz``` are extracted into memory, then the
kernel has all it needs to boot. We could also put all kernel modules for all
kernels in the ```initram.igz``` but it would require a lot of memory just to
boot since it would be necessary to extract the kernel modules of all kernels
into memory. So it would take more time and it would fail on computers with a
small amount of memory. 

The only problem with the ```CONFIG_INITRAMFS_SOURCE``` option is that it's a
bit more complicated to use: the kernel has to be compiled twice: once to
generate the kernel modules to create a cpio archive with its kernel modules,
and then we recompile the kernel a second time to merge this archive with the
kernel image. It's probably too complicated to use this option if you just want
to use your own kernel with SystemRescueCd. For that reason you should just
disable it, and then you can put your own kernel modules in ```/lib/modules```
in the ```initram.igz``` file and you will see that the kernel image will be
smaller than the official, because it won't contain the embedded archive with
its own kernel modules.

### Extracting the current initramfs
Here is how we extract the contents of the old initramfs using cpio. If you are
booting from the network, you may need to download ```initram.igz``` by hand.

mkdir /usr/src/initramfs cd /usr/src/initramfs cat /mnt/cdrom/isolinux/initram.igz | xz -d | cpio -id


### Copy the new modules into the initramfs
Now, you have to copy the directory where your new modules are stored to the
initramfs contents. The location of the modules can be either ```/lib/modules```
or ```/lib64/modules```:

cp -a /lib/modules/your-kernel-modules /usr/src/initramfs/lib/modules/


### Recreating the initramfs
Here is how we can recreate the new initramfs:

rm -f /usr/src/initram.igz cd /usr/src/initramfs find . | cpio -H newc -o | xz –check=crc32 –x86 –lzma2 > /usr/src/initram.igz


## Create a customized disc with the new kernel
Now what you have to do is to make a [custom SystemRescueCd](/Customization/)
in which you will copy the new ```initram.igz``` and the new kernel modules. You
have to follow the detailed instructions about [customizing SystemRescueCd]
(/Customization/) without forgetting to copy the new files. Here is a summarized
procedure (you have to update the files path and names so that they match your
configuration):

* You do not have to mount a partition again on ```/mnt/custom``` since has
  already been done
* Extract the file from the squashfs filesystem:
  ```/usr/sbin/sysresccd-custom extract```
* Copy the new kernel modules in ```/mnt/custom/customcd/files/lib/modules``` or
  ```/mnt/custom/customcd/files/lib64/modules```:
  ```cp -a /lib/modules/your-kernel-modules /mnt/custom/customcd/files/lib/modules```
  or
  ```cp -a /lib64/modules/your-kernel-modules /mnt/custom/customcd/files/lib64/modules```
* Create the new compressed squashfs filesystem:
  ```/usr/sbin/sysresccd-custom squashfs```
* Copy the new ```initram.igz```:
  ```cp /usr/src/initram.igz /mnt/custom/customcd/isoroot/isolinux/initram.igz```
* Copy the new kernel into ```/mnt/custom/customcd/isoroot/isolinux/```.
  You have to choose a name for your kernel image. For instance it may be
  ```vmlinuz``` which is a common name for kernel images, or you can replace the
  official kernel and give it the same name: ```rescue32```.
  ```cp /usr/src/linux-3.4/arch/x86/boot/bzImage /mnt/custom/customcd/isoroot/isolinux/vmlinuz```
  or
  ```cp /usr/src/linux-3.4/arch/x86/boot/bzImage /mnt/custom/customcd/isoroot/isolinux/rescue32```
  If you decided to give the kernel image another name, you will have to update ```isolinux.cfg```
  and ```syslinux.cfg``` so that it has boot entries which use the new kernel.
  Here is how to edit it: ```vim /mnt/custom/customcd/isoroot/isolinux/isolinux.cfg```
  Here is an example of two new entries that you can add to ```isolinux.cfg```.
  The first one has no boot option, and the second one has an option to set the
  keyboard mapping:

label mykernel kernel vmlinuz append initrd=initram.igz label mykernelfr kernel vmlinuz append initrd=initram.igz setkmap=fr In other words, you will have to type eithermykernelormykernelfr at the very first boot prompt in order to boot the new customized SystemRescueCd. * Now you have to build the ISO filesystem: /usr/sbin/sysresccd-custom isogen my_srcd * The final ISO image must have been written in /mnt/custom/customcd/isofile/sysresccd-new.iso. Copy this file wherever you want, or burn it directly from SystemRescueCd if your driver is not busy. * And then, unmount the partition cleanly: cd / ; umount /mnt/custom ; sync```


Documentation
Manual (EN)
LVM Guide
Disk partitioning
Networking
Manual (FR)

Related
Sourceforge
FSArchiver