Blog Archives

Your custom kernel in MeeGo

In my last post I covered the steps needed to create custom MeeGo images and play with them.

One of the things you may also want to do is to try new or modified kernels in your MeeGo images. You can do this either installing RPMs or directly compiling the kernel yourself. The following steps will cover this last case.

1. Where to compile the kernel

No, do not try to compile the kernel directly in a raw image launched within KVM/QEMU.

The easiest way to compile your own kernel is to prepare a loop image and chroot into it (See section “6. Create a loop image and chroot into it” in Your custom MeeGo builds).

Note: In order to completely compile the kernel, you will need quite a lot of empty space in the chroot. In order to easily get this, just use a big enough root partition size (given in MBytes) in the Kickstart file used to create the loop image.

2. Get into the chroot

Assuming meego-core-ia32.img is a loop image created, just:

$> sudo mic-chroot meego-core-ia32.img

3. Ensure only one kernel is available

The MeeGo Image Creation tools will expect to have exactly only one kernel available. Therefore, if you just created the loop image, you will need to remove the default kernel RPM installed.

# rpm -e kernel

4. Install the MeeGo kernel source and build dependencies

You will need to enable the source repositories in zypper first:
First, list the available repositories in zypper:

# zypper lr -u

Note that these repositories were initially configured in the Kickstart file used to create the loop image.

Then, enable the source repositories if not already done.

# zypper mr -e 1.2.0-non-oss-source
# zypper mr -e 1.2.0-oss-source
# zypper mr -e 1.2.0-updates-non-oss-source
# zypper mr -e 1.2.0-updates-oss-source

Once you have these enabled, you can install the kernel source, and all the build dependencies will also get installed:

# zypper si kernel

Install additional required packages which were not listed in the build dependencies (not sure why not listed).

# zypper in gcc

5. Get your new kernel, configure, compile and install

First, download the tarball and decompress it:

# cd /root
# wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.0.4.tar.bz2
# tar -jxvf linux-3.0.4.tar.bz2 -C /usr/src

Prepare the kernel configuration file, based on the one from the MeeGo kernel packaging. In this case we’re using a newer kernel version, so you will be prompted for the values of the new configuration parameters. You can just try use the default ones if you don’t know what they mean.

# cd /usr/src/linux-3.0.4
# cat /root/rpmbuild/SOURCES/config-generic /root/rpmbuild/SOURCES/config-x86 > .config
# make oldconfig

Note: Of course, you can fully skip using the MeeGo kernel configuration file and fully configure it yourself with, for example, make menuconfig.

Then, compile the new kernel and the kernel modules, and install them.

# make -j8
# make -j8 modules
# make modules_install
# make install

Note: In addition to the specific kernel configuration, MeeGo packaging also provides several kernel patches. In this case, we are not including them.

6. Make the kernel bootable

In order to make the kernel bootable in the image, you will need to create an initial ramdisk under /boot. But you shouldn’t use mkinitrd for that, use the provided mkliveinitrd instead:

# /usr/libexec/mkliveinitrd -f /boot/initrd.img-3.0.4 3.0.4

Once done, just exit the chroot:

# exit

7. Create a LiveUSB image to test the new kernel

The steps to convert a loop image to a LiveUSB image and write it into an external USB disk are explained in my previous post about Your custom MeeGo builds, so I won’t explain much more about it.

Just a warning: always make sure that you have ONLY ONE kernel available under /boot. If you happen to have more than one, for example when make install-ing twice (old ones get renamed with a .old extension), mic-image-convertor won’t like it and will exit with an error message like this one:

Error: Unable to copy valid kernels or initrds, please check the repo

The Core Pattern (core_pattern), or how to specify filename and path for core dumps

1. Introduction to Core Dumps

In most GNU/Linux systems (all of those I personally have used, at least), core dump files generated after an uncaught signal in a process (as a SIGSEGV or SIGQUIT), are generated in the base directory where the program was executed, and named as “core” or “core.PID”.

For example:

$> cd /home/user
$> ulimit -c unlimited
$> kill -s SIGSEGV $$

This will trigger a segmentation fault in your current shell (you probably guessed it after seeing that the shell session where you executed it was closed), and generate a core file in:
/home/user/core

Now… is it possible to change where that file is generated by default instead of the current directory? And is it possible to change the name of that generated file? The answer is YES! to both. Let’s see how we can get this.

2. The Core Pattern in Kernel

Since some years ago, the kernel configuration includes a file named “core_pattern”:
/proc/sys/kernel/core_pattern

In my system, that file contains just this single word:
core

As expected, this pattern shows how the core file will be generated. Two things can be understood from the previous line: The filename of the core dump file generated will be “core”; and second, the current directory will be used to store it (as the path specified is completely relative to the current directory).

Now, if we change the contents of that file… (as root, of course)

$> mkdir -p /tmp/cores
$> chmod a+rwx /tmp/cores
$> echo "/tmp/cores/core.%e.%p.%h.%t" > /proc/sys/kernel/core_pattern

And we run the same as before:

$> cd /home/user
$> ulimit -c unlimited
$> $> kill -s SIGSEGV $$

We get… voilá!
/tmp/cores/core.bash.8539.drehbahn-mbp.1236975953

Not only the program name (“bash“) or the PID (“8539“), but also the hostname (“drehbahn-mbp“) and the unix time (“1236975953“) are appended in the name of the core file!! And of course, it is stored in the absolute path we specified (“/tmp/cores/“).

You can use the following pattern elements in the core_pattern file:

%p: pid
%: '%' is dropped
%%: output one '%'
%u: uid
%g: gid
%s: signal number
%t: UNIX time of dump
%h: hostname
%e: executable filename
%: both are dropped

Isn’t is great?! Imagine that you have a cluster of machines and you want to use a NFS directory to store all core files from all the nodes. You will be able to detect which node generated the core file (with the hostname), which program generated it (with the program name), and also when did it happen (with the unix time).

3. Configure it forever

The changes done before are only applicable until the next reboot. In order to make the change in all future reboots, you will need to add the following in “/etc/sysctl.conf“:

# Own core file pattern...
kernel.core_pattern=/tmp/cores/core.%e.%p.%h.%t

sysctl.conf is the file controlling every configuration under /proc/sys

Follow

Get every new post delivered to your Inbox.

Join 36 other followers